CLASSROOMIO-T-80: Replace sapper with sveltekit
This commit is contained in:
@@ -1,20 +1,19 @@
|
||||
<script>
|
||||
import { goto } from '@sapper/app';
|
||||
import { appStore } from '../utils/store/app';
|
||||
import ErrorIcon from '../components/Icons/ErrorIcon.svelte';
|
||||
import ErrorIconDarkMode from '../components/Icons/ErrorIconDarkMode.svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import { browser } from '$app/environment';
|
||||
import { page } from '$app/stores';
|
||||
import { appStore } from '$lib/utils/store/app';
|
||||
import ErrorIcon from '$lib/components/Icons/ErrorIcon.svelte';
|
||||
import ErrorIconDarkMode from '$lib/components/Icons/ErrorIconDarkMode.svelte';
|
||||
|
||||
export let status;
|
||||
export let error;
|
||||
|
||||
if (status == 404) {
|
||||
if ($page.status == 404 && browser) {
|
||||
goto('/404');
|
||||
}
|
||||
console.error(error);
|
||||
console.error($page.error?.message);
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>{status}</title>
|
||||
<title>{$page.status}</title>
|
||||
</svelte:head>
|
||||
|
||||
<div
|
||||
@@ -1,66 +1,82 @@
|
||||
<script context="module">
|
||||
export function preload(page, { config }) {
|
||||
return { config };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import { derived } from 'svelte/store';
|
||||
import { stores, goto } from '@sapper/app';
|
||||
import { goto } from '$app/navigation';
|
||||
import { dev } from '$app/environment';
|
||||
import { page, navigating } from '$app/stores';
|
||||
import isEmpty from 'lodash/isEmpty';
|
||||
import * as Sentry from '@sentry/browser';
|
||||
import { Integrations } from '@sentry/tracing';
|
||||
import { CaptureConsole } from '@sentry/integrations';
|
||||
import { Theme } from 'carbon-components-svelte';
|
||||
import { Moon } from 'svelte-loading-spinners';
|
||||
import Tailwindcss from '../components/Tailwindcss.svelte';
|
||||
import LandingNavigation from '../components/Navigation/index.svelte';
|
||||
import OrgNavigation from '../components/Navigation/app.svelte';
|
||||
import LMSNavigation from '../components/Navigation/lms.svelte';
|
||||
import OrgLandingPage from '../components/Org/LandingPage/index.svelte';
|
||||
import Snackbar from '../components/Snackbar/index.svelte';
|
||||
import Backdrop from '../components/Backdrop/index.svelte';
|
||||
import OrgSideBar from '../components/Org/SideBar.svelte';
|
||||
import LMSSideBar from '../components/LMS/SideBar.svelte';
|
||||
import LandingNavigation from '$lib/components/Navigation/index.svelte';
|
||||
import OrgNavigation from '$lib/components/Navigation/app.svelte';
|
||||
import LMSNavigation from '$lib/components/Navigation/lms.svelte';
|
||||
import OrgLandingPage from '$lib/components/Org/LandingPage/index.svelte';
|
||||
import Snackbar from '$lib/components/Snackbar/index.svelte';
|
||||
import Backdrop from '$lib/components/Backdrop/index.svelte';
|
||||
import OrgSideBar from '$lib/components/Org/SideBar.svelte';
|
||||
import LMSSideBar from '$lib/components/LMS/SideBar.svelte';
|
||||
// import SideBar from "../components/SideBar/index.svelte";
|
||||
// import Footer from '../components/Footer/index.svelte';
|
||||
import Apps from '../components/Apps/index.svelte';
|
||||
import PlayQuiz from '../components/Org/Quiz/Play/index.svelte';
|
||||
// import Footer from '$lib/components/Footer/index.svelte';
|
||||
import Apps from '$lib/components/Apps/index.svelte';
|
||||
import PlayQuiz from '$lib/components/Org/Quiz/Play/index.svelte';
|
||||
import {
|
||||
isCoursesPage,
|
||||
isOrgPage,
|
||||
isLMSPage,
|
||||
isQuizPage,
|
||||
} from '../utils/functions/app';
|
||||
import showAppsSideBar from '../utils/functions/showAppsSideBar';
|
||||
import isPublicRoute from '../utils/functions/routes/isPublicRoute';
|
||||
import { user, profile } from '../utils/store/user';
|
||||
import { getSupabase } from '../utils/functions/supabase';
|
||||
import { isMobile } from '../utils/store/useMobile';
|
||||
import { ROUTES_TO_HIDE_NAV, ROUTE } from '../utils/constants/routes';
|
||||
import { getOrganizations, getCurrentOrg } from '../utils/services/org';
|
||||
import { toggleBodyByTheme } from '../utils/functions/app';
|
||||
import { appStore } from '../utils/store/app';
|
||||
import { currentOrg } from '../utils/store/org';
|
||||
import { blockedSubdomain } from '../utils/constants/app';
|
||||
} from '$lib/utils/functions/app';
|
||||
import showAppsSideBar from '$lib/utils/functions/showAppsSideBar';
|
||||
import isPublicRoute from '$lib/utils/functions/routes/isPublicRoute';
|
||||
import { user, profile } from '$lib/utils/store/user';
|
||||
import { getSupabase } from '$lib/utils/functions/supabase';
|
||||
import { isMobile } from '$lib/utils/store/useMobile';
|
||||
import { ROUTES_TO_HIDE_NAV, ROUTE } from '$lib/utils/constants/routes';
|
||||
import { getOrganizations, getCurrentOrg } from '$lib/utils/services/org';
|
||||
import { toggleBodyByTheme } from '$lib/utils/functions/app';
|
||||
import { appStore } from '$lib/utils/store/app';
|
||||
import { currentOrg } from '$lib/utils/store/org';
|
||||
import { blockedSubdomain } from '$lib/utils/constants/app';
|
||||
|
||||
export let segment;
|
||||
export let config;
|
||||
import '../app.postcss';
|
||||
|
||||
let { page, preloading } = stores();
|
||||
|
||||
let supabase = getSupabase(config);
|
||||
let path = $page.path.replace('/', '');
|
||||
let supabase = getSupabase();
|
||||
let path = $page.url.pathname.replace('/', '');
|
||||
let theme = 'white';
|
||||
let skipAuth = false;
|
||||
|
||||
const delayedPreloading = derived(preloading, (currentPreloading, set) => {
|
||||
const delayedPreloading = derived(navigating, (currentPreloading, set) => {
|
||||
setTimeout(() => set(currentPreloading), 250);
|
||||
});
|
||||
|
||||
function setupSentry() {
|
||||
if (!dev) {
|
||||
Sentry.init({
|
||||
dsn: 'https://c966f7e8cb1d4306be20b26bb4f0cc96@o476906.ingest.sentry.io/5999999',
|
||||
integrations: [
|
||||
new Integrations.BrowserTracing(),
|
||||
new CaptureConsole({
|
||||
levels: ['error'],
|
||||
}),
|
||||
],
|
||||
environment: !dev ? 'production' : 'development',
|
||||
// Set tracesSampleRate to 1.0 to capture 100%
|
||||
// of transactions for performance monitoring.
|
||||
// We recommend adjusting this value in production
|
||||
tracesSampleRate: 1.0,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async function getProfile() {
|
||||
const params = new URLSearchParams(window.location.search);
|
||||
// Get user profile
|
||||
const authUser = supabase.auth.user();
|
||||
const {
|
||||
data: { session },
|
||||
} = await supabase.auth.getSession();
|
||||
const { user: authUser } = session;
|
||||
console.log('Get user profile', authUser);
|
||||
|
||||
// Check if user has profile
|
||||
@@ -71,21 +87,26 @@
|
||||
} = await supabase
|
||||
.from('profile')
|
||||
.select(`*`)
|
||||
.eq('id', authUser.id)
|
||||
.eq('id', authUser?.id)
|
||||
.single();
|
||||
|
||||
if (error && !profileData && status === 406) {
|
||||
if (error && !profileData && status === 406 && authUser) {
|
||||
// User wasn't found, create profile
|
||||
console.log(`User wasn't found, create profile`);
|
||||
|
||||
const [regexUsernameMatch] = [...authUser.email.matchAll(/(.*)@/g)];
|
||||
const [regexUsernameMatch] = [
|
||||
...(authUser.email?.matchAll(/(.*)@/g) || []),
|
||||
];
|
||||
|
||||
const { data, error } = await supabase.from('profile').insert({
|
||||
id: authUser.id,
|
||||
username: regexUsernameMatch[1] + '1669991321770',
|
||||
fullname: regexUsernameMatch[1],
|
||||
email: authUser.email,
|
||||
});
|
||||
const { data, error } = await supabase
|
||||
.from('profile')
|
||||
.insert({
|
||||
id: authUser.id,
|
||||
username: regexUsernameMatch[1] + '1669991321770',
|
||||
fullname: regexUsernameMatch[1],
|
||||
email: authUser.email,
|
||||
})
|
||||
.select();
|
||||
|
||||
// Profile created, go to profile page
|
||||
if (!error && data) {
|
||||
@@ -105,7 +126,8 @@
|
||||
organization_id: $currentOrg.id,
|
||||
profile_id: $profile.id,
|
||||
role_id: 3,
|
||||
});
|
||||
})
|
||||
.select();
|
||||
if (error) {
|
||||
console.error('Error adding user to organisation', error);
|
||||
} else {
|
||||
@@ -115,8 +137,8 @@
|
||||
$currentOrg.memberId = memberId;
|
||||
}
|
||||
|
||||
if (params.has('redirect')) {
|
||||
goto(params.get('redirect'));
|
||||
if (params.get('redirect')) {
|
||||
goto(params.get('redirect') || '');
|
||||
} else {
|
||||
goto('/lms');
|
||||
}
|
||||
@@ -141,7 +163,7 @@
|
||||
// student redirect
|
||||
if ($appStore.isStudentDomain) {
|
||||
if (params.has('redirect')) {
|
||||
goto(params.get('redirect'));
|
||||
goto(params.get('redirect') || '');
|
||||
} else {
|
||||
goto('/lms');
|
||||
}
|
||||
@@ -184,27 +206,29 @@
|
||||
onMount(() => {
|
||||
console.log(
|
||||
'Welcome to ClassroomIO, we are grateful you chose us.',
|
||||
$page.host,
|
||||
$page.url.host,
|
||||
`\nIs student domain: ${$appStore.isStudentDomain}`
|
||||
);
|
||||
// Disable GA on localhost
|
||||
if (config && !config.isProd) {
|
||||
if (dev) {
|
||||
console.log('disable GA');
|
||||
window['ga-disable-G-C7WBN0S06R'] = true;
|
||||
}
|
||||
|
||||
setupSentry();
|
||||
|
||||
handleResize();
|
||||
|
||||
if (
|
||||
!localStorage.getItem('supabase.auth.token') &&
|
||||
!isPublicRoute($page.path)
|
||||
) {
|
||||
console.log(
|
||||
'No auth token and is not a public route, redirect to login',
|
||||
path
|
||||
);
|
||||
return goto('/login');
|
||||
}
|
||||
// if (
|
||||
// !localStorage.getItem('supabase.auth.token') &&
|
||||
// !isPublicRoute($page.url.pathname)
|
||||
// ) {
|
||||
// console.log(
|
||||
// 'No auth token and is not a public route, redirect to login',
|
||||
// path
|
||||
// );
|
||||
// return goto('/login');
|
||||
// }
|
||||
|
||||
const { data: authListener } = supabase.auth.onAuthStateChange(
|
||||
(event, session) => {
|
||||
@@ -242,13 +266,13 @@
|
||||
}
|
||||
|
||||
return () => {
|
||||
authListener.unsubscribe();
|
||||
authListener?.unsubscribe();
|
||||
};
|
||||
});
|
||||
|
||||
$: path = $page.path.replace('/', '');
|
||||
$: path = $page.url.pathname.replace('/', '');
|
||||
$: theme = $appStore.isDark ? 'g100' : 'white';
|
||||
$: setOrgBasedOnUrl($page.host);
|
||||
$: setOrgBasedOnUrl($page.url.host);
|
||||
</script>
|
||||
|
||||
<svelte:window on:resize={handleResize} />
|
||||
@@ -258,46 +282,45 @@
|
||||
</svelte:head>
|
||||
|
||||
<Theme bind:theme />
|
||||
<Tailwindcss />
|
||||
|
||||
<Snackbar />
|
||||
|
||||
{#if skipAuth}
|
||||
<PlayQuiz />
|
||||
{:else if $appStore.isStudentDomain && !path}
|
||||
<OrgLandingPage {segment} />
|
||||
<OrgLandingPage />
|
||||
{:else}
|
||||
<main class="dark:bg-gray-800">
|
||||
{#if $preloading && $delayedPreloading}
|
||||
{#if $navigating && $delayedPreloading}
|
||||
<Backdrop>
|
||||
<Moon size="60" color="#1d4ed8" unit="px" duration="1s" />
|
||||
</Backdrop>
|
||||
{/if}
|
||||
{#if !ROUTES_TO_HIDE_NAV.includes($page.path) && !isCoursesPage(path)}
|
||||
{#if isOrgPage($page.path) || $page.path.includes('profile')}
|
||||
{#if !ROUTES_TO_HIDE_NAV.includes($page.url.pathname) && !isCoursesPage(path)}
|
||||
{#if isOrgPage($page.url.pathname) || $page.url.pathname.includes('profile')}
|
||||
<OrgNavigation />
|
||||
{:else if isLMSPage($page.path)}
|
||||
{:else if isLMSPage($page.url.pathname)}
|
||||
<LMSNavigation />
|
||||
{:else}
|
||||
<LandingNavigation
|
||||
{segment}
|
||||
logo={$appStore.isStudentDomain ? $currentOrg.avatar_url : undefined}
|
||||
orgName={$appStore.isStudentDomain ? $currentOrg.name : undefined}
|
||||
disableLogin={false}
|
||||
/>
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
<div class="flex justify-between">
|
||||
{#if isOrgPage($page.path)}
|
||||
{#if isOrgPage($page.url.pathname)}
|
||||
<div class="org-root w-full flex items-center justify-between">
|
||||
{#if !isQuizPage($page.path)}
|
||||
{#if !isQuizPage($page.url.pathname)}
|
||||
<OrgSideBar />
|
||||
{/if}
|
||||
<div class="org-slot bg-white dark:bg-gray-800">
|
||||
<slot />
|
||||
</div>
|
||||
</div>
|
||||
{:else if isLMSPage($page.path)}
|
||||
{:else if isLMSPage($page.url.pathname)}
|
||||
<div class="org-root w-full flex items-center justify-between">
|
||||
<LMSSideBar />
|
||||
<div class="org-slot bg-white dark:bg-gray-800">
|
||||
@@ -315,7 +338,7 @@
|
||||
</main>
|
||||
|
||||
{#if !['about', ''].includes(path)}
|
||||
<!-- <Footer {segment} /> -->
|
||||
<!-- <Footer /> -->
|
||||
{/if}
|
||||
{/if}
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
<script>
|
||||
import FlowStreamReference32 from 'carbon-icons-svelte/lib/FlowStreamReference32';
|
||||
import ChartClusterBar32 from 'carbon-icons-svelte/lib/ChartClusterBar32';
|
||||
import MachineLearningModel32 from 'carbon-icons-svelte/lib/MachineLearningModel32';
|
||||
import { BarLoader } from 'svelte-loading-spinners';
|
||||
import TextField from '../components/Form/TextField.svelte';
|
||||
import PrimaryButton from '../components/PrimaryButton/index.svelte';
|
||||
import { VARIANTS } from '../components/PrimaryButton/constants';
|
||||
import { getSupabase } from '../utils/functions/supabase';
|
||||
import { validateEmail } from '../utils/functions/validateEmail';
|
||||
import FlowStreamReferenceIcon from 'carbon-icons-svelte/lib/FlowStreamReference.svelte';
|
||||
import ChartClusterBarIcon from 'carbon-icons-svelte/lib/ChartClusterBar.svelte';
|
||||
import MachineLearningModelIcon from 'carbon-icons-svelte/lib/MachineLearningModel.svelte';
|
||||
import TextField from '$lib/components/Form/TextField.svelte';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import { getSupabase } from '$lib/utils/functions/supabase';
|
||||
import { validateEmail } from '$lib/utils/functions/validateEmail';
|
||||
|
||||
let email;
|
||||
let isAdding = false;
|
||||
@@ -37,9 +35,7 @@
|
||||
if (!email || !validateEmail(email)) return;
|
||||
isAdding = true;
|
||||
|
||||
await supabase
|
||||
.from('waitinglist')
|
||||
.insert([{ email }], { returning: 'minimal' });
|
||||
await supabase.from('waitinglist').insert([{ email }]);
|
||||
|
||||
success = true;
|
||||
|
||||
@@ -103,11 +99,11 @@
|
||||
>
|
||||
<h3 class="dark:text-white text-3xl">
|
||||
{#if index === 0}
|
||||
<FlowStreamReference32 class="carbon-icon" />
|
||||
<FlowStreamReferenceIcon size={32} class="carbon-icon" />
|
||||
{:else if index === 1}
|
||||
<ChartClusterBar32 class="carbon-icon" />
|
||||
<ChartClusterBarIcon size={32} class="carbon-icon" />
|
||||
{:else if index === 2}
|
||||
<MachineLearningModel32 class="carbon-icon" />
|
||||
<MachineLearningModelIcon size={32} class="carbon-icon" />
|
||||
{/if}
|
||||
{area.title}
|
||||
</h3>
|
||||
@@ -1,11 +1,10 @@
|
||||
<script>
|
||||
import { stores, goto } from '@sapper/app';
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
import { appStore } from '$lib/utils/store/app';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
|
||||
import { appStore } from '../utils/store/app';
|
||||
import PrimaryButton from '../components/PrimaryButton/index.svelte';
|
||||
const { page } = stores();
|
||||
const src = './bg-404.png';
|
||||
$: console.log('route', $page);
|
||||
</script>
|
||||
|
||||
<div
|
||||
@@ -1,43 +0,0 @@
|
||||
<script context="module">
|
||||
export async function preload({ params }) {
|
||||
return { slug: params.slug };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import Backdrop from '../../components/Backdrop/index.svelte';
|
||||
import { Moon } from 'svelte-loading-spinners';
|
||||
import CourseLandingPage from '../../components/CourseLandingPage/index.svelte';
|
||||
import { profile } from '../../utils/store/user';
|
||||
import { setCourse, course } from '../../components/Course/store';
|
||||
import { lessons } from '../../components/Course/components/Lesson/store/lessons';
|
||||
import { fetchCourse } from '../../utils/services/courses';
|
||||
|
||||
export let slug;
|
||||
|
||||
let courseData = {};
|
||||
let loading = false;
|
||||
|
||||
async function triggerSetCourse(_profile) {
|
||||
loading = true;
|
||||
const { data } = await fetchCourse(undefined, slug);
|
||||
setCourse(data);
|
||||
loading = false;
|
||||
}
|
||||
|
||||
function setCourseData(course, lessons) {
|
||||
courseData = { ...course, lessons };
|
||||
console.log('courseData', courseData);
|
||||
}
|
||||
|
||||
$: triggerSetCourse($profile);
|
||||
$: setCourseData($course, $lessons);
|
||||
</script>
|
||||
|
||||
{#if loading}
|
||||
<Backdrop>
|
||||
<Moon size="60" color="#1d4ed8" unit="px" duration="1s" />
|
||||
</Backdrop>
|
||||
{:else}
|
||||
<CourseLandingPage {courseData} />
|
||||
{/if}
|
||||
@@ -0,0 +1,5 @@
|
||||
export const load = ({ params = { slug: '' } }) => {
|
||||
return {
|
||||
slug: params.slug,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,37 @@
|
||||
<script>
|
||||
import Backdrop from '$lib/components/Backdrop/index.svelte';
|
||||
import { Moon } from 'svelte-loading-spinners';
|
||||
import CourseLandingPage from '$lib/components/CourseLandingPage/index.svelte';
|
||||
import { profile } from '$lib/utils/store/user';
|
||||
import { setCourse, course } from '$lib/components/Course/store';
|
||||
import { lessons } from '$lib/components/Course/components/Lesson/store/lessons';
|
||||
import { fetchCourse } from '$lib/utils/services/courses';
|
||||
|
||||
export let data;
|
||||
|
||||
let courseData = {};
|
||||
let loading = false;
|
||||
|
||||
async function triggerSetCourse(_profile) {
|
||||
loading = true;
|
||||
const { data: _data } = await fetchCourse(undefined, data.slug);
|
||||
setCourse(_data);
|
||||
loading = false;
|
||||
}
|
||||
|
||||
function setCourseData(course, lessons) {
|
||||
courseData = { ...course, lessons };
|
||||
console.log('courseData', courseData);
|
||||
}
|
||||
|
||||
$: triggerSetCourse($profile);
|
||||
$: setCourseData($course, $lessons);
|
||||
</script>
|
||||
|
||||
{#if loading}
|
||||
<Backdrop>
|
||||
<Moon size="60" color="#1d4ed8" unit="px" duration="1s" />
|
||||
</Backdrop>
|
||||
{:else}
|
||||
<CourseLandingPage {courseData} />
|
||||
{/if}
|
||||
@@ -0,0 +1,5 @@
|
||||
export const load = ({ params = { id: '' } }) => {
|
||||
return {
|
||||
courseId: params.id,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,26 @@
|
||||
<script>
|
||||
import Overview from '$lib/components/Course/index.svelte';
|
||||
import CourseContainer from '$lib/components/CourseContainer/index.svelte';
|
||||
import { setCourse } from '$lib/components/Course/store';
|
||||
import { fetchCourse } from '$lib/utils/services/courses';
|
||||
|
||||
export let data;
|
||||
const { courseId } = data;
|
||||
|
||||
let prevCourseId = '';
|
||||
|
||||
async function onCourseIdChange(courseId = '') {
|
||||
if (!courseId || prevCourseId === courseId) return;
|
||||
|
||||
const { data: _data } = await fetchCourse(courseId);
|
||||
|
||||
setCourse(_data);
|
||||
prevCourseId = courseId;
|
||||
}
|
||||
|
||||
$: onCourseIdChange(courseId);
|
||||
</script>
|
||||
|
||||
<CourseContainer>
|
||||
<Overview />
|
||||
</CourseContainer>
|
||||
@@ -0,0 +1,5 @@
|
||||
export const load = ({ params = { id: '' } }) => {
|
||||
return {
|
||||
courseId: params.id,
|
||||
};
|
||||
};
|
||||
+23
-29
@@ -1,28 +1,22 @@
|
||||
<script context="module">
|
||||
export async function preload({ params }) {
|
||||
return { courseId: params.id };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import AudioConsole32 from 'carbon-icons-svelte/lib/AudioConsole32';
|
||||
import CourseContainer from '../../../components/CourseContainer/index.svelte';
|
||||
import PageNav from '../../../components/PageNav/index.svelte';
|
||||
import PageBody from '../../../components/PageBody/index.svelte';
|
||||
import Box from '../../../components/Box/index.svelte';
|
||||
import { course, group, setCourse } from '../../../components/Course/store';
|
||||
import { getLectureNo } from '../../../components/Course/function';
|
||||
import { fetchCourse } from '../../../utils/services/courses';
|
||||
import { lessons } from '../../../components/Course/components/Lesson/store/lessons';
|
||||
import { ROLE } from '../../../utils/constants/roles';
|
||||
import { takeAttendance } from '../../../utils/services/attendance';
|
||||
import { snackbarStore } from '../../../components/Snackbar/store';
|
||||
import { SNACKBAR_SEVERITY } from '../../../components/Snackbar/constants';
|
||||
import { attendance } from '../../../utils/store/attendance';
|
||||
import { profile } from '../../../utils/store/user';
|
||||
import AudioConsoleIcon from 'carbon-icons-svelte/lib/AudioConsole.svelte';
|
||||
import CourseContainer from '$lib/components/CourseContainer/index.svelte';
|
||||
import PageNav from '$lib/components/PageNav/index.svelte';
|
||||
import PageBody from '$lib/components/PageBody/index.svelte';
|
||||
import Box from '$lib/components/Box/index.svelte';
|
||||
import { course, group, setCourse } from '$lib/components/Course/store';
|
||||
import { getLectureNo } from '$lib/components/Course/function';
|
||||
import { fetchCourse } from '$lib/utils/services/courses';
|
||||
import { lessons } from '$lib/components/Course/components/Lesson/store/lessons';
|
||||
import { ROLE } from '$lib/utils/constants/roles';
|
||||
import { takeAttendance } from '$lib/utils/services/attendance';
|
||||
import { snackbarStore } from '$lib/components/Snackbar/store';
|
||||
import { SNACKBAR_SEVERITY } from '$lib/components/Snackbar/constants';
|
||||
import { attendance } from '$lib/utils/store/attendance';
|
||||
import { profile } from '$lib/utils/store/user';
|
||||
|
||||
export let courseId;
|
||||
export let data;
|
||||
|
||||
let borderBottomGrey = 'border-r-0 border-b border-l-0 border-gray-300';
|
||||
let students = [];
|
||||
@@ -72,15 +66,15 @@
|
||||
}
|
||||
*/
|
||||
|
||||
const data = {
|
||||
const _data = {
|
||||
id: attendanceItem.id,
|
||||
student_id: student.id,
|
||||
is_present: e.target.checked,
|
||||
lesson_id: lesson.id,
|
||||
course_id: courseId,
|
||||
course_id: data.courseId,
|
||||
};
|
||||
|
||||
takeAttendance(data).then((res) => {
|
||||
takeAttendance(_data).then((res) => {
|
||||
if (res.error) {
|
||||
console.error(`res.error`, res.error);
|
||||
$snackbarStore.open = true;
|
||||
@@ -115,9 +109,9 @@
|
||||
return;
|
||||
}
|
||||
|
||||
const { data } = await fetchCourse(courseId);
|
||||
setCourse(data);
|
||||
setAttendance(data);
|
||||
const { data: _data } = await fetchCourse(data.courseId);
|
||||
setCourse(_data);
|
||||
setAttendance(_data);
|
||||
});
|
||||
|
||||
$: students = isStudent
|
||||
@@ -181,7 +175,7 @@
|
||||
</div>
|
||||
{:else}
|
||||
<Box>
|
||||
<AudioConsole32 class="carbon-icon w-80" />
|
||||
<AudioConsoleIcon size={32} class="carbon-icon w-80" />
|
||||
<h3 class="text-3xl text-gray-500 dark:text-white">
|
||||
No Student Added
|
||||
</h3>
|
||||
@@ -0,0 +1,5 @@
|
||||
export const load = ({ params = { id: '' } }) => {
|
||||
return {
|
||||
courseId: params.id,
|
||||
};
|
||||
};
|
||||
+11
-19
@@ -1,26 +1,18 @@
|
||||
<script context="module">
|
||||
import { fetchCourse } from '../../../utils/services/courses';
|
||||
|
||||
export async function preload({ params = { id: '' } }) {
|
||||
return { courseId: params.id };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import CourseContainer from '../../../components/CourseContainer/index.svelte';
|
||||
import PageNav from '../../../components/PageNav/index.svelte';
|
||||
import PageBody from '../../../components/PageBody/index.svelte';
|
||||
import RoleBasedSecurity from '../../../components/RoleBasedSecurity/index.svelte';
|
||||
import { setCourse, course } from '../../../components/Course/store';
|
||||
import IssueCertificateModal from '../../../components/Course/components/Ceritficate/IssueCertificateModal.svelte';
|
||||
// import DeleteConfirmation from '../../../components/Course/components/People/DeleteConfirmation.svelte';
|
||||
import Design from '../../../components/Course/components/Ceritficate/Design.svelte';
|
||||
// import Reports from '../../../components/Course/components/Ceritficate/Reports.svelte';
|
||||
// import { issueCertificateModal } from '../../../components/Course/components/Ceritficate/store';
|
||||
import CourseContainer from '$lib/components/CourseContainer/index.svelte';
|
||||
import PageNav from '$lib/components/PageNav/index.svelte';
|
||||
import PageBody from '$lib/components/PageBody/index.svelte';
|
||||
import RoleBasedSecurity from '$lib/components/RoleBasedSecurity/index.svelte';
|
||||
import { setCourse, course } from '$lib/components/Course/store';
|
||||
import IssueCertificateModal from '$lib/components/Course/components/Ceritficate/IssueCertificateModal.svelte';
|
||||
// import DeleteConfirmation from '$lib/components/Course/components/People/DeleteConfirmation.svelte';
|
||||
import Design from '$lib/components/Course/components/Ceritficate/Design.svelte';
|
||||
// import Reports from '$lib/components/Course/components/Ceritficate/Reports.svelte';
|
||||
// import { issueCertificateModal } from '$lib/components/Course/components/Ceritficate/store';
|
||||
// import { Tabs, Tab } from 'carbon-components-svelte';
|
||||
// import TabContent from 'carbon-components-svelte/src/Tabs/TabContent.svelte';
|
||||
import StudentCertificate from '../../../components/Course/components/Ceritficate/StudentCertificate/Index.svelte';
|
||||
import StudentCertificate from '$lib/components/Course/components/Ceritficate/StudentCertificate/Index.svelte';
|
||||
export let courseId: string = '';
|
||||
let isStudent = false;
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
<script context="module">
|
||||
export async function preload({ params }, session) {
|
||||
return { courseId: params.id };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import Overview from '../../../components/Course/index.svelte';
|
||||
import CourseContainer from '../../../components/CourseContainer/index.svelte';
|
||||
import { setCourse } from '../../../components/Course/store';
|
||||
import { fetchCourse } from '../../../utils/services/courses';
|
||||
|
||||
export let courseId;
|
||||
|
||||
let prevCourseId;
|
||||
|
||||
async function onCourseIdChange(courseId) {
|
||||
if (!courseId || prevCourseId === courseId) return;
|
||||
|
||||
const { data } = await fetchCourse(courseId);
|
||||
|
||||
setCourse(data);
|
||||
prevCourseId = courseId;
|
||||
}
|
||||
|
||||
$: onCourseIdChange(courseId);
|
||||
</script>
|
||||
|
||||
<CourseContainer>
|
||||
<Overview />
|
||||
</CourseContainer>
|
||||
@@ -0,0 +1,5 @@
|
||||
export const load = ({ params = { id: '' } }) => {
|
||||
return {
|
||||
courseId: params.id,
|
||||
};
|
||||
};
|
||||
+12
-17
@@ -1,30 +1,25 @@
|
||||
<script context="module">
|
||||
export async function preload({ params }) {
|
||||
return { courseId: params.id };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { fly } from 'svelte/transition';
|
||||
import CourseLandingPage from '../../../components/CourseLandingPage/index.svelte';
|
||||
import Editor from '../../../components/CourseLandingPage/components/Editor/index.svelte';
|
||||
import { isMobile } from '../../../utils/store/useMobile';
|
||||
import { profile } from '../../../utils/store/user';
|
||||
import { setCourse, course } from '../../../components/Course/store';
|
||||
import { lessons } from '../../../components/Course/components/Lesson/store/lessons';
|
||||
import { fetchCourse } from '../../../utils/services/courses';
|
||||
import CourseLandingPage from '$lib/components/CourseLandingPage/index.svelte';
|
||||
import Editor from '$lib/components/CourseLandingPage/components/Editor/index.svelte';
|
||||
import { isMobile } from '$lib/utils/store/useMobile';
|
||||
import { profile } from '$lib/utils/store/user';
|
||||
import { setCourse, course } from '$lib/components/Course/store';
|
||||
import { lessons } from '$lib/components/Course/components/Lesson/store/lessons';
|
||||
import { fetchCourse } from '$lib/utils/services/courses';
|
||||
|
||||
export let courseId;
|
||||
export let data;
|
||||
const { courseId } = data;
|
||||
|
||||
let courseData = {};
|
||||
|
||||
async function triggerSetCourse(_profile) {
|
||||
if ($course.id) return;
|
||||
const { data } = await fetchCourse(courseId);
|
||||
setCourse(data);
|
||||
const { data: _data } = await fetchCourse(courseId);
|
||||
setCourse(_data);
|
||||
}
|
||||
|
||||
function setCourseData(course, lessons) {
|
||||
function setCourseData(course = {}, lessons) {
|
||||
courseData = { ...course, lessons };
|
||||
}
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
export const load = ({ params = { id: '' } }) => {
|
||||
return {
|
||||
courseId: params.id,
|
||||
};
|
||||
};
|
||||
+33
-46
@@ -1,52 +1,39 @@
|
||||
<script context="module">
|
||||
export async function preload({ params }) {
|
||||
return { courseId: params.id };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import { stores } from '@sapper/app';
|
||||
import { page } from '$app/stores';
|
||||
import { dndzone } from 'svelte-dnd-action';
|
||||
import Time24 from 'carbon-icons-svelte/lib/Time24';
|
||||
import Edit24 from 'carbon-icons-svelte/lib/Edit24';
|
||||
import Save24 from 'carbon-icons-svelte/lib/Save24';
|
||||
import Phone24 from 'carbon-icons-svelte/lib/Phone24';
|
||||
import Delete24 from 'carbon-icons-svelte/lib/Delete24';
|
||||
import CheckmarkFilled24 from 'carbon-icons-svelte/lib/CheckmarkFilled24';
|
||||
import PageNav from '../../../../components/PageNav/index.svelte';
|
||||
import RoleBasedSecurity from '../../../../components/RoleBasedSecurity/index.svelte';
|
||||
import Box from '../../../../components/Box/index.svelte';
|
||||
import PageBody from '../../../../components/PageBody/index.svelte';
|
||||
import PrimaryButton from '../../../../components/PrimaryButton/index.svelte';
|
||||
import TextField from '../../../../components/Form/TextField.svelte';
|
||||
import IconButton from '../../../../components/IconButton/index.svelte';
|
||||
import Select from '../../../../components/Form/Select.svelte';
|
||||
import {
|
||||
fetchCourse,
|
||||
updateLesson,
|
||||
} from '../../../../utils/services/courses';
|
||||
import CourseContainer from '../../../../components/CourseContainer/index.svelte';
|
||||
import { profile } from '../../../../utils/store/user';
|
||||
import TimeIcon from 'carbon-icons-svelte/lib/Time.svelte';
|
||||
import EditIcon from 'carbon-icons-svelte/lib/Edit.svelte';
|
||||
import SaveIcon from 'carbon-icons-svelte/lib/Save.svelte';
|
||||
import PhoneIcon from 'carbon-icons-svelte/lib/Phone.svelte';
|
||||
import TrashCanIcon from 'carbon-icons-svelte/lib/TrashCan.svelte';
|
||||
import CheckmarkFilled24 from 'carbon-icons-svelte/lib/CheckmarkFilled.svelte';
|
||||
import PageNav from '$lib/components/PageNav/index.svelte';
|
||||
import RoleBasedSecurity from '$lib/components/RoleBasedSecurity/index.svelte';
|
||||
import Box from '$lib/components/Box/index.svelte';
|
||||
import PageBody from '$lib/components/PageBody/index.svelte';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import TextField from '$lib/components/Form/TextField.svelte';
|
||||
import IconButton from '$lib/components/IconButton/index.svelte';
|
||||
import Select from '$lib/components/Form/Select.svelte';
|
||||
import { fetchCourse, updateLesson } from '$lib/utils/services/courses';
|
||||
import CourseContainer from '$lib/components/CourseContainer/index.svelte';
|
||||
import { profile } from '$lib/utils/store/user';
|
||||
import {
|
||||
lessons,
|
||||
handleAddLesson,
|
||||
handleSaveLesson,
|
||||
handleDelete,
|
||||
} from '../../../../components/Course/components/Lesson/store/lessons';
|
||||
import {
|
||||
course,
|
||||
setCourse,
|
||||
group,
|
||||
} from '../../../../components/Course/store';
|
||||
} from '$lib/components/Course/components/Lesson/store/lessons';
|
||||
import { course, setCourse, group } from '$lib/components/Course/store';
|
||||
|
||||
export let courseId;
|
||||
export let data;
|
||||
const { courseId } = data;
|
||||
|
||||
let lessonEditing;
|
||||
let ref;
|
||||
let isStudent = true;
|
||||
|
||||
const { page } = stores();
|
||||
const flipDurationMs = 300;
|
||||
|
||||
function formatDate(date) {
|
||||
@@ -106,8 +93,8 @@
|
||||
|
||||
onMount(async () => {
|
||||
if ($course.id) return;
|
||||
const { data } = await fetchCourse(courseId);
|
||||
setCourse(data);
|
||||
const { data: _data } = await fetchCourse(courseId);
|
||||
setCourse(_data);
|
||||
});
|
||||
|
||||
$: {
|
||||
@@ -124,7 +111,7 @@
|
||||
<CourseContainer bind:isStudent>
|
||||
<PageNav title="Lessons">
|
||||
<div slot="widget">
|
||||
<RoleBasedSecurity allowedRoles="[1,2]">
|
||||
<RoleBasedSecurity allowedRoles={[1, 2]}>
|
||||
<PrimaryButton
|
||||
label="Add"
|
||||
onClick={addLesson}
|
||||
@@ -177,7 +164,7 @@
|
||||
</IconButton>
|
||||
</div>
|
||||
|
||||
<RoleBasedSecurity allowedRoles="[1,2]">
|
||||
<RoleBasedSecurity allowedRoles={[1, 2]}>
|
||||
<!-- Edit/Save -->
|
||||
<div class="absolute -top-2 -right-2">
|
||||
{#if lessonEditing === lesson.id}
|
||||
@@ -187,11 +174,11 @@
|
||||
handleSaveLesson(lesson, $course.id);
|
||||
}}
|
||||
>
|
||||
<Save24 class="carbon-icon" />
|
||||
<SaveIcon size={24} class="carbon-icon" />
|
||||
</IconButton>
|
||||
{:else}
|
||||
<IconButton onClick={() => (lessonEditing = lesson.id)}>
|
||||
<Edit24 class="carbon-icon" />
|
||||
<EditIcon size={24} class="carbon-icon" />
|
||||
</IconButton>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -209,7 +196,7 @@
|
||||
<h3 class="dark:text-white text-2xl m-0 flex items-center">
|
||||
<a
|
||||
href={isStudent && !lesson.is_complete
|
||||
? $page.path
|
||||
? $page.url.pathname
|
||||
: '/courses/' + $course.id + '/lessons/' + lesson.id}
|
||||
class="dark:text-white hover:underline text-black {isStudent &&
|
||||
!lesson.is_complete
|
||||
@@ -264,7 +251,7 @@
|
||||
on:input={(e) => (lesson.lesson_at = e.target.value)}
|
||||
/>
|
||||
{:else}
|
||||
<Time24 class="carbon-icon" />
|
||||
<TimeIcon size={24} class="carbon-icon" />
|
||||
<p class="dark:text-white text-md ml-2">
|
||||
{new Date(lesson.lesson_at).toDateString()}
|
||||
</p>
|
||||
@@ -280,7 +267,7 @@
|
||||
placeholder="https://meet.google.com/mga-dsjs-fmb"
|
||||
/>
|
||||
{:else}
|
||||
<Phone24 class="carbon-icon" />
|
||||
<PhoneIcon size={24} class="carbon-icon" />
|
||||
<a
|
||||
class="text-md ml-2"
|
||||
href={lesson.call_url || '#'}
|
||||
@@ -293,10 +280,10 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<RoleBasedSecurity allowedRoles="[1,2]">
|
||||
<RoleBasedSecurity allowedRoles={[1, 2]}>
|
||||
<div class="absolute bottom-2 right-0">
|
||||
<IconButton onClick={handleDelete(lesson.id)}>
|
||||
<Delete24 class="carbon-icon" />
|
||||
<TrashCanIcon size={24} class="carbon-icon" />
|
||||
</IconButton>
|
||||
</div>
|
||||
</RoleBasedSecurity>
|
||||
@@ -0,0 +1,21 @@
|
||||
export const load = ({ params = { id: '' } }) => {
|
||||
const { id: courseId, lessonParams = [] } = params;
|
||||
console.log(lessonParams, lessonParams);
|
||||
// let lessonId = '';
|
||||
// let exerciseRouteName = '';
|
||||
// let exerciseId = '';
|
||||
// if (typeof lessonParams === 'string') {
|
||||
// lessonId
|
||||
// }
|
||||
const splitparams = lessonParams.split('/');
|
||||
console.log('splitparams', splitparams);
|
||||
const [lessonId, exerciseRouteName, exerciseId] = splitparams;
|
||||
|
||||
return {
|
||||
courseId,
|
||||
lessonId,
|
||||
exerciseRouteName,
|
||||
exerciseId,
|
||||
isMaterialsTabActive: !exerciseRouteName,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,117 @@
|
||||
<script>
|
||||
import { page } from '$app/stores';
|
||||
import CourseContainer from '$lib/components/CourseContainer/index.svelte';
|
||||
import { fetchCourse, fetchLesson } from '$lib/utils/services/courses';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import RoleBasedSecurity from '$lib/components/RoleBasedSecurity/index.svelte';
|
||||
import PageNav from '$lib/components/PageNav/index.svelte';
|
||||
import PageBody from '$lib/components/PageBody/index.svelte';
|
||||
import Materials from '$lib/components/Course/components/Lesson/Materials/index.svelte';
|
||||
import Exercises from '$lib/components/Course/components/Lesson/Exercises/index.svelte';
|
||||
import MODES from '$lib/utils/constants/mode.js';
|
||||
import { setCourse, course } from '$lib/components/Course/store';
|
||||
import { lesson } from '$lib/components/Course/components/Lesson/store/lessons';
|
||||
|
||||
export let data;
|
||||
|
||||
let path = '';
|
||||
let mode = MODES.view;
|
||||
let prevMode = '';
|
||||
let prevLessonId = '';
|
||||
let isFetching = false;
|
||||
|
||||
async function fetchReqData(lessonId = '') {
|
||||
isFetching = true;
|
||||
|
||||
let lessonData;
|
||||
if (!$course.id) {
|
||||
const { data: _data } = await fetchCourse(data.courseId);
|
||||
|
||||
lessonData = _data.lessons.find(
|
||||
(lesson = { id: '' }) => lesson.id === lessonId
|
||||
);
|
||||
setCourse(_data);
|
||||
} else if (prevLessonId !== lessonId) {
|
||||
const lesson = await fetchLesson(lessonId);
|
||||
lessonData = lesson.data;
|
||||
}
|
||||
|
||||
prevLessonId = lessonId;
|
||||
|
||||
const totalExercises =
|
||||
lessonData?.totalExercises?.[0] && lessonData.totalExercises[0].count;
|
||||
setLesson(lessonData, totalExercises || 0);
|
||||
isFetching = false;
|
||||
}
|
||||
|
||||
function setLesson(lessonData, totalExercises) {
|
||||
if (!lessonData) return;
|
||||
|
||||
lesson.update((l) => ({
|
||||
...l,
|
||||
id: data.lessonId,
|
||||
totalExercises,
|
||||
materials: lessonData,
|
||||
}));
|
||||
}
|
||||
|
||||
$: path = $page.url.pathname.replace(/\/exercises[\/ 0-9 a-z -]*/, '');
|
||||
|
||||
$: if (data.courseId) {
|
||||
mode = MODES.view;
|
||||
fetchReqData(data.lessonId);
|
||||
}
|
||||
|
||||
$: console.log('data changed', data);
|
||||
</script>
|
||||
|
||||
<CourseContainer
|
||||
{isFetching}
|
||||
{path}
|
||||
isExercisePage={!data.isMaterialsTabActive && data.exerciseId}
|
||||
>
|
||||
<PageNav
|
||||
navItems={[
|
||||
{
|
||||
label: 'Materials',
|
||||
isActive: data.isMaterialsTabActive,
|
||||
href: path,
|
||||
},
|
||||
{
|
||||
label: 'Exercises',
|
||||
badgeValue: $lesson.totalExercises,
|
||||
isActive: !data.isMaterialsTabActive,
|
||||
href: `${path}/exercises`,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<svelte:fragment slot="widget">
|
||||
<RoleBasedSecurity allowedRoles={[1, 2]}>
|
||||
{#if data.isMaterialsTabActive}
|
||||
<div class="flex items-center">
|
||||
<PrimaryButton
|
||||
className="mr-2"
|
||||
label={mode === MODES.edit ? 'Save' : 'Edit'}
|
||||
onClick={() => {
|
||||
prevMode = mode;
|
||||
mode = mode === MODES.edit ? MODES.view : MODES.edit;
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</RoleBasedSecurity>
|
||||
</svelte:fragment>
|
||||
</PageNav>
|
||||
|
||||
{#if !data.isMaterialsTabActive}
|
||||
<Exercises
|
||||
lessonId={data.lessonId}
|
||||
exerciseId={data.exerciseId}
|
||||
path={`${path}/exercises`}
|
||||
/>
|
||||
{:else if !!data.lessonId}
|
||||
<PageBody>
|
||||
<Materials lessonId={data.lessonId} {mode} {prevMode} />
|
||||
</PageBody>
|
||||
{/if}
|
||||
</CourseContainer>
|
||||
@@ -1,136 +0,0 @@
|
||||
<script context="module">
|
||||
import {
|
||||
fetchCourse,
|
||||
fetchLesson,
|
||||
} from '../../../../../utils/services/courses';
|
||||
|
||||
export async function preload({ params }) {
|
||||
const { id: courseId, lessonParams = [] } = params;
|
||||
const [lessonId, exerciseRouteName, exerciseId] = lessonParams;
|
||||
|
||||
return {
|
||||
courseId,
|
||||
lessonId,
|
||||
exerciseRouteName,
|
||||
exerciseId,
|
||||
isMaterialsTabActive: !exerciseRouteName,
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { stores } from '@sapper/app';
|
||||
import CourseContainer from '../../../../../components/CourseContainer/index.svelte';
|
||||
|
||||
import PrimaryButton from '../../../../../components/PrimaryButton/index.svelte';
|
||||
import RoleBasedSecurity from '../../../../../components/RoleBasedSecurity/index.svelte';
|
||||
import PageNav from '../../../../../components/PageNav/index.svelte';
|
||||
import PageBody from '../../../../../components/PageBody/index.svelte';
|
||||
import Materials from '../../../../../components/Course/components/Lesson/Materials/index.svelte';
|
||||
import Exercises from '../../../../../components/Course/components/Lesson/Exercises/index.svelte';
|
||||
import MODES from '../../../../../utils/constants/mode.js';
|
||||
import { setCourse, course } from '../../../../../components/Course/store';
|
||||
import { lesson } from '../../../../../components/Course/components/Lesson/store/lessons';
|
||||
|
||||
export let courseId;
|
||||
export let lessonId;
|
||||
export let exerciseId;
|
||||
export let isMaterialsTabActive;
|
||||
|
||||
let path;
|
||||
let mode = MODES.view;
|
||||
let prevMode;
|
||||
let prevLessonId;
|
||||
let isFetching = false;
|
||||
|
||||
const { page } = stores();
|
||||
|
||||
async function fetchReqData(lessonId) {
|
||||
isFetching = true;
|
||||
|
||||
let lessonData;
|
||||
if (!$course.id) {
|
||||
const { data } = await fetchCourse(courseId);
|
||||
|
||||
lessonData = data.lessons.find((lesson) => lesson.id === lessonId);
|
||||
setCourse(data);
|
||||
} else if (prevLessonId !== lessonId) {
|
||||
const lesson = await fetchLesson(lessonId);
|
||||
lessonData = lesson.data;
|
||||
}
|
||||
|
||||
prevLessonId = lessonId;
|
||||
|
||||
const totalExercises =
|
||||
lessonData.totalExercises[0] && lessonData.totalExercises[0].count;
|
||||
setLesson(lessonData, totalExercises);
|
||||
isFetching = false;
|
||||
}
|
||||
|
||||
function setLesson(lessonData, totalExercises) {
|
||||
if (!lessonData) return;
|
||||
|
||||
lesson.update((l) => ({
|
||||
...l,
|
||||
id: lessonId,
|
||||
totalExercises,
|
||||
materials: lessonData,
|
||||
}));
|
||||
}
|
||||
|
||||
$: path = $page.path.replace(/\/exercises[\/ 0-9 a-z -]*/, '');
|
||||
|
||||
$: {
|
||||
if (courseId) {
|
||||
mode = MODES.view;
|
||||
fetchReqData(lessonId);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<CourseContainer
|
||||
{isFetching}
|
||||
{path}
|
||||
isExercisePage={!isMaterialsTabActive && exerciseId}
|
||||
>
|
||||
<PageNav
|
||||
navItems={[
|
||||
{
|
||||
label: 'Materials',
|
||||
isActive: isMaterialsTabActive,
|
||||
href: path,
|
||||
},
|
||||
{
|
||||
label: 'Exercises',
|
||||
badgeValue: $lesson.totalExercises,
|
||||
isActive: !isMaterialsTabActive,
|
||||
href: `${path}/exercises`,
|
||||
},
|
||||
]}
|
||||
>
|
||||
<svelte:fragment slot="widget">
|
||||
<RoleBasedSecurity allowedRoles="[1,2]">
|
||||
{#if isMaterialsTabActive}
|
||||
<div class="flex items-center">
|
||||
<PrimaryButton
|
||||
className="mr-2"
|
||||
label={mode === MODES.edit ? 'Save' : 'Edit'}
|
||||
onClick={() => {
|
||||
prevMode = mode;
|
||||
mode = mode === MODES.edit ? MODES.view : MODES.edit;
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
{/if}
|
||||
</RoleBasedSecurity>
|
||||
</svelte:fragment>
|
||||
</PageNav>
|
||||
|
||||
{#if !isMaterialsTabActive}
|
||||
<Exercises {lessonId} {exerciseId} path={`${path}/exercises`} />
|
||||
{:else if !!lessonId}
|
||||
<PageBody>
|
||||
<Materials {lessonId} {mode} {prevMode} />
|
||||
</PageBody>
|
||||
{/if}
|
||||
</CourseContainer>
|
||||
@@ -0,0 +1,5 @@
|
||||
export const load = ({ params = { id: '' } }) => {
|
||||
return {
|
||||
courseId: params.id,
|
||||
};
|
||||
};
|
||||
@@ -1,28 +1,23 @@
|
||||
<script context="module">
|
||||
export async function preload({ params }) {
|
||||
return { courseId: params.id };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import AudioConsole32 from 'carbon-icons-svelte/lib/AudioConsole32';
|
||||
import CourseContainer from '../../../components/CourseContainer/index.svelte';
|
||||
import PageNav from '../../../components/PageNav/index.svelte';
|
||||
import PageBody from '../../../components/PageBody/index.svelte';
|
||||
import Box from '../../../components/Box/index.svelte';
|
||||
import { ROLE } from '../../../utils/constants/roles';
|
||||
import { setCourse, course, group } from '../../../components/Course/store';
|
||||
import { lessons } from '../../../components/Course/components/Lesson/store/lessons';
|
||||
import AudioConsoleIcon from 'carbon-icons-svelte/lib/AudioConsole.svelte';
|
||||
import CourseContainer from '$lib/components/CourseContainer/index.svelte';
|
||||
import PageNav from '$lib/components/PageNav/index.svelte';
|
||||
import PageBody from '$lib/components/PageBody/index.svelte';
|
||||
import Box from '$lib/components/Box/index.svelte';
|
||||
import { ROLE } from '$lib/utils/constants/roles';
|
||||
import { setCourse, course, group } from '$lib/components/Course/store';
|
||||
import { lessons } from '$lib/components/Course/components/Lesson/store/lessons';
|
||||
import {
|
||||
fetchCourse,
|
||||
fetchExercisesByMarks,
|
||||
} from '../../../utils/services/courses';
|
||||
import { getLectureNo } from '../../../components/Course/function';
|
||||
import { fetchMarks } from '../../../utils/services/marks';
|
||||
import { profile } from '../../../utils/store/user';
|
||||
} from '$lib/utils/services/courses';
|
||||
import { getLectureNo } from '$lib/components/Course/function';
|
||||
import { fetchMarks } from '$lib/utils/services/marks';
|
||||
import { profile } from '$lib/utils/store/user';
|
||||
|
||||
export let courseId;
|
||||
export let data;
|
||||
const { courseId } = data;
|
||||
|
||||
let borderBottomGrey =
|
||||
'border-r-0 border-t-0 border-b border-l-0 border-gray-300';
|
||||
@@ -180,7 +175,7 @@
|
||||
</div>
|
||||
{:else}
|
||||
<Box>
|
||||
<AudioConsole32 class="carbon-icon w-80" />
|
||||
<AudioConsoleIcon size={32} class="carbon-icon w-80" />
|
||||
<h3 class="text-3xl text-gray-500 dark:text-white">
|
||||
No Student Added
|
||||
</h3>
|
||||
@@ -0,0 +1,5 @@
|
||||
export const load = ({ params = { id: '' } }) => {
|
||||
return {
|
||||
courseId: params.id,
|
||||
};
|
||||
};
|
||||
+29
-35
@@ -1,46 +1,40 @@
|
||||
<script context="module">
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import copy from 'copy-to-clipboard';
|
||||
import CourseContainer from '$lib/components/CourseContainer/index.svelte';
|
||||
import {
|
||||
fetchCourse,
|
||||
deleteGroupMember,
|
||||
updatedGroupMember,
|
||||
} from '../../../utils/services/courses';
|
||||
|
||||
export async function preload({ params }) {
|
||||
return { courseId: params.id };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import copy from 'copy-to-clipboard';
|
||||
import CourseContainer from '../../../components/CourseContainer/index.svelte';
|
||||
import Edit16 from 'carbon-icons-svelte/lib/Edit16';
|
||||
import Copy16 from 'carbon-icons-svelte/lib/Copy16';
|
||||
import Delete24 from 'carbon-icons-svelte/lib/Delete24';
|
||||
import Avatar from '../../../components/Avatar/index.svelte';
|
||||
import PageNav from '../../../components/PageNav/index.svelte';
|
||||
import PrimaryButton from '../../../components/PrimaryButton/index.svelte';
|
||||
import TextField from '../../../components/Form/TextField.svelte';
|
||||
import Select from '../../../components/Form/Select.svelte';
|
||||
import IconButton from '../../../components/IconButton/index.svelte';
|
||||
import PageBody from '../../../components/PageBody/index.svelte';
|
||||
import RoleBasedSecurity from '../../../components/RoleBasedSecurity/index.svelte';
|
||||
import { setCourse, course, group } from '../../../components/Course/store';
|
||||
import InviationModal from '../../../components/Course/components/People/InviationModal.svelte';
|
||||
import DeleteConfirmation from '../../../components/Course/components/People/DeleteConfirmation.svelte';
|
||||
} from '$lib/utils/services/courses';
|
||||
import EditIcon from 'carbon-icons-svelte/lib/Edit.svelte';
|
||||
import CopyIcon from 'carbon-icons-svelte/lib/Copy.svelte';
|
||||
import TrashCanIcon from 'carbon-icons-svelte/lib/TrashCan.svelte';
|
||||
import Avatar from '$lib/components/Avatar/index.svelte';
|
||||
import PageNav from '$lib/components/PageNav/index.svelte';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import TextField from '$lib/components/Form/TextField.svelte';
|
||||
import Select from '$lib/components/Form/Select.svelte';
|
||||
import IconButton from '$lib/components/IconButton/index.svelte';
|
||||
import PageBody from '$lib/components/PageBody/index.svelte';
|
||||
import RoleBasedSecurity from '$lib/components/RoleBasedSecurity/index.svelte';
|
||||
import { setCourse, course, group } from '$lib/components/Course/store';
|
||||
import InviationModal from '$lib/components/Course/components/People/InviationModal.svelte';
|
||||
import DeleteConfirmation from '$lib/components/Course/components/People/DeleteConfirmation.svelte';
|
||||
import {
|
||||
invitationModal,
|
||||
deleteMemberModal,
|
||||
} from '../../../components/Course/components/People/store';
|
||||
} from '$lib/components/Course/components/People/store';
|
||||
import type {
|
||||
Person,
|
||||
ProfileRole,
|
||||
} from '../../../components/Course/components/People/types';
|
||||
import { ROLE_LABEL, ROLES } from '../../../utils/constants/roles';
|
||||
import { profile } from '../../../utils/store/user';
|
||||
import { snackbarStore } from '../../../components/Snackbar/store';
|
||||
} from '$lib/components/Course/components/People/types';
|
||||
import { ROLE_LABEL, ROLES } from '$lib/utils/constants/roles';
|
||||
import { profile } from '$lib/utils/store/user';
|
||||
import { snackbarStore } from '$lib/components/Snackbar/store';
|
||||
|
||||
export let courseId: string = '';
|
||||
export let data;
|
||||
const { courseId } = data;
|
||||
|
||||
let people: Array<Person> = [];
|
||||
let borderBottomGrey = 'border-r-0 border-b border-l-0 border-gray-300';
|
||||
@@ -165,12 +159,12 @@
|
||||
<IconButton
|
||||
onClick={() => handleEditStudentIdMode(person.id)}
|
||||
>
|
||||
<Edit16 class="carbon-icon active" />
|
||||
<EditIcon size={16} class="carbon-icon active" />
|
||||
</IconButton>
|
||||
<IconButton
|
||||
onClick={() => copyToClipboard(person.assigned_student_id)}
|
||||
>
|
||||
<Copy16 class="carbon-icon active" />
|
||||
<CopyIcon size={16} class="carbon-icon active" />
|
||||
</IconButton>
|
||||
</div>
|
||||
{/if}
|
||||
@@ -221,7 +215,7 @@
|
||||
$deleteMemberModal.open = true;
|
||||
}}
|
||||
>
|
||||
<Delete24 class="carbon-icon" />
|
||||
<TrashCanIcon size={24} class="carbon-icon" />
|
||||
</IconButton>
|
||||
{/if}
|
||||
</div>
|
||||
@@ -1,35 +0,0 @@
|
||||
<script context="module">
|
||||
import { fetchCourse } from '../../../utils/services/courses';
|
||||
|
||||
export async function preload({ params }, session) {
|
||||
if (process.browser) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const {
|
||||
data,
|
||||
// error
|
||||
} = await fetchCourse(params.id, session);
|
||||
|
||||
return { courseData: data };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import CourseContainer from '../../../components/CourseContainer/index.svelte';
|
||||
import PageNav from '../../../components/PageNav/index.svelte';
|
||||
import PageBody from '../../../components/PageBody/index.svelte';
|
||||
import { setCourse } from '../../../components/Course/store';
|
||||
|
||||
export let courseData = {};
|
||||
|
||||
onMount(() => {
|
||||
setCourse(courseData);
|
||||
});
|
||||
</script>
|
||||
|
||||
<CourseContainer>
|
||||
<PageNav title="Scoreboard" />
|
||||
<PageBody />
|
||||
</CourseContainer>
|
||||
@@ -0,0 +1,5 @@
|
||||
export const load = ({ params = { id: '' } }) => {
|
||||
return {
|
||||
courseId: params.id,
|
||||
};
|
||||
};
|
||||
+31
-38
@@ -1,36 +1,32 @@
|
||||
<script context="module">
|
||||
export async function preload({ params }) {
|
||||
return { courseId: params.id };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import { flip } from 'svelte/animate';
|
||||
import { dndzone } from 'svelte-dnd-action';
|
||||
import { stores, goto } from '@sapper/app';
|
||||
import PageNav from '../../../components/PageNav/index.svelte';
|
||||
import RoleBasedSecurity from '../../../components/RoleBasedSecurity/index.svelte';
|
||||
import MarkExerciseModal from '../../../components/Course/components/Lesson/Exercise/MarkExerciseModal.svelte';
|
||||
import Chip from '../../../components/Chip/index.svelte';
|
||||
import PageBody from '../../../components/PageBody/index.svelte';
|
||||
import CourseContainer from '../../../components/CourseContainer/index.svelte';
|
||||
import { fetchCourse } from '../../../utils/services/courses';
|
||||
import { setCourse, course } from '../../../components/Course/store';
|
||||
import { goto } from '$app/navigation';
|
||||
import { page } from '$app/stores';
|
||||
import PageNav from '$lib/components/PageNav/index.svelte';
|
||||
import RoleBasedSecurity from '$lib/components/RoleBasedSecurity/index.svelte';
|
||||
import MarkExerciseModal from '$lib/components/Course/components/Lesson/Exercise/MarkExerciseModal.svelte';
|
||||
import Chip from '$lib/components/Chip/index.svelte';
|
||||
import PageBody from '$lib/components/PageBody/index.svelte';
|
||||
import CourseContainer from '$lib/components/CourseContainer/index.svelte';
|
||||
import { fetchCourse } from '$lib/utils/services/courses';
|
||||
import { setCourse, course } from '$lib/components/Course/store';
|
||||
import {
|
||||
fetchSubmissions,
|
||||
updateSubmission,
|
||||
updateQuestionAnswer,
|
||||
} from '../../../utils/services/submissions';
|
||||
import { formatAnswers } from '../../../components/Course/function';
|
||||
import { snackbarStore } from '../../../components/Snackbar/store';
|
||||
import { SNACKBAR_SEVERITY } from '../../../components/Snackbar/constants';
|
||||
import isSubmissionEarly from '../../../utils/functions/isSubmissionEarly';
|
||||
import formatDate from '../../../utils/functions/formatDate';
|
||||
} from '$lib/utils/services/submissions';
|
||||
import { formatAnswers } from '$lib/components/Course/function';
|
||||
import { snackbarStore } from '$lib/components/Snackbar/store';
|
||||
import { SNACKBAR_SEVERITY } from '$lib/components/Snackbar/constants';
|
||||
import isSubmissionEarly from '$lib/utils/functions/isSubmissionEarly';
|
||||
import formatDate from '$lib/utils/functions/formatDate';
|
||||
|
||||
const flipDurationMs = 300;
|
||||
|
||||
export let courseId;
|
||||
export let data;
|
||||
const { courseId } = data;
|
||||
|
||||
let sections = [
|
||||
{
|
||||
@@ -57,8 +53,6 @@
|
||||
|
||||
let openExercise = false;
|
||||
|
||||
const { page } = stores();
|
||||
|
||||
function handleItemFinalize(columnIdx, newItems) {
|
||||
let itemToWithNewStatus;
|
||||
|
||||
@@ -104,7 +98,7 @@
|
||||
}
|
||||
|
||||
function handleModalClose() {
|
||||
goto($page.path);
|
||||
goto($page.url.pathname);
|
||||
}
|
||||
|
||||
// Via dialog
|
||||
@@ -163,13 +157,10 @@
|
||||
return updateQuestionAnswer({ point }, { id: questionAnswer.id });
|
||||
});
|
||||
|
||||
updateSubmission(
|
||||
{
|
||||
id: submissionId,
|
||||
total: totalPoints,
|
||||
},
|
||||
{ returning: 'minimal' }
|
||||
).then((res) => console.log('Updated submission', res));
|
||||
updateSubmission({
|
||||
id: submissionId,
|
||||
total: totalPoints,
|
||||
}).then((res) => console.log('Updated submission', res));
|
||||
|
||||
$snackbarStore.open = true;
|
||||
$snackbarStore.message = `Saved successfully`;
|
||||
@@ -253,7 +244,7 @@
|
||||
});
|
||||
|
||||
$: {
|
||||
submissionId = $page.query.submissionId;
|
||||
submissionId = $page.url.query.submissionId;
|
||||
openExercise = !!submissionId && submissionIdData[submissionId];
|
||||
}
|
||||
</script>
|
||||
@@ -267,7 +258,7 @@
|
||||
{submissionId}
|
||||
/>
|
||||
|
||||
<RoleBasedSecurity allowedRoles="[1,2]">
|
||||
<RoleBasedSecurity allowedRoles={[1, 2]}>
|
||||
<CourseContainer>
|
||||
<PageNav title="Submitted Exercises" />
|
||||
|
||||
@@ -302,7 +293,7 @@
|
||||
<div
|
||||
class="flex items-center cursor-pointer text-black mb-2"
|
||||
on:click={() => {
|
||||
goto(`${$page.path}?submissionId=${item.id}`);
|
||||
goto(`${$page.url.pathname}?submissionId=${item.id}`);
|
||||
}}
|
||||
>
|
||||
<img
|
||||
@@ -316,14 +307,16 @@
|
||||
</div>
|
||||
<a
|
||||
class="text-blue-700 text-md font-bold"
|
||||
href="{$page.path}?submissionId={item.id}"
|
||||
href="{$page.url.pathname}?submissionId={item.id}"
|
||||
>
|
||||
{item.exercise.title}
|
||||
</a>
|
||||
<a
|
||||
class="flex items-center no-underline hover:underline text-black my-2"
|
||||
href="{$page.path.replace('submissions', 'lessons')}/{item
|
||||
.lesson.id}/exercises/{item.exercise.id}"
|
||||
href="{$page.url.pathname.replace(
|
||||
'submissions',
|
||||
'lessons'
|
||||
)}/{item.lesson.id}/exercises/{item.exercise.id}"
|
||||
>
|
||||
<p class="dark:text-white text-grey text-sm">
|
||||
#{item.lesson.title}
|
||||
@@ -1,35 +0,0 @@
|
||||
<script context="module">
|
||||
import { fetchCourse } from '../../../utils/services/courses';
|
||||
|
||||
export async function preload({ params }, session) {
|
||||
if (process.browser) {
|
||||
return {};
|
||||
}
|
||||
|
||||
const {
|
||||
data,
|
||||
// error
|
||||
} = await fetchCourse(params.id, session);
|
||||
|
||||
return { courseData: data };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import CourseContainer from '../../../components/CourseContainer/index.svelte';
|
||||
import PageNav from '../../../components/PageNav/index.svelte';
|
||||
import PageBody from '../../../components/PageBody/index.svelte';
|
||||
import { setCourse } from '../../../components/Course/store';
|
||||
|
||||
export let courseData = {};
|
||||
|
||||
onMount(() => {
|
||||
setCourse(courseData);
|
||||
});
|
||||
</script>
|
||||
|
||||
<CourseContainer>
|
||||
<PageNav title="Timetable" />
|
||||
<PageBody />
|
||||
</CourseContainer>
|
||||
@@ -1,19 +1,19 @@
|
||||
<script lang="ts">
|
||||
import { onMount } from 'svelte';
|
||||
import { InlineCalendar, Datepicker } from 'svelte-calendar';
|
||||
import CheckmarkFilled20 from 'carbon-icons-svelte/lib/CheckmarkFilled20';
|
||||
import CheckmarkFilledIcon from 'carbon-icons-svelte/lib/CheckmarkFilled.svelte';
|
||||
|
||||
import {
|
||||
formatUserUpcomingData,
|
||||
formatDate,
|
||||
} from '../utils/functions/routes/dashboard';
|
||||
import { user } from '../utils/store/user';
|
||||
import { fetchUserUpcomingData } from '../utils/services/dashboard';
|
||||
import { isMobile } from '../utils/store/useMobile';
|
||||
} from '$lib/utils/functions/routes/dashboard';
|
||||
import { user } from '$lib/utils/store/user';
|
||||
import { fetchUserUpcomingData } from '$lib/utils/services/dashboard';
|
||||
import { isMobile } from '$lib/utils/store/useMobile';
|
||||
import type {
|
||||
UserLessonDataType,
|
||||
LessonsByMonthIndexType,
|
||||
} from '../utils/types';
|
||||
} from '$lib/utils/types';
|
||||
|
||||
const theme = {
|
||||
calendar: {
|
||||
@@ -130,7 +130,6 @@
|
||||
|
||||
// Every time the date changes
|
||||
$: selectedDateLessonData = getDataOfSelectedDate($store?.selected);
|
||||
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
@@ -183,7 +182,7 @@
|
||||
{lessonData.lesson_title}
|
||||
{#if lessonData.is_complete}
|
||||
<span class="ml-2 success">
|
||||
<CheckmarkFilled20 class="carbon-icon" />
|
||||
<CheckmarkFilledIcon size={20} class="carbon-icon" />
|
||||
</span>
|
||||
{:else}
|
||||
<span class="text-md ml-2">🔒</span>
|
||||
@@ -1,24 +1,16 @@
|
||||
<script context="module">
|
||||
export function preload(page, { config }) {
|
||||
return { config };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { goto } from '@sapper/app';
|
||||
import TextField from '../components/Form/TextField.svelte';
|
||||
import PrimaryButton from '../components/PrimaryButton/index.svelte';
|
||||
import { VARIANTS } from '../components/PrimaryButton/constants';
|
||||
import { getSupabase } from '../utils/functions/supabase';
|
||||
import { forgotValidation } from '../utils/functions/validator';
|
||||
import { ROUTE } from '../utils/constants/routes';
|
||||
import { FORGOT_PASSWORD_FIELDS } from '../utils/constants/authentication';
|
||||
import AuthUI from '../components/AuthUI/index.svelte';
|
||||
import EmailSentIcon from '../components/Icons/EmailSentIcon.svelte';
|
||||
import { goto } from '$app/navigation';
|
||||
import TextField from '$lib/components/Form/TextField.svelte';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import { VARIANTS } from '$lib/components/PrimaryButton/constants';
|
||||
import { getSupabase } from '$lib/utils/functions/supabase';
|
||||
import { forgotValidation } from '$lib/utils/functions/validator';
|
||||
import { ROUTE } from '$lib/utils/constants/routes';
|
||||
import { FORGOT_PASSWORD_FIELDS } from '$lib/utils/constants/authentication';
|
||||
import AuthUI from '$lib/components/AuthUI/index.svelte';
|
||||
import EmailSentIcon from '$lib/components/Icons/EmailSentIcon.svelte';
|
||||
|
||||
export let config;
|
||||
|
||||
let supabase = getSupabase(config);
|
||||
let supabase = getSupabase();
|
||||
let fields = Object.assign({}, FORGOT_PASSWORD_FIELDS);
|
||||
let submitError;
|
||||
let loading = false;
|
||||
@@ -35,7 +27,7 @@
|
||||
|
||||
try {
|
||||
loading = true;
|
||||
const { data, error } = await supabase.auth.api.resetPasswordForEmail(
|
||||
const { data, error } = await supabase.auth.resetPasswordForEmail(
|
||||
fields.email,
|
||||
{
|
||||
redirectTo: window.location.origin + ROUTE.RESET,
|
||||
@@ -1,21 +1,13 @@
|
||||
<script context="module">
|
||||
export function preload(page, { config }) {
|
||||
return { config };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import TextField from '../components/Form/TextField.svelte';
|
||||
import PrimaryButton from '../components/PrimaryButton/index.svelte';
|
||||
import { getSupabase } from '../utils/functions/supabase';
|
||||
import { authValidation } from '../utils/functions/validator';
|
||||
import { LOGIN_FIELDS } from '../utils/constants/authentication';
|
||||
import AuthUI from '../components/AuthUI/index.svelte';
|
||||
|
||||
export let config;
|
||||
import TextField from '$lib/components/Form/TextField.svelte';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import { getSupabase } from '$lib/utils/functions/supabase';
|
||||
import { authValidation } from '$lib/utils/functions/validator';
|
||||
import { LOGIN_FIELDS } from '$lib/utils/constants/authentication';
|
||||
import AuthUI from '$lib/components/AuthUI/index.svelte';
|
||||
|
||||
let formRef;
|
||||
let supabase = getSupabase(config);
|
||||
let supabase = getSupabase();
|
||||
let fields = Object.assign({}, LOGIN_FIELDS);
|
||||
let submitError;
|
||||
let loading = false;
|
||||
@@ -32,7 +24,7 @@
|
||||
|
||||
try {
|
||||
loading = true;
|
||||
const { data, error } = await supabase.auth.signIn({
|
||||
const { data, error } = await supabase.auth.signInWithPassword({
|
||||
email: fields.email,
|
||||
password: fields.password,
|
||||
});
|
||||
@@ -1,23 +1,15 @@
|
||||
<script context="module">
|
||||
//@ts-ignore
|
||||
export function preload(page, { config }) {
|
||||
return { config };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
import { goto } from '@sapper/app';
|
||||
import TextField from '../components/Form/TextField.svelte';
|
||||
import UserProfileIcon from '../components/Icons/UserProfileIcon.svelte';
|
||||
import PrimaryButton from '../components/PrimaryButton/index.svelte';
|
||||
import { VARIANTS } from '../components/PrimaryButton/constants';
|
||||
import { profile } from '../utils/store/user';
|
||||
import { orgs, currentOrg } from '../utils/store/org';
|
||||
import { onboardingValidation } from '../utils/functions/validator';
|
||||
import { supabase } from '../utils/functions/supabase';
|
||||
import { blockedSubdomain } from '../utils/constants/app';
|
||||
import { welcomeModalStore } from '../components/WelcomeModal/store';
|
||||
import { getOrganizations } from '../utils/services/org';
|
||||
import { goto } from '$app/navigation';
|
||||
import TextField from '$lib/components/Form/TextField.svelte';
|
||||
import UserProfileIcon from '$lib/components/Icons/UserProfileIcon.svelte';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import { VARIANTS } from '$lib/components/PrimaryButton/constants';
|
||||
import { profile } from '$lib/utils/store/user';
|
||||
import { onboardingValidation } from '$lib/utils/functions/validator';
|
||||
import { supabase } from '$lib/utils/functions/supabase';
|
||||
import { blockedSubdomain } from '$lib/utils/constants/app';
|
||||
import { welcomeModalStore } from '$lib/components/WelcomeModal/store';
|
||||
import { getOrganizations } from '$lib/utils/services/org';
|
||||
|
||||
interface OnboardingField {
|
||||
fullname?: string;
|
||||
@@ -125,10 +117,13 @@
|
||||
return;
|
||||
}
|
||||
|
||||
const { data: org, error } = await supabase.from('organization').insert({
|
||||
name: fields.orgName,
|
||||
siteName: fields.siteName,
|
||||
});
|
||||
const { data: org, error } = await supabase
|
||||
.from('organization')
|
||||
.insert({
|
||||
name: fields.orgName,
|
||||
siteName: fields.siteName,
|
||||
})
|
||||
.select();
|
||||
console.log('Create organisation', org);
|
||||
if (error) {
|
||||
console.log('Error: create organisation', error);
|
||||
@@ -145,7 +140,8 @@
|
||||
organization_id: orgData.id,
|
||||
profile_id: $profile.id,
|
||||
role_id: 1,
|
||||
});
|
||||
})
|
||||
.select();
|
||||
console.log('Create organisation member', data);
|
||||
|
||||
if (error) {
|
||||
@@ -0,0 +1,5 @@
|
||||
export const load = ({ params = { slug: '' } }) => {
|
||||
return {
|
||||
orgName: params.slug,
|
||||
};
|
||||
};
|
||||
@@ -1,34 +1,27 @@
|
||||
<script context="module">
|
||||
export async function preload({ params }) {
|
||||
return {
|
||||
orgName: params.slug,
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<script lang="ts">
|
||||
// import { profile } from '../../utils/store/user';
|
||||
// import { supabase } from '../../utils/functions/supabase';
|
||||
import { goto } from '@sapper/app';
|
||||
import PrimaryButton from '../../../components/PrimaryButton/index.svelte';
|
||||
import Avatar from '../../../components/Avatar/index.svelte';
|
||||
// import { profile } from '$lib/utils/store/user';
|
||||
// import { supabase } from '$lib/utils/functions/supabase';
|
||||
import { goto } from '$app/navigation';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import Avatar from '$lib/components/Avatar/index.svelte';
|
||||
import { InlineCalendar, Datepicker } from 'svelte-calendar';
|
||||
import CheckmarkFilled20 from 'carbon-icons-svelte/lib/CheckmarkFilled20';
|
||||
import CheckmarkFilledIcon from 'carbon-icons-svelte/lib/CheckmarkFilled.svelte';
|
||||
import {
|
||||
formatUserUpcomingData,
|
||||
formatDate,
|
||||
} from '../../../utils/functions/routes/dashboard';
|
||||
import { user } from '../../../utils/store/user';
|
||||
import { fetchUserUpcomingData } from '../../../utils/services/dashboard';
|
||||
import { isMobile } from '../../../utils/store/useMobile';
|
||||
} from '$lib/utils/functions/routes/dashboard';
|
||||
import { user } from '$lib/utils/store/user';
|
||||
import { fetchUserUpcomingData } from '$lib/utils/services/dashboard';
|
||||
import { isMobile } from '$lib/utils/store/useMobile';
|
||||
import type {
|
||||
UserLessonDataType,
|
||||
LessonsByMonthIndexType,
|
||||
} from '../../../utils/types';
|
||||
import WelcomeModal from '../../../components/WelcomeModal/WelcomeModal.svelte';
|
||||
} from '$lib/utils/types';
|
||||
import WelcomeModal from '$lib/components/WelcomeModal/WelcomeModal.svelte';
|
||||
import { onMount } from 'svelte';
|
||||
|
||||
export let orgName: string;
|
||||
export let data;
|
||||
const { orgName } = data;
|
||||
|
||||
function createCourse() {
|
||||
goto(`/org/${orgName}/courses?create=true`);
|
||||
@@ -194,7 +187,7 @@
|
||||
onMount(() => {
|
||||
// Remove default shouldEnlargeDay=true when <DatePicker /> on mobile
|
||||
if ($store && $store.shouldEnlargeDay) {
|
||||
$store.shouldEnlargeDay = false
|
||||
$store.shouldEnlargeDay = false;
|
||||
}
|
||||
});
|
||||
|
||||
@@ -272,7 +265,7 @@
|
||||
{lessonData.lesson_title}
|
||||
{#if lessonData.is_complete}
|
||||
<span class="ml-2 success">
|
||||
<CheckmarkFilled20 class="carbon-icon" />
|
||||
<CheckmarkFilledIcon size={20} class="carbon-icon" />
|
||||
</span>
|
||||
{:else}
|
||||
<span class="text-md ml-2">🔒</span>
|
||||
@@ -399,4 +392,4 @@
|
||||
font-size: 30px;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
</style>
|
||||
@@ -1,6 +1,6 @@
|
||||
<script>
|
||||
import PrimaryButton from '../../../components/PrimaryButton/index.svelte';
|
||||
import Audience from '../../../components/Org/Audience/index.svelte';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import Audience from '$lib/components/Org/Audience/index.svelte';
|
||||
|
||||
let isLoading = false;
|
||||
function exportAudience() {
|
||||
+4
-4
@@ -1,8 +1,8 @@
|
||||
<script>
|
||||
import { goto } from '@sapper/app';
|
||||
import Community from '../../../../components/Org/Community/index.svelte';
|
||||
import PrimaryButton from '../../../../components/PrimaryButton/index.svelte';
|
||||
import { currentOrgPath } from '../../../../utils/store/org';
|
||||
import { goto } from '$app/navigation';
|
||||
import Community from '$lib/components/Org/Community/index.svelte';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import { currentOrgPath } from '$lib/utils/store/org';
|
||||
|
||||
function askCommunity() {
|
||||
goto(`${$currentOrgPath}/community/ask`);
|
||||
@@ -0,0 +1,5 @@
|
||||
export const load = ({ params = { slug: '' } }) => {
|
||||
return {
|
||||
slug: params.slug,
|
||||
};
|
||||
};
|
||||
+33
-35
@@ -1,39 +1,34 @@
|
||||
<script context="module">
|
||||
export async function preload({ params }) {
|
||||
return { slug: params.slug };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import marked from 'marked';
|
||||
import { marked } from 'marked';
|
||||
import dayjs from 'dayjs';
|
||||
import pluralize from 'pluralize';
|
||||
import relativeTime from 'dayjs/plugin/relativeTime';
|
||||
import Delete16 from 'carbon-icons-svelte/lib/Delete16';
|
||||
import TrashCanIcon from 'carbon-icons-svelte/lib/TrashCan.svelte';
|
||||
import { SkeletonPlaceholder, SkeletonText } from 'carbon-components-svelte';
|
||||
import ArrowLeft24 from 'carbon-icons-svelte/lib/ArrowLeft24';
|
||||
import Vote from '../../../../components/Vote/index.svelte';
|
||||
import PrimaryButton from '../../../../components/PrimaryButton/index.svelte';
|
||||
import { VARIANTS } from '../../../../components/PrimaryButton/constants';
|
||||
import TextEditor from '../../../../components/TextEditor/index.svelte';
|
||||
import Avatar from '../../../../components/Avatar/index.svelte';
|
||||
import IconButton from '../../../../components/IconButton/index.svelte';
|
||||
import CheckmarkOutline20 from 'carbon-icons-svelte/lib/CheckmarkOutline20';
|
||||
import { currentOrgPath, currentOrg } from '../../../../utils/store/org';
|
||||
import { profile } from '../../../../utils/store/user';
|
||||
import { supabase } from '../../../../utils/functions/supabase';
|
||||
import ArrowLeftIcon from 'carbon-icons-svelte/lib/ArrowLeft.svelte';
|
||||
import Vote from '$lib/components/Vote/index.svelte';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import { VARIANTS } from '$lib/components/PrimaryButton/constants';
|
||||
import TextEditor from '$lib/components/TextEditor/index.svelte';
|
||||
import Avatar from '$lib/components/Avatar/index.svelte';
|
||||
import IconButton from '$lib/components/IconButton/index.svelte';
|
||||
import CheckmarkOutlineIcon from 'carbon-icons-svelte/lib/CheckmarkOutline.svelte';
|
||||
import { currentOrgPath, currentOrg } from '$lib/utils/store/org';
|
||||
import { profile } from '$lib/utils/store/user';
|
||||
import { supabase } from '$lib/utils/functions/supabase';
|
||||
import {
|
||||
askCommunityValidation,
|
||||
commentInCommunityValidation,
|
||||
} from '../../../../utils/functions/validator';
|
||||
import { SNACKBAR_SEVERITY } from '../../../../components/Snackbar/constants';
|
||||
import { snackbarStore } from '../../../../components/Snackbar/store';
|
||||
import TextField from '../../../../components/Form/TextField.svelte';
|
||||
import DeleteCommentModal from '../../../../components/Org/Community/DeleteCommentModal.svelte';
|
||||
} from '$lib/utils/functions/validator';
|
||||
import { SNACKBAR_SEVERITY } from '$lib/components/Snackbar/constants';
|
||||
import { snackbarStore } from '$lib/components/Snackbar/store';
|
||||
import TextField from '$lib/components/Form/TextField.svelte';
|
||||
import DeleteCommentModal from '$lib/components/Org/Community/DeleteCommentModal.svelte';
|
||||
|
||||
dayjs.extend(relativeTime);
|
||||
|
||||
export let slug;
|
||||
export let data;
|
||||
const { slug } = data;
|
||||
|
||||
let question;
|
||||
let comment = '';
|
||||
@@ -122,13 +117,16 @@
|
||||
return;
|
||||
}
|
||||
|
||||
const { data, error } = await supabase.from('community_answer').insert({
|
||||
id: undefined,
|
||||
body: comment,
|
||||
question_id: question.id,
|
||||
author_id: $currentOrg.memberId,
|
||||
votes: 0,
|
||||
});
|
||||
const { data, error } = await supabase
|
||||
.from('community_answer')
|
||||
.insert({
|
||||
id: undefined,
|
||||
body: comment,
|
||||
question_id: question.id,
|
||||
author_id: $currentOrg.memberId,
|
||||
votes: 0,
|
||||
})
|
||||
.select();
|
||||
|
||||
if (error) {
|
||||
console.error('Error: commenting', error);
|
||||
@@ -290,7 +288,7 @@
|
||||
class="text-gray-500 dark:text-white text-md flex items-center"
|
||||
href={`${$currentOrgPath}/community`}
|
||||
>
|
||||
<ArrowLeft24 class="carbon-icon" /> Go Back
|
||||
<ArrowLeftIcon size={24} class="carbon-icon" /> Go Back
|
||||
</a>
|
||||
<div class="my-5 flex justify-between items-center">
|
||||
{#if isEditMode}
|
||||
@@ -390,7 +388,7 @@
|
||||
</div>
|
||||
|
||||
{#if isValidAnswer}
|
||||
<CheckmarkOutline20 />
|
||||
<CheckmarkOutlineIcon size={20} />
|
||||
{/if}
|
||||
|
||||
{#if comment.authorId === $profile.id}
|
||||
@@ -401,7 +399,7 @@
|
||||
deleteComment.commentId = comment.id;
|
||||
}}
|
||||
>
|
||||
<Delete16 class="carbon-icon" />
|
||||
<TrashCanIcon size={16} class="carbon-icon" />
|
||||
</IconButton>
|
||||
{/if}
|
||||
</header>
|
||||
+13
-12
@@ -1,14 +1,14 @@
|
||||
<script>
|
||||
import { goto } from '@sapper/app';
|
||||
import ArrowLeft24 from 'carbon-icons-svelte/lib/ArrowLeft24';
|
||||
import TextEditor from '../../../../components/TextEditor/index.svelte';
|
||||
import { currentOrgPath, currentOrg } from '../../../../utils/store/org';
|
||||
import PrimaryButton from '../../../../components/PrimaryButton/index.svelte';
|
||||
import { askCommunityValidation } from '../../../../utils/functions/validator';
|
||||
import { supabase } from '../../../../utils/functions/supabase';
|
||||
import { SNACKBAR_SEVERITY } from '../../../../components/Snackbar/constants';
|
||||
import { snackbarStore } from '../../../../components/Snackbar/store';
|
||||
import generateSlug from '../../../../utils/functions/generateSlug';
|
||||
import { goto } from '$app/navigation';
|
||||
import ArrowLeftIcon from 'carbon-icons-svelte/lib/ArrowLeft.svelte';
|
||||
import TextEditor from '$lib/components/TextEditor/index.svelte';
|
||||
import { currentOrgPath, currentOrg } from '$lib/utils/store/org';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import { askCommunityValidation } from '$lib/utils/functions/validator';
|
||||
import { supabase } from '$lib/utils/functions/supabase';
|
||||
import { SNACKBAR_SEVERITY } from '$lib/components/Snackbar/constants';
|
||||
import { snackbarStore } from '$lib/components/Snackbar/store';
|
||||
import generateSlug from '$lib/utils/functions/generateSlug';
|
||||
|
||||
let errors = {};
|
||||
let fields = {
|
||||
@@ -32,7 +32,8 @@
|
||||
author_id: $currentOrg.memberId,
|
||||
votes: 0,
|
||||
slug: generateSlug(fields.title),
|
||||
});
|
||||
})
|
||||
.select();
|
||||
|
||||
if (error) {
|
||||
console.error('Error: asking question', error);
|
||||
@@ -60,7 +61,7 @@
|
||||
class="text-gray-500 dark:text-white text-md flex items-center"
|
||||
href={`${$currentOrgPath}/community`}
|
||||
>
|
||||
<ArrowLeft24 class="carbon-icon" /> Go Back
|
||||
<ArrowLeftIcon size={24} class="carbon-icon" /> Go Back
|
||||
</a>
|
||||
<div class="flex items-center justify-between">
|
||||
<h1 class="dark:text-white text-3xl font-bold">Ask the community</h1>
|
||||
@@ -1,89 +0,0 @@
|
||||
<script context="module">
|
||||
import { profile } from '../../../utils/store/user';
|
||||
import { fetchCourses } from '../../../components/Courses/api';
|
||||
|
||||
export async function preload(page, params) {
|
||||
const parsedUser = JSON.parse(params.user);
|
||||
// if (page.query.create === 'true') {
|
||||
// $createCourseModal.open = true;
|
||||
// }
|
||||
// if (parsedUser && parsedUser.id) {
|
||||
// return fetchCourses(parsedUser.id);
|
||||
// }
|
||||
|
||||
return {
|
||||
page,
|
||||
allCourses: [],
|
||||
organizationId: null,
|
||||
cantFetch: true,
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import Courses from '../../../components/Courses/index.svelte';
|
||||
import NewCourseModal from '../../../components/Courses/components/NewCourseModal/index.svelte';
|
||||
import PrimaryButton from '../../../components/PrimaryButton/index.svelte';
|
||||
import {
|
||||
courses,
|
||||
createCourseModal,
|
||||
courseMetaDeta,
|
||||
} from '../../../components/Courses/store';
|
||||
import { setProfileIdOfGroupMember } from '../../../utils/services/courses';
|
||||
|
||||
export let allCourses = [];
|
||||
export let cantFetch;
|
||||
export let page;
|
||||
|
||||
if (page.query.create === 'true') {
|
||||
$createCourseModal.open = true;
|
||||
}
|
||||
async function getCourses(userId) {
|
||||
if (process.browser) {
|
||||
if (cantFetch && typeof cantFetch === 'boolean' && !allCourses.length) {
|
||||
$courseMetaDeta.isLoading = true;
|
||||
|
||||
const updatedProfile = await setProfileIdOfGroupMember(
|
||||
$profile.email,
|
||||
userId
|
||||
);
|
||||
console.log(`updatedProfile`, updatedProfile);
|
||||
const coursesResult = await fetchCourses(userId);
|
||||
console.log(`coursesResult`, coursesResult);
|
||||
|
||||
$courseMetaDeta.isLoading = false;
|
||||
if (!coursesResult) return;
|
||||
|
||||
// organizationId = coursesResult.organizationId;
|
||||
courses.set(coursesResult.allCourses);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
courses.set(allCourses);
|
||||
});
|
||||
|
||||
$: getCourses($profile.id);
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Courses - ClassroomIO</title>
|
||||
</svelte:head>
|
||||
|
||||
<section class="w-full max-w-6xl mx-auto">
|
||||
<div class="py-10 px-5">
|
||||
<div class="flex items-center justify-between mb-10">
|
||||
<h1 class="dark:text-white text-3xl font-bold">Courses</h1>
|
||||
<PrimaryButton
|
||||
label="Create Course"
|
||||
onClick={() => ($createCourseModal.open = true)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<NewCourseModal />
|
||||
|
||||
<Courses />
|
||||
</div>
|
||||
</section>
|
||||
@@ -0,0 +1,6 @@
|
||||
export const load = ({ params = { slug: '' } }) => {
|
||||
return {
|
||||
allCourses: [],
|
||||
cantFetch: true,
|
||||
};
|
||||
};
|
||||
@@ -0,0 +1,70 @@
|
||||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import { page } from '$app/stores';
|
||||
import { profile } from '$lib/utils/store/user';
|
||||
import { fetchCourses } from '$lib/components/Courses/api';
|
||||
import Courses from '$lib/components/Courses/index.svelte';
|
||||
import NewCourseModal from '$lib/components/Courses/components/NewCourseModal/index.svelte';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import {
|
||||
courses,
|
||||
createCourseModal,
|
||||
courseMetaDeta,
|
||||
} from '$lib/components/Courses/store';
|
||||
import { setProfileIdOfGroupMember } from '$lib/utils/services/courses';
|
||||
|
||||
export let data;
|
||||
let { allCourses, cantFetch } = data;
|
||||
|
||||
const urlParams = new URLSearchParams($page.url.search);
|
||||
|
||||
if (urlParams.get('create') === 'true') {
|
||||
$createCourseModal.open = true;
|
||||
}
|
||||
|
||||
async function getCourses(userId) {
|
||||
if (cantFetch && typeof cantFetch === 'boolean' && !allCourses.length) {
|
||||
$courseMetaDeta.isLoading = true;
|
||||
|
||||
const updatedProfile = await setProfileIdOfGroupMember(
|
||||
$profile.email,
|
||||
userId
|
||||
);
|
||||
console.log(`updatedProfile`, updatedProfile);
|
||||
const coursesResult = await fetchCourses(userId);
|
||||
console.log(`coursesResult`, coursesResult);
|
||||
|
||||
$courseMetaDeta.isLoading = false;
|
||||
if (!coursesResult) return;
|
||||
|
||||
// organizationId = coursesResult.organizationId;
|
||||
courses.set(coursesResult.allCourses);
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
courses.set(allCourses);
|
||||
});
|
||||
|
||||
$: getCourses($profile.id);
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
<title>Courses - ClassroomIO</title>
|
||||
</svelte:head>
|
||||
|
||||
<section class="w-full max-w-6xl mx-auto">
|
||||
<div class="py-10 px-5">
|
||||
<div class="flex items-center justify-between mb-10">
|
||||
<h1 class="dark:text-white text-3xl font-bold">Courses</h1>
|
||||
<PrimaryButton
|
||||
label="Create Course"
|
||||
onClick={() => ($createCourseModal.open = true)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<NewCourseModal />
|
||||
|
||||
<Courses />
|
||||
</div>
|
||||
</section>
|
||||
@@ -1,9 +1,9 @@
|
||||
<script>
|
||||
import Quizzes from '../../../../components/Org/Quiz/Quizzes.svelte';
|
||||
import NewQuizModal from '../../../../components/Org/Quiz/NewQuizModal.svelte';
|
||||
import DeleteModal from '../../../../components/Org/Quiz/DeleteModal.svelte';
|
||||
import PrimaryButton from '../../../../components/PrimaryButton/index.svelte';
|
||||
import { createQuizModal } from '../../../../utils/store/org';
|
||||
import Quizzes from '$lib/components/Org/Quiz/Quizzes.svelte';
|
||||
import NewQuizModal from '$lib/components/Org/Quiz/NewQuizModal.svelte';
|
||||
import DeleteModal from '$lib/components/Org/Quiz/DeleteModal.svelte';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import { createQuizModal } from '$lib/utils/store/org';
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
@@ -0,0 +1,5 @@
|
||||
export const load = ({ params = { slug: '' } }) => {
|
||||
return {
|
||||
quizId: params.slug,
|
||||
};
|
||||
};
|
||||
+26
-36
@@ -1,39 +1,33 @@
|
||||
<script context="module">
|
||||
export async function preload({ params }) {
|
||||
return {
|
||||
quizId: params.slug,
|
||||
};
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { onMount } from 'svelte';
|
||||
import { goto } from '@sapper/app';
|
||||
import { goto } from '$app/navigation';
|
||||
import cloneDeep from 'lodash/cloneDeep';
|
||||
import isBoolean from 'lodash/isBoolean';
|
||||
import ArrowLeft24 from 'carbon-icons-svelte/lib/ArrowLeft24';
|
||||
import CheckmarkFilled24 from 'carbon-icons-svelte/lib/CheckmarkFilled24';
|
||||
import WarningFilled20 from 'carbon-icons-svelte/lib/WarningFilled20';
|
||||
import ArrowLeftIcon from 'carbon-icons-svelte/lib/ArrowLeft.svelte';
|
||||
import CheckmarkFilledIcon from 'carbon-icons-svelte/lib/CheckmarkFilled.svelte';
|
||||
import WarningFilledIcon from 'carbon-icons-svelte/lib/WarningFilled.svelte';
|
||||
|
||||
import { Select, SelectItem } from 'carbon-components-svelte';
|
||||
import { currentOrgPath, deleteModal } from '../../../../utils/store/org';
|
||||
import PrimaryButton from '../../../../components/PrimaryButton/index.svelte';
|
||||
import { VARIANTS } from '../../../../components/PrimaryButton/constants';
|
||||
import { currentOrgPath, deleteModal } from '$lib/utils/store/org';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import { VARIANTS } from '$lib/components/PrimaryButton/constants';
|
||||
import {
|
||||
themeImages,
|
||||
allOptions,
|
||||
booleanOptions,
|
||||
allThemes,
|
||||
} from '../../../../utils/constants/quiz';
|
||||
import { quizStore, quizesStore } from '../../../../utils/store/org';
|
||||
import DeleteModal from '../../../../components/Org/Quiz/DeleteModal.svelte';
|
||||
import Preview from '../../../../components/Org/Quiz/Play/Preview.svelte';
|
||||
import QuizQuestion from '../../../../components/Org/Quiz/QuizQuestion.svelte';
|
||||
import { snackbarStore } from '../../../../components/Snackbar/store';
|
||||
import { SNACKBAR_SEVERITY } from '../../../../components/Snackbar/constants';
|
||||
import { supabase } from '../../../../utils/functions/supabase';
|
||||
} from '$lib/utils/constants/quiz';
|
||||
import { quizStore, quizesStore } from '$lib/utils/store/org';
|
||||
import DeleteModal from '$lib/components/Org/Quiz/DeleteModal.svelte';
|
||||
import Preview from '$lib/components/Org/Quiz/Play/Preview.svelte';
|
||||
import QuizQuestion from '$lib/components/Org/Quiz/QuizQuestion.svelte';
|
||||
import { snackbarStore } from '$lib/components/Snackbar/store';
|
||||
import { SNACKBAR_SEVERITY } from '$lib/components/Snackbar/constants';
|
||||
import { supabase } from '$lib/utils/functions/supabase';
|
||||
|
||||
export let data;
|
||||
const { quizId } = data;
|
||||
|
||||
export let quizId;
|
||||
// Questionnaire State
|
||||
let currentQuestion = $quizStore.questions[0] || {
|
||||
options: [],
|
||||
@@ -153,15 +147,10 @@
|
||||
|
||||
const { data, error } = await supabase
|
||||
.from('quiz')
|
||||
.update(
|
||||
{
|
||||
...$quizStore,
|
||||
updated_at: new Date(),
|
||||
},
|
||||
{
|
||||
returning: 'minimal',
|
||||
}
|
||||
)
|
||||
.update({
|
||||
...$quizStore,
|
||||
updated_at: new Date(),
|
||||
})
|
||||
.match({ id: quizId });
|
||||
|
||||
console.log('data', data);
|
||||
@@ -223,7 +212,7 @@
|
||||
class="text-gray-500 dark:text-white text-md flex items-center"
|
||||
href={`${$currentOrgPath}/quiz`}
|
||||
>
|
||||
<ArrowLeft24 class="carbon-icon" /> Back to Quizzes
|
||||
<ArrowLeftIcon size={24} class="carbon-icon" /> Back to Quizzes
|
||||
</a>
|
||||
|
||||
<h3 class="my-3">Quiz</h3>
|
||||
@@ -243,7 +232,7 @@
|
||||
Question {i + 1}
|
||||
|
||||
{#if qHasError(question.id, errors)}
|
||||
<WarningFilled20 class="carbon-icon error" />
|
||||
<WarningFilledIcon size={20} class="carbon-icon error" />
|
||||
{/if}
|
||||
</button>
|
||||
{/each}
|
||||
@@ -381,7 +370,8 @@
|
||||
_theme.id && 'border-blue-700'}"
|
||||
>
|
||||
{#if $quizStore.theme === _theme.id}
|
||||
<CheckmarkFilled24
|
||||
<CheckmarkFilledIcon
|
||||
size={24}
|
||||
class="carbon-icon absolute top-4 right-4"
|
||||
style="fill:white;"
|
||||
/>
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<script>
|
||||
import OrgSettings from '../../../../components/Org/Settings/index.svelte';
|
||||
import OrgSettings from '$lib/components/Org/Settings/index.svelte';
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
<script>
|
||||
import Domains from '../../../../components/Org/Settings/Domains.svelte';
|
||||
import { currentOrgPath } from '../../../../utils/store/org';
|
||||
import Domains from '$lib/components/Org/Settings/Domains.svelte';
|
||||
import { currentOrgPath } from '$lib/utils/store/org';
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
+2
-2
@@ -1,6 +1,6 @@
|
||||
<script>
|
||||
import TeamMembers from '../../../../components/Org/Settings/TeamMembers.svelte';
|
||||
import { currentOrgPath } from '../../../../utils/store/org';
|
||||
import TeamMembers from '$lib/components/Org/Settings/TeamMembers.svelte';
|
||||
import { currentOrgPath } from '$lib/utils/store/org';
|
||||
</script>
|
||||
|
||||
<svelte:head>
|
||||
@@ -1 +0,0 @@
|
||||
Sites Page
|
||||
@@ -0,0 +1,5 @@
|
||||
export const load = ({ params = { id: '' } }) => {
|
||||
return {
|
||||
profileId: params.id,
|
||||
};
|
||||
};
|
||||
@@ -1,21 +1,16 @@
|
||||
<script context="module">
|
||||
export function preload({ params }) {
|
||||
return { profileId: params.id };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { goto } from '@sapper/app';
|
||||
import UserAvatar16 from 'carbon-icons-svelte/lib/UserAvatar16';
|
||||
import Book16 from 'carbon-icons-svelte/lib/Book16';
|
||||
import TextField from '../../components/Form/TextField.svelte';
|
||||
import PrimaryButton from '../../components/PrimaryButton/index.svelte';
|
||||
import { VARIANTS } from '../../components/PrimaryButton/constants';
|
||||
import UploadImage from '../../components/UploadImage/index.svelte';
|
||||
import { supabase } from '../../utils/functions/supabase';
|
||||
import { user, profile } from '../../utils/store/user';
|
||||
import { goto } from '$app/navigation';
|
||||
import UserAvatarIcon from 'carbon-icons-svelte/lib/UserAvatar.svelte';
|
||||
import BookIcon from 'carbon-icons-svelte/lib/Book.svelte';
|
||||
import TextField from '$lib/components/Form/TextField.svelte';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import { VARIANTS } from '$lib/components/PrimaryButton/constants';
|
||||
import UploadImage from '$lib/components/UploadImage/index.svelte';
|
||||
import { supabase } from '$lib/utils/functions/supabase';
|
||||
import { user, profile } from '$lib/utils/store/user';
|
||||
|
||||
export let profileId;
|
||||
export let data;
|
||||
const { profileId } = data;
|
||||
|
||||
let avatar;
|
||||
let loading = false;
|
||||
@@ -78,9 +73,7 @@
|
||||
|
||||
let { error } = await supabase
|
||||
.from('profile')
|
||||
.update(updates, {
|
||||
returning: 'minimal', // Don't return the value after inserting
|
||||
})
|
||||
.update(updates)
|
||||
.match({ id: profileId });
|
||||
|
||||
if (isOwner) {
|
||||
@@ -195,11 +188,11 @@
|
||||
</p>
|
||||
<div class="mt-2 flex items-center">
|
||||
<span class="flex mr-2 items-center">
|
||||
<UserAvatar16 class="mr-2" /> 5
|
||||
<UserAvatarIcon size={16} class="mr-2" /> 5
|
||||
</span>
|
||||
|
||||
<span class="flex mr-2 items-center">
|
||||
<Book16 class="mr-2" /> 5
|
||||
<BookIcon size={16} class="mr-2" /> 5
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -216,11 +209,11 @@
|
||||
</p>
|
||||
<div class="mt-2 flex items-center">
|
||||
<span class="flex mr-2 items-center">
|
||||
<UserAvatar16 class="mr-2" /> 30
|
||||
<UserAvatarIcon size={16} class="mr-2" /> 30
|
||||
</span>
|
||||
|
||||
<span class="flex mr-2 items-center">
|
||||
<Book16 class="mr-2" /> 3
|
||||
<BookIcon size={16} class="mr-2" /> 3
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -1,25 +1,17 @@
|
||||
<script context="module">
|
||||
export function preload(page, { config }) {
|
||||
return { config };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { goto } from '@sapper/app';
|
||||
import TextField from '../components/Form/TextField.svelte';
|
||||
import PrimaryButton from '../components/PrimaryButton/index.svelte';
|
||||
import { getSupabase } from '../utils/functions/supabase';
|
||||
import { goto } from '$app/navigation';
|
||||
import TextField from '$lib/components/Form/TextField.svelte';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import { getSupabase } from '$lib/utils/functions/supabase';
|
||||
import {
|
||||
resetValidation,
|
||||
getConfirmPasswordError,
|
||||
getDisableSubmit,
|
||||
} from '../utils/functions/validator';
|
||||
import { RESET_FIELDS } from '../utils/constants/authentication';
|
||||
import AuthUI from '../components/AuthUI/index.svelte';
|
||||
} from '$lib/utils/functions/validator';
|
||||
import { RESET_FIELDS } from '$lib/utils/constants/authentication';
|
||||
import AuthUI from '$lib/components/AuthUI/index.svelte';
|
||||
|
||||
export let config;
|
||||
|
||||
let supabase = getSupabase(config);
|
||||
let supabase = getSupabase();
|
||||
let fields = Object.assign({}, RESET_FIELDS);
|
||||
let loading = false;
|
||||
let success = false;
|
||||
@@ -1,25 +1,17 @@
|
||||
<script context="module">
|
||||
export function preload(page, { config }) {
|
||||
return { config };
|
||||
}
|
||||
</script>
|
||||
|
||||
<script>
|
||||
import { goto } from "@sapper/app";
|
||||
import TextField from "../components/Form/TextField.svelte";
|
||||
import PrimaryButton from "../components/PrimaryButton/index.svelte";
|
||||
import { getSupabase } from "../utils/functions/supabase";
|
||||
import { goto } from '$app/navigation';
|
||||
import TextField from '$lib/components/Form/TextField.svelte';
|
||||
import PrimaryButton from '$lib/components/PrimaryButton/index.svelte';
|
||||
import { getSupabase } from '$lib/utils/functions/supabase';
|
||||
import {
|
||||
authValidation,
|
||||
getConfirmPasswordError,
|
||||
getDisableSubmit,
|
||||
} from "../utils/functions/validator";
|
||||
import { SIGNUP_FIELDS } from "../utils/constants/authentication";
|
||||
import AuthUI from "../components/AuthUI/index.svelte";
|
||||
} from '$lib/utils/functions/validator';
|
||||
import { SIGNUP_FIELDS } from '$lib/utils/constants/authentication';
|
||||
import AuthUI from '$lib/components/AuthUI/index.svelte';
|
||||
|
||||
export let config;
|
||||
|
||||
let supabase = getSupabase(config);
|
||||
let supabase = getSupabase();
|
||||
let fields = Object.assign({}, SIGNUP_FIELDS);
|
||||
let loading = false;
|
||||
let success = false;
|
||||
@@ -30,7 +22,7 @@
|
||||
|
||||
async function handleSubmit(e) {
|
||||
const validationRes = authValidation(fields);
|
||||
console.log("validationRes", validationRes);
|
||||
console.log('validationRes', validationRes);
|
||||
|
||||
if (Object.keys(validationRes).length) {
|
||||
errors = Object.assign(errors, validationRes);
|
||||
@@ -43,12 +35,12 @@
|
||||
email: fields.email,
|
||||
password: fields.password,
|
||||
});
|
||||
console.log("data", data);
|
||||
console.log('data', data);
|
||||
if (error) throw error;
|
||||
|
||||
formRef?.reset();
|
||||
|
||||
return goto("/login");
|
||||
return goto('/login');
|
||||
// success = true;
|
||||
// fields = Object.assign({}, SIGNUP_FIELDS);
|
||||
} catch (error) {
|
||||
Reference in New Issue
Block a user