From 5f14b36ef871f3f66ea4bf249a8c9a3f79cf999e Mon Sep 17 00:00:00 2001 From: Rotimi Best Date: Tue, 2 May 2023 23:55:26 +0000 Subject: [PATCH] CLASSROOMIO-T-5: Educators Settings CRUD Co-authored-by: Rotimi Best Merge-request: CLASSROOMIO-MR-7 Merged-by: Digdippa Team --- src/components/Avatar/index.svelte | 3 +- src/components/Box/index.svelte | 6 +- src/components/ComingSoon/index.svelte | 15 ++ src/components/Courses/index.svelte | 2 +- src/components/Navigation/app.svelte | 20 +- src/components/Navigation/index.svelte | 16 +- .../{ => Org}/Audience/AudienceList.svelte | 2 +- .../{ => Org}/Audience/index.svelte | 8 +- src/components/Org/Settings/Account.svelte | 0 src/components/Org/Settings/Domains.svelte | 98 +++++++++ .../Org/Settings/OrgSettings.svelte | 141 ++++++++++++ src/components/Org/Settings/Profile.svelte | 129 +++++++++++ .../Org/Settings/TeamMembers.svelte | 205 ++++++++++++++++++ src/components/Org/Settings/index.svelte | 23 ++ src/components/Org/SideBar.svelte | 28 ++- .../OrgSelector/OrgSelectorItem.svelte | 3 +- src/components/PrimaryButton/constants.js | 8 +- src/components/Snackbar/index.svelte | 13 +- src/components/UploadImage/index.svelte | 56 ++--- src/routes/org/[slug]/audience.svelte | 2 +- src/routes/org/[slug]/settings.svelte | 1 - src/routes/org/[slug]/settings/domains.svelte | 22 ++ src/routes/org/[slug]/settings/index.svelte | 17 ++ src/routes/org/[slug]/settings/teams.svelte | 22 ++ src/utils/functions/validator.js | 31 +++ src/utils/services/org/index.js | 48 +++- src/utils/store/org.js | 2 + 27 files changed, 832 insertions(+), 89 deletions(-) create mode 100644 src/components/ComingSoon/index.svelte rename src/components/{ => Org}/Audience/AudienceList.svelte (94%) rename src/components/{ => Org}/Audience/index.svelte (72%) create mode 100644 src/components/Org/Settings/Account.svelte create mode 100644 src/components/Org/Settings/Domains.svelte create mode 100644 src/components/Org/Settings/OrgSettings.svelte create mode 100644 src/components/Org/Settings/Profile.svelte create mode 100644 src/components/Org/Settings/TeamMembers.svelte create mode 100644 src/components/Org/Settings/index.svelte delete mode 100644 src/routes/org/[slug]/settings.svelte create mode 100644 src/routes/org/[slug]/settings/domains.svelte create mode 100644 src/routes/org/[slug]/settings/index.svelte create mode 100644 src/routes/org/[slug]/settings/teams.svelte diff --git a/src/components/Avatar/index.svelte b/src/components/Avatar/index.svelte index 5bf445d5..472618ed 100644 --- a/src/components/Avatar/index.svelte +++ b/src/components/Avatar/index.svelte @@ -2,6 +2,7 @@ export let name = ''; export let src = ''; export let className = ''; + export let shape = 'rounded-full'; export let width = 'w-10'; export let height = 'h-10'; @@ -9,5 +10,5 @@ {name} diff --git a/src/components/Box/index.svelte b/src/components/Box/index.svelte index 3dd3ec7e..29305ffc 100644 --- a/src/components/Box/index.svelte +++ b/src/components/Box/index.svelte @@ -1,5 +1,9 @@ + +
diff --git a/src/components/ComingSoon/index.svelte b/src/components/ComingSoon/index.svelte new file mode 100644 index 00000000..7cc4df0e --- /dev/null +++ b/src/components/ComingSoon/index.svelte @@ -0,0 +1,15 @@ + + +

+ {label} +

+ + diff --git a/src/components/Courses/index.svelte b/src/components/Courses/index.svelte index 6cfb61ee..acead83a 100644 --- a/src/components/Courses/index.svelte +++ b/src/components/Courses/index.svelte @@ -33,7 +33,7 @@ {:else} -

No Courses Created

+

No Courses Created

Share your knowledge with the world by creating engaging courses for your students. diff --git a/src/components/Navigation/app.svelte b/src/components/Navigation/app.svelte index b65db5dd..c65ffdc4 100644 --- a/src/components/Navigation/app.svelte +++ b/src/components/Navigation/app.svelte @@ -1,9 +1,6 @@ @@ -20,22 +17,7 @@

  • -
  • - {#if $user.isLoggedIn} - - - - {/if} -
  • +
  • diff --git a/src/components/Navigation/index.svelte b/src/components/Navigation/index.svelte index d8c55949..a25fc75d 100644 --- a/src/components/Navigation/index.svelte +++ b/src/components/Navigation/index.svelte @@ -1,6 +1,5 @@ + + + + Add + +

    + Add your team mates or collaborators to your organization. Start working + together +

    + +
    + + + +
    +
    +
    + + + Custom domain + +
    +

    Add your own domain name

    + +
    +
    +
    +
    diff --git a/src/components/Org/Settings/OrgSettings.svelte b/src/components/Org/Settings/OrgSettings.svelte new file mode 100644 index 00000000..823d6669 --- /dev/null +++ b/src/components/Org/Settings/OrgSettings.svelte @@ -0,0 +1,141 @@ + + + + + Organization Profile + + + + + + + + + Custom Domain + +

    Customise your Domain

    +

    + Create a custom URL so your audience can get to your organization easily +

    + gotoSetting('/domains')} + /> +
    +
    + + Team + +

    Set up your website

    +

    + Add team mates to your organization so you can both collaborate on + projects. +

    + gotoSetting('/teams')} + /> +
    +
    +
    diff --git a/src/components/Org/Settings/Profile.svelte b/src/components/Org/Settings/Profile.svelte new file mode 100644 index 00000000..7b3dafd2 --- /dev/null +++ b/src/components/Org/Settings/Profile.svelte @@ -0,0 +1,129 @@ + + + + + Profile Picture + + + + + + Personal Information + + + + + + + + + + + diff --git a/src/components/Org/Settings/TeamMembers.svelte b/src/components/Org/Settings/TeamMembers.svelte new file mode 100644 index 00000000..a69678a0 --- /dev/null +++ b/src/components/Org/Settings/TeamMembers.svelte @@ -0,0 +1,205 @@ + + + + + Add + +

    + Add your team mates or collaborators to your organization. Start working + together +

    + +
    + + + + + +
    +
    +
    + + + Members + + {#if isFetching} + + {:else} + {#each $orgTeam as teamMember} +
    +
    +

    + {teamMember.email} +

    + + {#if !teamMember.verified} + + {:else if teamMember.profileId === $profile.id} + + {/if} +
    + {#if teamMember.profileId !== $profile.id && isTeamMemberAdmin($orgTeam, $profile.id)} + onRemove(teamMember.id)} + isLoading={isRemoving} + isDisabled={isRemoving} + /> + {/if} +
    + {/each} + {/if} +
    +
    +
    diff --git a/src/components/Org/Settings/index.svelte b/src/components/Org/Settings/index.svelte new file mode 100644 index 00000000..10d1dbce --- /dev/null +++ b/src/components/Org/Settings/index.svelte @@ -0,0 +1,23 @@ + + + + + + + + + + + + + + + + diff --git a/src/components/Org/SideBar.svelte b/src/components/Org/SideBar.svelte index 85d8c09d..8aa6012e 100644 --- a/src/components/Org/SideBar.svelte +++ b/src/components/Org/SideBar.svelte @@ -1,6 +1,5 @@ -
    +
    { - fileinput.click(); - }} + 'setwidthheight'} pointer border-2 border-gray-200 relative {shape}" > {#if src} - Avatar + Avatar {:else if avatar} - Avatar + Avatar {:else} {/if} -
    - -
    +

    { + fileinput.click(); + }} + > + Upload Image +

    + diff --git a/src/routes/org/[slug]/audience.svelte b/src/routes/org/[slug]/audience.svelte index 91301ab9..39573071 100644 --- a/src/routes/org/[slug]/audience.svelte +++ b/src/routes/org/[slug]/audience.svelte @@ -1,6 +1,6 @@ + + + Custom domain - ClassroomIO + + +
    +
    + Back to Settings +
    +

    Custom domain

    +
    + + +
    +
    diff --git a/src/routes/org/[slug]/settings/index.svelte b/src/routes/org/[slug]/settings/index.svelte new file mode 100644 index 00000000..30e073c5 --- /dev/null +++ b/src/routes/org/[slug]/settings/index.svelte @@ -0,0 +1,17 @@ + + + + Settings - ClassroomIO + + +
    +
    +
    +

    Settings

    +
    + + +
    +
    diff --git a/src/routes/org/[slug]/settings/teams.svelte b/src/routes/org/[slug]/settings/teams.svelte new file mode 100644 index 00000000..0f474507 --- /dev/null +++ b/src/routes/org/[slug]/settings/teams.svelte @@ -0,0 +1,22 @@ + + + + Teams - ClassroomIO + + +
    +
    + Back to Settings +
    +

    Team members

    +
    + + +
    +
    diff --git a/src/utils/functions/validator.js b/src/utils/functions/validator.js index 2c579f71..6ca5e55b 100644 --- a/src/utils/functions/validator.js +++ b/src/utils/functions/validator.js @@ -1,4 +1,5 @@ import z from 'zod'; +import { validateEmail } from './validateEmail'; const forgotValidationSchema = z.object({ email: z.string().email({ @@ -100,3 +101,33 @@ export const onboardingValidation = (fields = {}, step) => { export const getDisableSubmit = ({ password, confirmPassword }) => { return !!(password && confirmPassword && password !== confirmPassword); }; + +export const validateEmailInString = (emailsStr) => { + let error = ''; + let hasError = false; + + if (!emailsStr) { + return { + hasError: true, + error: 'Enter an email', + emails: [], + }; + } + + const emails = emailsStr.split(',').map((_email) => { + const email = _email.trim(); + + if (!validateEmail(email)) { + hasError = true; + error += !error.length ? `Not valid email: ${email}` : `, ${email}`; + } + + return email; + }); + + return { + hasError, + error, + emails, + }; +}; diff --git a/src/utils/services/org/index.js b/src/utils/services/org/index.js index 55e33b26..37688994 100644 --- a/src/utils/services/org/index.js +++ b/src/utils/services/org/index.js @@ -1,5 +1,47 @@ import { supabase } from '../../functions/supabase'; -import { orgs, currentOrg, orgAudience } from '../../store/org'; +import { orgs, currentOrg, orgAudience, orgTeam } from '../../store/org'; +import { ROLE, ROLE_LABEL } from '../../constants/roles'; + +export async function getOrgTeam(orgId) { + const { data, error } = await supabase + .from('organizationmember') + .select( + ` + id, + email, + verified, + role_id, + profile( + id, + fullname, + email + ) + ` + ) + .eq('organization_id', orgId) + .order('id', { ascending: false }); + + const team = []; + if (data?.length) { + data.forEach((teamMember) => { + team.push({ + id: teamMember.id, + email: teamMember?.profile?.email || teamMember?.email, + verified: teamMember?.verified, + profileId: teamMember?.profile?.id, + role: ROLE_LABEL[teamMember?.role_id] || '', + isAdmin: teamMember?.role_id === ROLE.ADMIN, + }); + }); + + orgTeam.set(team); + } + + return { + team, + error, + }; +} export async function getOrganizations(userId) { const { data, error } = await supabase @@ -11,7 +53,8 @@ export async function getOrganizations(userId) { organization ( id, name, - siteName + siteName, + avatar_url ) ` ) @@ -26,6 +69,7 @@ export async function getOrganizations(userId) { shortName: orgMember?.organization?.name?.substring(0, 2)?.toUpperCase() || '', siteName: orgMember?.organization?.siteName, + avatar_url: orgMember?.organization?.avatar_url, }); }); diff --git a/src/utils/store/org.js b/src/utils/store/org.js index 6d46fc9b..df18fe2a 100644 --- a/src/utils/store/org.js +++ b/src/utils/store/org.js @@ -6,5 +6,7 @@ export const currentOrg = writable({ name: '', shortName: '', siteName: '', + avatar_url: '', }); export const orgAudience = writable([]); +export const orgTeam = writable([]);