diff --git a/apps/dashboard/src/lib/components/AuthUI/index.svelte b/apps/dashboard/src/lib/components/AuthUI/index.svelte index f2ff8b26..14efc9c2 100644 --- a/apps/dashboard/src/lib/components/AuthUI/index.svelte +++ b/apps/dashboard/src/lib/components/AuthUI/index.svelte @@ -47,9 +47,11 @@ height="h-10" className="mr-2" /> -

- {$currentOrg.name ? $currentOrg.name : 'ClassroomIO'} -

+ +

+ {$currentOrg.name ? $currentOrg.name : 'ClassroomIO'} +

+
{/if}
diff --git a/apps/dashboard/src/lib/components/CourseLandingPage/components/PricingSection.svelte b/apps/dashboard/src/lib/components/CourseLandingPage/components/PricingSection.svelte index ec9eba5c..a178f12c 100644 --- a/apps/dashboard/src/lib/components/CourseLandingPage/components/PricingSection.svelte +++ b/apps/dashboard/src/lib/components/CourseLandingPage/components/PricingSection.svelte @@ -4,7 +4,7 @@ import getCurrencyFormatter from '$lib/utils/functions/getCurrencyFormatter'; import { isCourseFree } from '$lib/utils/functions/course'; import { getStudentInviteLink } from '$lib/utils/functions/course'; - import { currentOrg } from '$lib/utils/store/org'; + import { currentOrg, currentOrgDomain } from '$lib/utils/store/org'; import { goto } from '$app/navigation'; import PaymentModal from './PaymentModal.svelte'; import type { Course } from '$lib/utils/types'; @@ -17,6 +17,7 @@ export let startCoursePayment = false; export let mobile = false; + let openModal = false; let calculatedCost = 0; let discount = 0; let formatter: Intl.NumberFormat | undefined; @@ -39,11 +40,13 @@ course_free: isFree }); if (isFree) { - const link = getStudentInviteLink(courseData, $currentOrg.siteName); + const link = getStudentInviteLink(courseData, $currentOrg.siteName, $currentOrgDomain); goto(link); } else { - startCoursePayment = true; + openModal = true; } + + startCoursePayment = false; } function setFormatter(currency: string | undefined) { @@ -62,10 +65,11 @@ $: discount = get(courseData, 'metadata.discount', 0); $: calculatedCost = calcDisc(discount, courseData.cost || 0, !!courseData.metadata.showDiscount); $: isFree = isCourseFree(calculatedCost); + $: startCoursePayment && handleJoinCourse(); -
-

+

+

{$profile.fullname}

diff --git a/apps/dashboard/src/lib/utils/functions/course.ts b/apps/dashboard/src/lib/utils/functions/course.ts index 1a3d6d28..307ba5f4 100644 --- a/apps/dashboard/src/lib/utils/functions/course.ts +++ b/apps/dashboard/src/lib/utils/functions/course.ts @@ -3,7 +3,7 @@ import type { Course } from '../types'; export const isCourseFree = (cost: number) => !(Number(cost) > 0); -export const getStudentInviteLink = (_course: Course, orgSiteName: string) => { +export const getStudentInviteLink = (_course: Course, orgSiteName: string, origin: string) => { const hash = encodeURIComponent( btoa( JSON.stringify({ @@ -15,7 +15,7 @@ export const getStudentInviteLink = (_course: Course, orgSiteName: string) => { ) ); - return `https://${orgSiteName}.classroomio.com/invite/s/${hash}`; + return `${origin}/invite/s/${hash}`; }; export const getTextFromHTML = (html: string): string => { @@ -27,7 +27,7 @@ export const getTextFromHTML = (html: string): string => { return dummyDiv.textContent?.trim() || ''; }; -const tagsToReplace = { +const tagsToReplace: { [k: string]: string } = { '&': '&', '<': '<', '>': '>' diff --git a/apps/dashboard/src/lib/utils/store/org.ts b/apps/dashboard/src/lib/utils/store/org.ts index b27922a5..d08f46ce 100644 --- a/apps/dashboard/src/lib/utils/store/org.ts +++ b/apps/dashboard/src/lib/utils/store/org.ts @@ -6,8 +6,7 @@ import type { CurrentOrg, OrgTeamMember, OrgAudience } from '../types/org'; import { ROLE } from '$lib/utils/constants/roles'; import type { UserLessonDataType } from '$lib/utils/types'; -export const orgs = writable([]); -export const currentOrg: Writable = writable({ +export const defaultCurrentOrgState: CurrentOrg = { id: '', name: '', shortName: '', @@ -17,7 +16,10 @@ export const currentOrg: Writable = writable({ role_id: '', landingpage: {}, theme: '' -}); +}; + +export const orgs = writable([]); +export const currentOrg: Writable = writable(defaultCurrentOrgState); export const orgAudience = writable([]); export const orgTeam = writable([]); export const isOrgAdmin = derived( diff --git a/apps/dashboard/src/lib/utils/store/user.ts b/apps/dashboard/src/lib/utils/store/user.ts index af9734cb..5b0f87dd 100644 --- a/apps/dashboard/src/lib/utils/store/user.ts +++ b/apps/dashboard/src/lib/utils/store/user.ts @@ -1,21 +1,15 @@ import { writable } from 'svelte/store'; import type { User } from '@supabase/supabase-js'; -export const user = writable<{ +interface UserStore { openAuthModal: boolean; fetchingUser: boolean; isLoggedIn: boolean; currentSession: User | undefined; expiresAt: number; -}>({ - openAuthModal: false, - fetchingUser: false, - isLoggedIn: false, - currentSession: undefined, - expiresAt: 0 -}); +} -export const profile = writable<{ +interface ProfileStore { id: string | undefined; fullname: string; avatar_url: string; @@ -27,7 +21,17 @@ export const profile = writable<{ goal: string; source: string; telegram_chat_id: number | null; -}>({ +} + +export const defaultUserState: UserStore = { + openAuthModal: false, + fetchingUser: false, + isLoggedIn: false, + currentSession: undefined, + expiresAt: 0 +}; + +export const defaultProfileState: ProfileStore = { id: undefined, fullname: '', avatar_url: 'https://pbs.twimg.com/profile_images/1416443682157473795/dGtFbtht_normal.jpg', @@ -38,4 +42,8 @@ export const profile = writable<{ goal: '', source: '', telegram_chat_id: null -}); +}; + +export const user = writable(defaultUserState); + +export const profile = writable(defaultProfileState); diff --git a/apps/dashboard/src/routes/+layout.svelte b/apps/dashboard/src/routes/+layout.svelte index 7ee0f1fe..1b7e74aa 100644 --- a/apps/dashboard/src/routes/+layout.svelte +++ b/apps/dashboard/src/routes/+layout.svelte @@ -80,8 +80,8 @@ const { user: authUser } = session || {}; console.log('Get user', authUser); - if (!authUser) { - goto('/login?redirect=/' + path); + if (!authUser && !isPublicRoute($page.url.pathname)) { + return goto('/login?redirect=/' + path); } // Check if user has profile @@ -185,7 +185,7 @@ } } - if (!profileData) { + if (!profileData && !isPublicRoute($page.url.pathname)) { goto('/login?redirect=/' + path); } } @@ -239,10 +239,10 @@ if (data.skipAuth) return; // Authentication Steps - if (event === 'SIGNED_IN') { + if (event === 'SIGNED_IN' || event === 'INITIAL_SESSION') { $user.fetchingUser = true; getProfile(); - } else if (!['INITIAL_SESSION', 'TOKEN_REFRESHED'].includes(event)) { + } else if (!['TOKEN_REFRESHED'].includes(event)) { console.log('not logged in, go to login'); return goto('/login'); } diff --git a/apps/dashboard/src/routes/invite/s/[hash]/+page.svelte b/apps/dashboard/src/routes/invite/s/[hash]/+page.svelte index 875bbcfe..0fa081d6 100644 --- a/apps/dashboard/src/routes/invite/s/[hash]/+page.svelte +++ b/apps/dashboard/src/routes/invite/s/[hash]/+page.svelte @@ -16,12 +16,12 @@ } from '$lib/utils/services/notification/notification'; import { snackbar } from '$lib/components/Snackbar/store.js'; import { capturePosthogEvent } from '$lib/utils/services/posthog'; + import { page } from '$app/stores'; export let data; let supabase = getSupabase(); let loading = false; - let refresh = false; let disableSubmit = false; let formRef: HTMLFormElement; @@ -29,16 +29,9 @@ async function handleSubmit() { loading = true; - if (refresh) { - window.location.reload(); - refresh = false; - return; - } - if (!$profile.id || !$profile.email) { console.log('Profile not found', $profile); - refresh = true; - return; + return goto(`/signup?redirect=${$page.url?.pathname || ''}`); } const member = { @@ -124,19 +117,13 @@ bind:formRef >
- {#if refresh} -

- Something went wrong, please try again. -

- {:else} -

{data.name}

-

{data.description}

- {/if} +

{data.name}

+

{data.description}

acc + (cur.progress_rate || 0), 0); + totalCompleted = courses.reduce((acc, cur) => acc + (cur.progress_rate || 0), 0); totalLessons = courses.reduce((acc, cur) => acc + (cur.total_lessons || 0), 0); - progressPercentage = Math.round((totalComPleted / totalLessons) * 100); + progressPercentage = Math.round((totalCompleted / totalLessons) * 100) || 0; } $: getCourses($profile.id, $currentOrg.id); @@ -93,7 +93,7 @@

{#if totalLessons > 0}

- {totalComPleted}/{totalLessons} lessons completed + {totalCompleted}/{totalLessons} lessons completed

{:else}

No courses started

diff --git a/apps/dashboard/src/routes/login/+page.svelte b/apps/dashboard/src/routes/login/+page.svelte index c4ec0aa4..5e8188e9 100644 --- a/apps/dashboard/src/routes/login/+page.svelte +++ b/apps/dashboard/src/routes/login/+page.svelte @@ -7,16 +7,14 @@ import { LOGIN_FIELDS } from '$lib/utils/constants/authentication'; import AuthUI from '$lib/components/AuthUI/index.svelte'; import { currentOrg } from '$lib/utils/store/org'; - import { onDestroy } from 'svelte'; import { capturePosthogEvent } from '$lib/utils/services/posthog'; - let formRef; + let formRef: HTMLFormElement; let supabase = getSupabase(); let fields = Object.assign({}, LOGIN_FIELDS); let submitError: string; let loading = false; - let errors = {}; - // let reloadTimeout: NodeJS.Timeout; + let errors = Object.assign({}, LOGIN_FIELDS); let query = new URLSearchParams($page.url.search); let redirect = query.get('redirect'); @@ -39,12 +37,6 @@ console.log('data', data); if (error) throw error; - // reload page on org site cause for some reason the authlistener on +layout.svelte doesn't run sometimes - // reloadTimeout = setTimeout(() => { - // console.log('Forcing full page reload for auth listener'); - // window.location.reload(); - // }, 1500); - capturePosthogEvent('login', { email: fields.email }); @@ -54,10 +46,6 @@ loading = false; } } - - // onDestroy(() => { - // clearTimeout(reloadTimeout); - // });