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,12 +1,25 @@
<script>
export let width = 'max-w-4xl w-full lg:w-11/12';
export let padding = 'pb-5 px-4';
export let className = '';
export let headerClassName = '';
export let onClick = () => {};
export let isPageNavHidden = false;
<script lang="ts">
interface Props {
width?: string;
padding?: string;
className?: string;
headerClassName?: string;
onClick?: any;
isPageNavHidden?: boolean;
header?: import('svelte').Snippet;
children?: import('svelte').Snippet;
}
$: padding = isPageNavHidden ? `pb-20 px-4` : padding;
let {
width = 'max-w-4xl w-full lg:w-11/12',
padding = $bindable('pb-5 px-4'),
className = '',
headerClassName = '',
onClick = () => {},
isPageNavHidden,
header,
children
}: Props = $props();
function handleKeydown(event) {
if (event.key === 'Enter' || event.key === ' ') {
@@ -21,19 +34,19 @@
tabindex="0"
class="overflow-y-auto {isPageNavHidden
? 'h-[calc(100vh-65px)] lg:h-[calc(100vh-127px)]'
: 'h-[calc(100vh-127px)]'} mx-auto mt-4 {width} {className} relative {padding}"
on:click={onClick}
on:keydown={handleKeydown}
: 'h-[calc(100vh-127px)]'} mx-auto mt-4 {width} {className} relative {isPageNavHidden ? 'px-4 pb-20' : padding}"
onclick={onClick}
onkeydown={handleKeydown}
>
{#if $$slots.header}
{#if header}
<div
class="head sticky right-0 flex w-full items-center justify-between px-3 dark:bg-neutral-800 {headerClassName}"
>
<slot name="header" />
{@render header?.()}
</div>
{/if}
<slot />
{@render children?.()}
</div>
<style>
@@ -1,21 +1,37 @@
<script>
<script lang="ts">
import { t } from '$lib/utils/functions/translations';
import Chip from '../Chip/index.svelte';
import TextField from '../Form/TextField.svelte';
export let title = '';
export let overidableStyle = '';
export let navItems = [];
export let disableSticky = false;
export let isTitleEditable = false;
export let onEditComplete = () => {};
export let paddingClass = 'px-2';
export let hideOnMobile = false;
interface Props {
title?: string;
overidableStyle?: string;
navItems?: any;
disableSticky?: boolean;
isTitleEditable?: boolean;
onEditComplete?: any;
paddingClass?: string;
hideOnMobile?: boolean;
image?: import('svelte').Snippet;
widget?: import('svelte').Snippet;
}
let dynamicRootClass = '';
let enterEditTitleMode = false;
let {
title = $bindable(''),
overidableStyle = '',
navItems = [],
disableSticky = false,
isTitleEditable = false,
onEditComplete = () => {},
paddingClass = 'px-2',
hideOnMobile = false,
image,
widget
}: Props = $props();
$: dynamicRootClass = Array.isArray(navItems) && navItems.length > 4 ? 'bring-down' : '';
let enterEditTitleMode = $state(false);
const dynamicRootClass = $derived(Array.isArray(navItems) && navItems.length > 4 ? 'bring-down' : '');
</script>
<div
@@ -32,10 +48,8 @@
{#if !!title}
{#if isTitleEditable}
{#if !enterEditTitleMode}
<button class="w-full" on:click={() => (enterEditTitleMode = true)}>
<h4
class="editable-title overflow-ellipsis rounded-md px-3 hover:bg-gray-100 dark:bg-black"
>
<button class="w-full" onclick={() => (enterEditTitleMode = true)}>
<h4 class="editable-title overflow-ellipsis rounded-md px-3 hover:bg-gray-100 dark:bg-black">
{title}
</h4>
</button>
@@ -54,12 +68,8 @@
{/if}
{:else}
<div class="flex w-full items-center" {title}>
<slot name="image" />
<h4
class="{$$slots.image
? 'ml-2'
: ''} truncate whitespace-nowrap text-lg font-semibold dark:text-white"
>
{@render image?.()}
<h4 class="{image ? 'ml-2' : ''} truncate whitespace-nowrap text-lg font-semibold dark:text-white">
{title}
</h4>
</div>
@@ -83,12 +93,12 @@
class="bg-primary-700 absolute bottom-0 left-0 h-1 transition-all duration-500 ease-in-out {item.isActive
? 'w-full'
: 'w-0'}"
/>
></span>
</a>
{/each}
</div>
{/if}
<slot name="widget" />
{@render widget?.()}
</div>
</div>
@@ -1,9 +1,13 @@
<script>
<script lang="ts">
import { goto } from '$app/navigation';
import { VARIANTS } from '$lib/components/PrimaryButton/constants';
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
export let isOrg = false;
interface Props {
isOrg?: boolean;
}
let { isOrg = false }: Props = $props();
function handleClick() {
if (!isOrg) {
@@ -16,7 +20,7 @@
<div class="root flex w-screen flex-col items-center justify-center">
<img src="https://brand.cdn.clsrio.com/404.png" alt="classroomio_error_image" />
<div class="flex w-4/5 flex-col items-center justify-center gap-3 dark:text-white lg:w-2/5">
<div class="flex w-4/5 flex-col items-center justify-center gap-3 lg:w-2/5 dark:text-white">
<p class="mb-5 text-4xl font-semibold dark:text-white">
{#if isOrg}
Organization doesn't exist!
@@ -27,12 +31,7 @@
<p class=" mb-5 text-center text-lg text-gray-700 dark:text-white">
The page you are looking for doesn't exist or has been moved. Please go back to the homepage.
</p>
<PrimaryButton
variant={VARIANTS.CONTAINED_DARK}
label="Go Home"
className="text-lg"
onClick={handleClick}
/>
<PrimaryButton variant={VARIANTS.CONTAINED_DARK} label="Go Home" className="text-lg" onClick={handleClick} />
</div>
</div>
@@ -2,26 +2,21 @@
import { goto } from '$app/navigation';
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
import { VARIANTS } from '$lib/components/PrimaryButton/constants';
import Locked from 'carbon-icons-svelte/lib/Locked.svelte';
import LockIcon from '@lucide/svelte/icons/lock';
function handleClick() {
return goto('https://classroomio.com');
}
</script>
<div class="root flex items-center justify-center flex-col w-screen">
<Locked size={32} />
<div class="flex flex-col items-center justify-center dark:text-white gap-3 w-4/5 lg:w-2/5">
<p class="text-4xl dark:text-white font-semibold mt-5">Restricted Page</p>
<p class=" text-gray-700 text-lg text-center dark:text-white mb-5">
<div class="root flex w-screen flex-col items-center justify-center">
<LockIcon size={16} />
<div class="flex w-4/5 flex-col items-center justify-center gap-3 lg:w-2/5 dark:text-white">
<p class="mt-5 text-4xl font-semibold dark:text-white">Restricted Page</p>
<p class=" mb-5 text-center text-lg text-gray-700 dark:text-white">
This organization is restricted. In the mean time, you can checkout our features.
</p>
<PrimaryButton
variant={VARIANTS.CONTAINED_DARK}
label="Go Home"
className="text-lg"
onClick={handleClick}
/>
<PrimaryButton variant={VARIANTS.CONTAINED_DARK} label="Go Home" className="text-lg" onClick={handleClick} />
</div>
</div>
@@ -8,17 +8,13 @@
class="root flex h-[calc(100vh-48px)] w-screen flex-col items-center justify-center gap-2 bg-[#F3F5F9] text-center text-black dark:bg-black dark:text-white"
>
<img src="./unauthorized.svg" alt="unauthorized" class="w-[220px]" />
<p class=" text-4xl font-bold text-black dark:text-white md:text-5xl">Page not found</p>
<p class=" text-4xl font-bold text-black md:text-5xl dark:text-white">Page not found</p>
<p class=" mb-2 mt-1 text-base font-[400] text-[#656565] dark:text-white">
The page you are trying to access does not exist
</p>
<PrimaryButton label="Go Home" onClick={() => goto('https://www.classroomio.com')} />
<PrimaryButton
label="Help"
variant={VARIANTS.LINK}
onClick={() => goto('https://help.classroomio.com/')}
/>
<PrimaryButton label="Help" variant={VARIANTS.LINK} onClick={() => goto('https://help.classroomio.com/')} />
</div>
<style>