diff --git a/dump.sql b/dump.sql new file mode 100644 index 00000000..e69de29b diff --git a/src/components/Avatar/index.svelte b/src/components/Avatar/index.svelte index e86a8e67..5bf445d5 100644 --- a/src/components/Avatar/index.svelte +++ b/src/components/Avatar/index.svelte @@ -2,10 +2,12 @@ export let name = ''; export let src = ''; export let className = ''; + export let width = 'w-10'; + export let height = 'h-10'; {name} diff --git a/src/components/Box/index.svelte b/src/components/Box/index.svelte index 8e58130d..3dd3ec7e 100644 --- a/src/components/Box/index.svelte +++ b/src/components/Box/index.svelte @@ -1,3 +1,5 @@ -
+
diff --git a/src/components/Chip/Text.svelte b/src/components/Chip/Text.svelte new file mode 100644 index 00000000..19320503 --- /dev/null +++ b/src/components/Chip/Text.svelte @@ -0,0 +1,19 @@ + + +

+ {value} +

+ + diff --git a/src/components/Course/components/Navigation/index.svelte b/src/components/Course/components/Navigation/index.svelte index ec0250cf..2378099f 100644 --- a/src/components/Course/components/Navigation/index.svelte +++ b/src/components/Course/components/Navigation/index.svelte @@ -21,9 +21,10 @@ import Settings from '../Settings/index.svelte'; import { settingsDialog } from '../Settings/store'; import { lessons } from '../Lesson/store/lessons'; - import { course, group } from '../../store'; + import { course } from '../../store'; import { updateCourse } from '../../../../utils/services/courses'; import { profile } from '../../../../utils/store/user'; + import { currentOrg } from '../../../../utils/store/org'; import { isMobile } from '../../../../utils/store/useMobile'; // export let lessonId; @@ -208,7 +209,7 @@ > goto('/courses')} + onClick={() => goto(`/org/${$currentOrg.siteName}/courses`)} buttonClassName="mx-3" > diff --git a/src/components/CourseLandingPage/components/Editor/index.svelte b/src/components/CourseLandingPage/components/Editor/index.svelte index feb4a9d5..47978d5d 100644 --- a/src/components/CourseLandingPage/components/Editor/index.svelte +++ b/src/components/CourseLandingPage/components/Editor/index.svelte @@ -2,6 +2,8 @@ import { goto } from '@sapper/app'; import ChevronRight24 from 'carbon-icons-svelte/lib/ChevronRight24'; import ArrowLeft24 from 'carbon-icons-svelte/lib/ArrowLeft24'; + import ArrowUpRight24 from 'carbon-icons-svelte/lib/ArrowUpRight24'; + import Container from './Container.svelte'; import IconButton from '../../../IconButton/index.svelte'; import CloseButton from '../../../Buttons/Close/index.svelte'; @@ -94,6 +96,14 @@ const link = `${window.location.origin}/course/${course.slug}`; window.open(link, '_blank'); } + + async function handlePublish() { + loading = true; + await updateCourse(courseId, undefined, { + is_published: true, + }); + loading = false; + } @@ -111,11 +121,14 @@ isLoading={loading} /> + + +
diff --git a/src/components/CourseLandingPage/components/PricingSection.svelte b/src/components/CourseLandingPage/components/PricingSection.svelte index 79f27d68..e7b14fd7 100644 --- a/src/components/CourseLandingPage/components/PricingSection.svelte +++ b/src/components/CourseLandingPage/components/PricingSection.svelte @@ -2,6 +2,7 @@ import PrimaryButton from '../../PrimaryButton/index.svelte'; import { VARIANTS } from '../../PrimaryButton/constants'; import type { Course } from '../../../utils/types'; + import getCurrencyFormatter from '../../../utils/functions/getCurrencyFormatter'; import { get } from 'lodash'; export let className = ''; @@ -26,11 +27,7 @@ function setFormatter(currency: string | undefined) { if (!currency) return; - formatter = new Intl.NumberFormat('en-US', { - style: 'currency', - currency: currency, - minimumFractionDigits: 2, - }); + formatter = getCurrencyFormatter(currency); } $: setFormatter(courseData.currency); diff --git a/src/components/Courses/components/Card/Loader.svelte b/src/components/Courses/components/Card/Loader.svelte new file mode 100644 index 00000000..c0deb9d0 --- /dev/null +++ b/src/components/Courses/components/Card/Loader.svelte @@ -0,0 +1,28 @@ + + +
+ +
+ + + + + + +
+ + +
+ +
+
+ + diff --git a/src/components/Courses/components/Card/index.svelte b/src/components/Courses/components/Card/index.svelte index 5b5bd203..60d7ae90 100644 --- a/src/components/Courses/components/Card/index.svelte +++ b/src/components/Courses/components/Card/index.svelte @@ -1,13 +1,20 @@ - -
- + + diff --git a/src/components/Courses/index.svelte b/src/components/Courses/index.svelte index a224dab9..61f7a7bb 100644 --- a/src/components/Courses/index.svelte +++ b/src/components/Courses/index.svelte @@ -1,7 +1,8 @@ @@ -12,21 +13,30 @@ class="flex items-center justify-center lg:justify-start flex-wrap my-4 m-auto" > {#if $courseMetaDeta.isLoading} - - - + + + {:else} {#each $courses as courseData} {:else} -

No Course Assigned

+ +

No Courses Created

+

+ Share your knowledge with the world by creating engaging courses for + your students. +

{/each} {/if} diff --git a/src/components/Dropdown/index.svelte b/src/components/Dropdown/index.svelte index 87abe8e2..736c92c8 100644 --- a/src/components/Dropdown/index.svelte +++ b/src/components/Dropdown/index.svelte @@ -32,7 +32,11 @@
+ + diff --git a/src/components/PrimaryButton/index.svelte b/src/components/PrimaryButton/index.svelte index 0fc77aaa..7a5cb55d 100644 --- a/src/components/PrimaryButton/index.svelte +++ b/src/components/PrimaryButton/index.svelte @@ -12,14 +12,13 @@ export let isDisabled = false; export let isLoading = false; - $: variant = isLoading ? VARIANTS.OUTLINED : variant; $: isDisabled = isLoading ? true : false; - {/each} -
- {#if errors.role} -

{errors.role}

- {/if} -
+

ClassroomIO

- {:else} - -
-
- -
- - - {#each goals as goal} -
+ +
+ {#if step === 1} + +
+ + + + + (isSiteNameTouched = true)} + /> + + + +
+ {:else} + +
+
+ +
+ - {/each} - - {#if errors.goal} -

{errors.goal}

- {/if} -
- -
- + + {#each educatorGoals as goal} + + {/each} + + {#if errors.goal} +

{errors.goal}

+ {/if} +
- - {#each sources as source} -
-
- {/if} -
- - -
-
- -
- -
- {#if step > 1} - (step = step - 1)} - /> {/if} - +
+ + +
+
+ +
+ +
+ {#if step > 1} + (step = step - 1)} + /> + {/if} + +
- +{/if} diff --git a/src/routes/org/[slug]/index.svelte b/src/routes/org/[slug]/index.svelte new file mode 100644 index 00000000..e02f416e --- /dev/null +++ b/src/routes/org/[slug]/index.svelte @@ -0,0 +1,398 @@ + + + + + + Dashboard - ClassroomIO + + +
+
+

Dashboard

+ +
+ +
+ {#each boxes as box} +
+

{box.label}

+

{box.value}

+
+ {/each} +
+ +
+ +
+

Your Schedule

+
+ {#if !$isMobile} +
+ +
+ {/if} + + {#if $isMobile} +
+ + + +
+ {:else} +

+ {formatDate($store?.selected)} +

+ {/if} + + {#each selectedDateLessonData as lessonData} + + {:else} +

+ No lesson on this day +

+ {/each} +
+
+ + +
+

Your Activities

+
+ {#each activities as activity} +
+ +
+
+

{activity.name}

+

+ {activity.description} +

+ View +
+ +
+

{activity.time}

+
+
+
+ {/each} +
+
+
+
+ + diff --git a/src/routes/org/[slug]/settings.svelte b/src/routes/org/[slug]/settings.svelte new file mode 100644 index 00000000..a01c11a4 --- /dev/null +++ b/src/routes/org/[slug]/settings.svelte @@ -0,0 +1 @@ +settings diff --git a/src/routes/org/[slug]/site.svelte b/src/routes/org/[slug]/site.svelte new file mode 100644 index 00000000..c3a68fa6 --- /dev/null +++ b/src/routes/org/[slug]/site.svelte @@ -0,0 +1 @@ +Sites Page diff --git a/src/utils/functions/getCurrencyFormatter.ts b/src/utils/functions/getCurrencyFormatter.ts new file mode 100644 index 00000000..3603fcec --- /dev/null +++ b/src/utils/functions/getCurrencyFormatter.ts @@ -0,0 +1,7 @@ +export default (currency: string | undefined) => { + return new Intl.NumberFormat('en-US', { + style: 'currency', + currency: currency, + minimumFractionDigits: 2, + }); +}; diff --git a/src/utils/functions/org.js b/src/utils/functions/org.js new file mode 100644 index 00000000..e69de29b diff --git a/src/utils/functions/validator.js b/src/utils/functions/validator.js index 17a0f8b9..2c579f71 100644 --- a/src/utils/functions/validator.js +++ b/src/utils/functions/validator.js @@ -28,10 +28,8 @@ const resetValidationSchema = z.object({ const onboardingValidationSchema = { stepOne: z.object({ fullname: z.string().min(1, { message: 'Enter your fullname' }), - role: z.string({ - required_error: 'Please select a goal', - invalid_type_error: 'Please select a goal', - }), + orgName: z.string().min(1, { message: 'Enter your organisation name' }), + siteName: z.string().min(1, { message: 'Enter your site name' }), }), stepTwo: z.object({ goal: z diff --git a/src/utils/services/org/index.js b/src/utils/services/org/index.js new file mode 100644 index 00000000..e2bde4cd --- /dev/null +++ b/src/utils/services/org/index.js @@ -0,0 +1,39 @@ +import { supabase } from '../../functions/supabase'; +import { orgs, currentOrg } from '../../store/org'; + +export async function getOrganizations(userId) { + const { data, error } = await supabase + .from('organizationmember') + .select( + ` + id, + profile_id, + organization ( + id, + name, + siteName + ) + ` + ) + .eq('profile_id', userId); + + const orgsArray = []; + if (data.length) { + data.forEach((orgMember) => { + orgsArray.push({ + id: orgMember?.organization?.id, + name: orgMember?.organization?.name, + siteName: orgMember?.organization?.siteName, + }); + }); + + orgs.set(orgsArray); + currentOrg.set(orgsArray[0]); + } + + return { + orgs: orgsArray, + currentOrg: orgsArray[0], + error, + }; +} diff --git a/src/utils/store/org.js b/src/utils/store/org.js new file mode 100644 index 00000000..bc0e88e7 --- /dev/null +++ b/src/utils/store/org.js @@ -0,0 +1,4 @@ +import { writable } from 'svelte/store'; + +export const orgs = writable([]); +export const currentOrg = writable({}); diff --git a/static/images/classroomio-course-img-template.jpg b/static/images/classroomio-course-img-template.jpg new file mode 100644 index 00000000..b8fe4e4a Binary files /dev/null and b/static/images/classroomio-course-img-template.jpg differ diff --git a/supabase/.gitignore b/supabase/.gitignore new file mode 100644 index 00000000..773c7c3e --- /dev/null +++ b/supabase/.gitignore @@ -0,0 +1,3 @@ +# Supabase +.branches +.temp diff --git a/supabase/config.toml b/supabase/config.toml new file mode 100644 index 00000000..c208a647 --- /dev/null +++ b/supabase/config.toml @@ -0,0 +1,71 @@ +# A string used to distinguish different Supabase projects on the same host. Defaults to the working +# directory name when running `supabase init`. +project_id = "classroomio" + +[api] +# Port to use for the API URL. +port = 54321 +# Schemas to expose in your API. Tables, views and stored procedures in this schema will get API +# endpoints. public and storage are always included. +schemas = [] +# Extra schemas to add to the search_path of every request. +extra_search_path = ["extensions"] +# The maximum number of rows returns from a view, table, or stored procedure. Limits payload size +# for accidental or malicious requests. +max_rows = 1000 + +[db] +# Port to use for the local database URL. +port = 54322 +# The database major version to use. This has to be the same as your remote database's. Run `SHOW +# server_version;` on the remote database to check. +major_version = 12 + +[studio] +# Port to use for Supabase Studio. +port = 54323 + +# Email testing server. Emails sent with the local dev setup are not actually sent - rather, they +# are monitored, and you can view the emails that would have been sent from the web interface. +[inbucket] +# Port to use for the email testing server web interface. +port = 54324 +smtp_port = 54325 +pop3_port = 54326 + +[storage] +# The maximum file size allowed (e.g. "5MB", "500KB"). +file_size_limit = "50MiB" + +[auth] +# The base URL of your website. Used as an allow-list for redirects and for constructing URLs used +# in emails. +site_url = "http://localhost:3000" +# A list of *exact* URLs that auth providers are permitted to redirect to post authentication. +additional_redirect_urls = ["https://localhost:3000"] +# How long tokens are valid for, in seconds. Defaults to 3600 (1 hour), maximum 604,800 seconds (one +# week). +jwt_expiry = 3600 +# Allow/disallow new user signups to your project. +enable_signup = true + +[auth.email] +# Allow/disallow new user signups via email to your project. +enable_signup = true +# If enabled, a user will be required to confirm any email change on both the old, and new email +# addresses. If disabled, only the new email is required to confirm. +double_confirm_changes = true +# If enabled, users need to confirm their email address before signing in. +enable_confirmations = false + +# Use an external OAuth provider. The full list of providers are: `apple`, `azure`, `bitbucket`, +# `discord`, `facebook`, `github`, `gitlab`, `google`, `twitch`, `twitter`, `slack`, `spotify`. +[auth.external.apple] +enabled = false +client_id = "" +secret = "" +# Overrides the default auth redirectUrl. +redirect_uri = "" +# Overrides the default auth provider URL. Used to support self-hosted gitlab, single-tenant Azure, +# or any other third-party OIDC providers. +url = "" diff --git a/supabase/seed.sql b/supabase/seed.sql new file mode 100644 index 00000000..e69de29b