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:
Rotimi Best
2025-11-01 15:49:29 +01:00
committed by GitHub
parent 97fb446df5
commit b96d91cd7c
801 changed files with 22279 additions and 10834 deletions
@@ -1,6 +1,6 @@
<script lang="ts">
import { goto } from '$app/navigation';
import { page } from '$app/stores';
import { page } from '$app/state';
import Avatar from '$lib/components/Avatar/index.svelte';
import TextChip from '$lib/components/Chip/Text.svelte';
import ComingSoon from '$lib/components/ComingSoon/index.svelte';
@@ -10,7 +10,7 @@
import type { ProfileRole } from '$lib/components/Course/components/People/types';
import { group } from '$lib/components/Course/store';
import Select from '$lib/components/Form/Select.svelte';
import IconButton from '$lib/components/IconButton/index.svelte';
import { IconButton } from '$lib/components/IconButton';
import { VARIANTS } from '$lib/components/PrimaryButton/constants';
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
import RoleBasedSecurity from '$lib/components/RoleBasedSecurity/index.svelte';
@@ -28,12 +28,13 @@
StructuredListHead,
StructuredListRow
} from 'carbon-components-svelte';
import TrashCanIcon from 'carbon-icons-svelte/lib/TrashCan.svelte';
import TrashIcon from '@lucide/svelte/icons/trash';
let people: Array<GroupPerson> = [];
let member: { id?: string; email?: string; profile?: { email: string } } = {};
let filterBy: ProfileRole = ROLES[0];
let searchValue = '';
let member: { id?: string; email?: string; profile?: { email: string } } = $state({});
let filterBy: ProfileRole = $state(ROLES[0]);
let searchValue = $state('');
const people: Array<GroupPerson> = $derived(sortAndFilterPeople($group.people, filterBy));
function filterPeople(_query, people) {
const query = _query.toLowerCase();
@@ -52,16 +53,13 @@
}
function sortAndFilterPeople(_people: Array<GroupPerson>, filterBy: ProfileRole) {
people = (_people || [])
return (_people || [])
.filter((person) => {
if (filterBy.value === 'all') return true;
return person.role_id === filterBy.value;
})
.sort(
(a: GroupPerson, b: GroupPerson) =>
new Date(a.created_at).getTime() - new Date(b.created_at).getTime()
)
.sort((a: GroupPerson, b: GroupPerson) => new Date(a.created_at).getTime() - new Date(b.created_at).getTime())
.sort((a: GroupPerson, b: GroupPerson) => a.role_id - b.role_id);
}
@@ -80,23 +78,16 @@
}
function gotoPerson(person) {
goto(`${$page.url.href}/${person.profile_id}`);
goto(`${page.url.href}/${person.profile_id}`);
}
$: sortAndFilterPeople($group.people, filterBy);
</script>
<InvitationModal />
<DeleteConfirmation
email={member.email || (member.profile && member.profile.email)}
{deletePerson}
/>
<DeleteConfirmation email={member.email || (member.profile && member.profile.email)} {deletePerson} />
<section class="mx-2 my-5 md:mx-9">
<div
class="flex-end mb-7 flex flex-col items-start justify-end gap-2 md:flex-row md:items-center"
>
<div class="flex-end mb-7 flex flex-col items-start justify-end gap-2 md:flex-row md:items-center">
<div class="max-w-[320px]">
<Search
class="w-full border-0 bg-zinc-100 dark:text-slate-950"
@@ -117,14 +108,12 @@
</select> -->
</div>
<RoleBasedSecurity allowedRoles={[1, 2]}>
<p class="hidden w-20 text-lg dark:text-white lg:block" />
<p class="hidden w-20 text-lg lg:block dark:text-white"></p>
</RoleBasedSecurity>
</div>
<StructuredList class="m-0">
<StructuredListHead
class="bg-slate-100 dark:border-2 dark:border-neutral-800 dark:bg-neutral-800"
>
<StructuredListHead class="bg-slate-100 dark:border-2 dark:border-neutral-800 dark:bg-neutral-800">
<StructuredListRow head class="mx-7">
<StructuredListCell head class="text-primary-700 py-3 dark:text-white"
>{$t('course.navItem.people.name')}</StructuredListCell
@@ -136,7 +125,7 @@
>{$t('course.navItem.people.action')}</StructuredListCell
>
<RoleBasedSecurity allowedRoles={[1, 2]}>
<p class="hidden w-20 text-lg dark:text-white lg:block" />
<p class="hidden w-20 text-lg lg:block dark:text-white"></p>
</RoleBasedSecurity>
</StructuredListRow>
</StructuredListHead>
@@ -181,18 +170,12 @@
className="bg-primary-200 text-black font-semibold text-xs mr-3"
shape="rounded-full"
/>
<a
href="mailto:{person.email}"
class="text-md text-primary-600 mr-2 dark:text-white"
>
<a href="mailto:{person.email}" class="text-md text-primary-600 mr-2 dark:text-white">
{person.email}
</a>
<div class="flex items-center justify-between">
<RoleBasedSecurity allowedRoles={[1, 2]}>
<CopyButton
text={getEmail(person)}
feedback={$t('course.navItem.people.feedback')}
/>
<CopyButton text={getEmail(person)} feedback={$t('course.navItem.people.feedback')} />
</RoleBasedSecurity>
<TextChip
@@ -223,12 +206,12 @@
$deleteMemberModal.open = true;
}}
>
<TrashCanIcon size={16} class="carbon-icon dark:text-white" />
<TrashIcon size={16} />
</IconButton>
<!-- <IconButton
onClick={() => gotoPerson(person)}
>
<TrashCanIcon size={16} class="carbon-icon dark:text-white" />
<TrashIcon size={16} />
</IconButton> -->
<PrimaryButton