feat: setup drizzle (#594)
* chore: migration to SvelteKit 2 * stage 1: migrate to svelte 5 and fix rerendering issues * stage 2: fix more $: reactivity across dashboard * fix merge conflicts * chore: migrate code in main to svelte 5 * chore: update preventDefault * chore: simplify tsconfig and remove unused mobileMenuRef in MobileMenu.svelte * chore: enforce .ts across dashboard * rename from classroomio-com to website * stage-3: Replace carbon icon svelte with lucide icon * update lock file * chore: finish icon replacement * fix: settings and setup page multiple rerender * stage 3: More icon and rerendering fixes * feat: setup drizzle and better auth * fix: onboarding validation error showing translation key #586 (#593) * fix: onboarding validation error showing translation key #586 * fix: remove debug log for profile update errors * chore: add a clean command * fix: remove message from email verification response
This commit is contained in:
@@ -1,13 +1,13 @@
|
||||
<script lang="ts">
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
import { page } from '$app/state';
|
||||
import Box from '$lib/components/Box/index.svelte';
|
||||
import NewFeedModal from '$lib/components/Course/components/NewsFeed/NewFeedModal.svelte';
|
||||
import NewsFeedCard from '$lib/components/Course/components/NewsFeed/NewsFeedCard.svelte';
|
||||
import NewsFeedLoader from '$lib/components/Course/components/NewsFeed/NewsFeedLoader.svelte';
|
||||
import { isNewFeedModal, newsFeed } from '$lib/components/Course/components/NewsFeed/store';
|
||||
import { group } from '$lib/components/Course/store';
|
||||
import CourseContainer from '$lib/components/CourseContainer/index.svelte';
|
||||
import { CourseContainer } from '$lib/components/CourseContainer';
|
||||
import { PageBody, PageNav } from '$lib/components/Page';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import RoleBasedSecurity from '$lib/components/RoleBasedSecurity/index.svelte';
|
||||
@@ -23,32 +23,35 @@
|
||||
handleEditFeed,
|
||||
toggleFeedIsPinned
|
||||
} from '$lib/utils/services/newsfeed';
|
||||
import {
|
||||
NOTIFICATION_NAME,
|
||||
triggerSendEmail
|
||||
} from '$lib/utils/services/notification/notification';
|
||||
import { NOTIFICATION_NAME, triggerSendEmail } from '$lib/utils/services/notification/notification';
|
||||
import { currentOrg } from '$lib/utils/store/org';
|
||||
import { profile } from '$lib/utils/store/user';
|
||||
import type { Feed } from '$lib/utils/types/feed';
|
||||
import type { CurrentOrg } from '$lib/utils/types/org';
|
||||
import PinFilled from 'carbon-icons-svelte/lib/PinFilled.svelte';
|
||||
import PinIcon from '@lucide/svelte/icons/pin';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
export let data;
|
||||
let { data = $bindable() } = $props();
|
||||
|
||||
let createdComment;
|
||||
let edit = false;
|
||||
let isLoading = false;
|
||||
let editFeed: Feed;
|
||||
let author = {
|
||||
id: '',
|
||||
username: '',
|
||||
fullname: '',
|
||||
avatar_url: ''
|
||||
};
|
||||
let edit = $state(false);
|
||||
let isLoading = $state(false);
|
||||
let editFeed: Feed | null = $state(null);
|
||||
|
||||
let query = new URLSearchParams($page.url.search);
|
||||
let query = new URLSearchParams(page.url.search);
|
||||
let feedId = query.get('feedId') || '';
|
||||
|
||||
const author = $derived.by(() => {
|
||||
const groupMember = $group.people.find((person) => person.profile_id === $profile.id);
|
||||
|
||||
return {
|
||||
id: groupMember?.id || '',
|
||||
username: $profile.username || '',
|
||||
fullname: $profile.fullname || '',
|
||||
avatar_url: $profile.avatar_url || ''
|
||||
};
|
||||
});
|
||||
|
||||
const onEdit = (id: string, content: string) => {
|
||||
handleEditFeed(id, content);
|
||||
|
||||
@@ -81,9 +84,7 @@
|
||||
let reactedAuthorIds: string[] = reactedFeed.reaction[reactionType];
|
||||
|
||||
if (reactedAuthorIds.includes(authorId)) {
|
||||
reactedAuthorIds = reactedAuthorIds.filter(
|
||||
(reactionAuthorId) => reactionAuthorId !== authorId
|
||||
);
|
||||
reactedAuthorIds = reactedAuthorIds.filter((reactionAuthorId) => reactionAuthorId !== authorId);
|
||||
} else {
|
||||
reactedAuthorIds = [...reactedAuthorIds, authorId];
|
||||
}
|
||||
@@ -199,10 +200,12 @@
|
||||
snackbar.error('snackbar.course.error.news_feed_fail');
|
||||
}
|
||||
if (data) {
|
||||
$newsFeed = data.map((feedItem) => ({
|
||||
...feedItem,
|
||||
isPinned: feedItem.is_pinned
|
||||
}));
|
||||
$newsFeed = data
|
||||
.map((feedItem) => ({
|
||||
...feedItem,
|
||||
isPinned: feedItem.is_pinned
|
||||
}))
|
||||
.sort((a, b) => Number(b.isPinned) - Number(a.isPinned));
|
||||
}
|
||||
} catch (error) {
|
||||
snackbar.error('snackbar.course.error.feed_fetch_error');
|
||||
@@ -211,17 +214,6 @@
|
||||
}
|
||||
};
|
||||
|
||||
function setAuthor(groups, profileId) {
|
||||
const currentGroupMember = groups.people.find((person) => person.profile_id === profileId);
|
||||
|
||||
author = {
|
||||
id: currentGroupMember?.id || '',
|
||||
username: $profile.username || '',
|
||||
fullname: $profile.fullname || '',
|
||||
avatar_url: $profile.avatar_url || ''
|
||||
};
|
||||
}
|
||||
|
||||
function getPageRoles(org: CurrentOrg) {
|
||||
const roles: number[] = [1, 2];
|
||||
|
||||
@@ -232,13 +224,12 @@
|
||||
return roles;
|
||||
}
|
||||
|
||||
$: initNewsFeed(data.courseId);
|
||||
|
||||
$: setAuthor($group, $profile.id);
|
||||
$: $newsFeed = $newsFeed.sort((a, b) => Number(b.isPinned) - Number(a.isPinned));
|
||||
onMount(() => {
|
||||
initNewsFeed(data.courseId);
|
||||
});
|
||||
</script>
|
||||
|
||||
<CourseContainer bind:courseId={data.courseId}>
|
||||
<CourseContainer courseId={data.courseId}>
|
||||
<RoleBasedSecurity
|
||||
allowedRoles={getPageRoles($currentOrg)}
|
||||
onDenied={() => {
|
||||
@@ -246,7 +237,7 @@
|
||||
}}
|
||||
>
|
||||
<PageNav title={$t('course.navItem.news_feed.heading')} disableSticky={true}>
|
||||
<slot:fragment slot="widget">
|
||||
{#snippet widget()}
|
||||
<RoleBasedSecurity allowedRoles={[1, 2]}>
|
||||
<PrimaryButton
|
||||
className="mr-2"
|
||||
@@ -254,7 +245,7 @@
|
||||
onClick={() => ($isNewFeedModal.open = true)}
|
||||
/>
|
||||
</RoleBasedSecurity>
|
||||
</slot:fragment>
|
||||
{/snippet}
|
||||
</PageNav>
|
||||
|
||||
<PageBody width="max-w-4xl px-3">
|
||||
@@ -290,7 +281,7 @@
|
||||
{#each $newsFeed as feed}
|
||||
{#if feed.isPinned}
|
||||
<div class="mb-3 flex items-center gap-2">
|
||||
<PinFilled size={16} />
|
||||
<PinIcon size={16} class="filled" />
|
||||
|
||||
<p class="text-sm">{$t('course.navItem.news_feed.pinned')}</p>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user