feat: migrate course UI from supabase (#615)
* chore: fix storybook build * chore: implement theming * community list not showing properly * refactor: migrate Chip component to @cio/ui/custom/chip - Updated imports for the Chip component across multiple files to use the new location in the @cio/ui package. - Replaced the previous Chip implementation with a new version that utilizes a Badge for better styling and functionality. - Adjusted related components to ensure consistent usage of the updated Chip component. * fix: align course sidebar design to match organization design (#611) * fix: align course sidebar design to match organization design * feat: add hideSearch prop to AppHeader and update sidebar layout --------- Co-authored-by: Rotimi Best <best@classroomio.com> * refactor: replace PrimaryButton with Button component across multiple files - Updated various components to use the new Button component from @cio/ui/base/button instead of the deprecated PrimaryButton. - Ensured consistent button usage throughout the application for improved styling and functionality. - Removed the PrimaryButton component and its associated constants from the codebase. * refactor: standardize button and input usage across components - Replaced instances of deprecated components such as TextField, TextArea, and IconButton with their updated counterparts (InputField, TextareaField, and updated IconButton). - Ensured consistent event handling by changing `onClick` to `onclick` for better alignment with Svelte's event binding conventions. - Removed unused components and streamlined imports to enhance code maintainability and readability. * chore: themeing, course card, use $features * refactor: centralize UI components and update modal implementations - Refactored various components to centralize UI elements, improving discoverability and maintainability. - Replaced deprecated modal components with the new Dialog component for consistent modal behavior across the application. - Removed unused components and streamlined imports to enhance code clarity and reduce complexity. * feat: add new documentation and refactor org and lms UI components - Introduced new documentation files for Auth Flow, Breadcrumbs Refactoring, Page and Route Creation, and Route Page Setup to enhance developer onboarding and reference. - Refactored various UI components, including the Course Sidebar and Lesson Modal, to improve layout and functionality. - Removed deprecated components and streamlined imports for better maintainability. - Updated translations across multiple languages to ensure consistency in user experience. * refactor: update UI components and improve styling consistency - Refactored various components to enhance styling consistency, including updates to button and text color classes. - Removed deprecated components and streamlined imports for better maintainability. - Replaced instances of PageBody with a more flexible Page component structure across multiple routes. - Updated translations and UI elements to align with the new design system. - Deleted unused components to reduce code complexity and improve clarity. * update output.css --------- Co-authored-by: Abdulmuizz Hamzat <103611443+canhamzacode@users.noreply.github.com>
This commit is contained in:
co-authored by
Abdulmuizz Hamzat
parent
e6a3cf9332
commit
9fb6c7cbaa
@@ -1,5 +1,5 @@
|
||||
import { lesson } from '$lib/components/Course/components/Lesson/store/lessons';
|
||||
import { snackbar } from '$lib/components/Snackbar/store';
|
||||
import { snackbar } from '$features/ui/snackbar/store';
|
||||
|
||||
export function formatYoutubeVideo(url: string, errors: Record<string, string>) {
|
||||
console.log(`url`, url);
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { appInitApi } from '$lib/features/app/init.svelte';
|
||||
import { appInitApi } from '$features/app/init.svelte';
|
||||
import { authClient } from '$lib/utils/services/auth/client';
|
||||
import { capturePosthogEvent } from '$lib/utils/services/posthog';
|
||||
import { goto } from '$app/navigation';
|
||||
|
||||
@@ -1,51 +1,17 @@
|
||||
import { tc } from '$lib/utils/functions/trycatch';
|
||||
import { darken, lighten } from 'color2k';
|
||||
|
||||
function updateThemeClassInBody(newClass: string, customRegex?: string) {
|
||||
const regex = /theme-[\w]+/gi;
|
||||
document.body.className = document.body.className.replace(customRegex ?? regex, newClass);
|
||||
}
|
||||
import { tc } from '$lib/utils/functions/trycatch';
|
||||
|
||||
export function setTheme(_theme?: string) {
|
||||
const theme = _theme || '';
|
||||
|
||||
// this condition checks if it's a hex code from the db or a specified theme
|
||||
if (theme && !theme.includes('theme-')) {
|
||||
// add the "custom-theme" styles to the head tag
|
||||
injectCustomTheme(theme);
|
||||
|
||||
// add the "custom-theme" classname to the head tag
|
||||
setCustomTheme('theme-custom');
|
||||
} else if (!theme && document.body.className.includes('theme-')) {
|
||||
// if no theme and a theme is already applied, remove it
|
||||
updateThemeClassInBody(theme);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// In case theme already exists in dom, don't add
|
||||
if (document.body.className.includes(theme)) return;
|
||||
|
||||
// set the new theme
|
||||
export function setTheme(theme: string) {
|
||||
localStorage.setItem('theme', theme);
|
||||
document.body.className = document.body.className.concat(' ', theme);
|
||||
}
|
||||
|
||||
export function setCustomTheme(theme?: string) {
|
||||
// In case the default theme is added but another theme exists
|
||||
if (!theme && document.body.className.includes('theme-')) {
|
||||
updateThemeClassInBody(theme || '');
|
||||
return;
|
||||
}
|
||||
if (theme.includes('#')) {
|
||||
const escapedHex = theme.replace(/"/g, '\\"');
|
||||
document.body.setAttribute('data-theme', escapedHex);
|
||||
|
||||
// Remove any class starting with "theme-"
|
||||
updateThemeClassInBody('');
|
||||
|
||||
const _theme = theme || '';
|
||||
// Add the new theme if it doesn't already exist
|
||||
if (!document.body.className.includes(_theme)) {
|
||||
localStorage.setItem('theme', _theme);
|
||||
document.body.className = document.body.className.concat(' ', _theme);
|
||||
injectCustomTheme(escapedHex);
|
||||
} else {
|
||||
document.body.setAttribute('data-theme', theme);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -54,10 +20,8 @@ const _lighten = (hex: string, no: number) => tc(() => lighten(hex, no), hex);
|
||||
const _darken = (hex: string, no: number) => tc(() => darken(hex, no), hex);
|
||||
|
||||
export function injectCustomTheme(hex: string) {
|
||||
const styleId = 'theme-custom';
|
||||
let styleElement = document.getElementById(styleId);
|
||||
|
||||
// generate shades using color2k's lighten function
|
||||
// Generate shades using color2k's lighten/darken functions
|
||||
// Following the same pattern as predefined themes (e.g., purple)
|
||||
const shades = {
|
||||
50: _lighten(hex, 0.7),
|
||||
100: _lighten(hex, 0.6),
|
||||
@@ -72,46 +36,36 @@ export function injectCustomTheme(hex: string) {
|
||||
};
|
||||
|
||||
const styleContent = `
|
||||
.theme-custom .bg-primary-50 { background-color: ${shades[50]} !important; }
|
||||
.theme-custom .bg-primary-100 { background-color: ${shades[100]} !important; }
|
||||
.theme-custom .bg-primary-200 { background-color: ${shades[200]} !important; }
|
||||
.theme-custom .bg-primary-300 { background-color: ${shades[300]} !important; }
|
||||
.theme-custom .bg-primary-400 { background-color: ${shades[400]} !important; }
|
||||
.theme-custom .bg-primary-500 { background-color: ${shades[500]} !important; }
|
||||
.theme-custom .bg-primary-600 { background-color: ${shades[600]} !important; }
|
||||
.theme-custom .bg-primary-700 { background-color: ${shades[700]} !important; }
|
||||
.theme-custom .bg-primary-800 { background-color: ${shades[800]} !important; }
|
||||
.theme-custom .bg-primary-900 { background-color: ${shades[900]} !important; }
|
||||
body[data-theme="${hex}"] {
|
||||
--primary: ${shades[600]};
|
||||
--primary-foreground: ${shades[50]};
|
||||
--ring: ${shades[400]};
|
||||
--chart-1: ${shades[300]};
|
||||
--chart-2: ${shades[500]};
|
||||
--chart-3: ${shades[600]};
|
||||
--chart-4: ${shades[700]};
|
||||
--chart-5: ${shades[800]};
|
||||
--sidebar-primary: ${shades[600]};
|
||||
--sidebar-primary-foreground: ${shades[50]};
|
||||
--sidebar-accent: ${shades[50]};
|
||||
--sidebar-accent-foreground: ${shades[700]};
|
||||
--sidebar-ring: ${shades[400]};
|
||||
}
|
||||
|
||||
.theme-custom .text-primary-50 { color: ${shades[50]} !important; }
|
||||
.theme-custom .text-primary-100 { color: ${shades[100]} !important; }
|
||||
.theme-custom .text-primary-200 { color: ${shades[200]} !important; }
|
||||
.theme-custom .text-primary-300 { color: ${shades[300]} !important; }
|
||||
.theme-custom .text-primary-400 { color: ${shades[400]} !important; }
|
||||
.theme-custom .text-primary-500 { color: ${shades[500]} !important; }
|
||||
.theme-custom .text-primary-600 { color: ${shades[600]} !important; }
|
||||
.theme-custom .text-primary-700 { color: ${shades[700]} !important; }
|
||||
.theme-custom .text-primary-800 { color: ${shades[800]} !important; }
|
||||
.theme-custom .text-primary-900 { color: ${shades[900]} !important; }
|
||||
|
||||
.theme-custom .border-primary-50 { border-color: ${shades[50]} !important; }
|
||||
.theme-custom .border-primary-100 { border-color: ${shades[100]} !important; }
|
||||
.theme-custom .border-primary-200 { border-color: ${shades[200]} !important; }
|
||||
.theme-custom .border-primary-300 { border-color: ${shades[300]} !important; }
|
||||
.theme-custom .border-primary-400 { border-color: ${shades[400]} !important; }
|
||||
.theme-custom .border-primary-500 { border-color: ${shades[500]} !important; }
|
||||
.theme-custom .border-primary-600 { border-color: ${shades[600]} !important; }
|
||||
.theme-custom .border-primary-700 { border-color: ${shades[700]} !important; }
|
||||
.theme-custom .border-primary-800 { border-color: ${shades[800]} !important; }
|
||||
.theme-custom .border-primary-900 { border-color: ${shades[900]} !important; }
|
||||
body.dark[data-theme="${hex}"],
|
||||
html.dark body[data-theme="${hex}"] {
|
||||
--primary: ${shades[500]};
|
||||
--primary-foreground: ${shades[50]};
|
||||
--ring: ${shades[900]};
|
||||
--sidebar-primary: ${shades[500]};
|
||||
--sidebar-primary-foreground: ${shades[50]};
|
||||
--sidebar-accent: oklch(0.268 0.007 34.298);
|
||||
--sidebar-accent-foreground: ${shades[500]};
|
||||
--sidebar-ring: ${shades[900]};
|
||||
}
|
||||
`;
|
||||
|
||||
if (styleElement) {
|
||||
styleElement.innerHTML = styleContent;
|
||||
} else {
|
||||
styleElement = document.createElement('style');
|
||||
styleElement.id = styleId;
|
||||
styleElement.innerHTML = styleContent;
|
||||
document.head.appendChild(styleElement);
|
||||
}
|
||||
const styleElement = document.createElement('style');
|
||||
styleElement.innerHTML = styleContent;
|
||||
document.head.appendChild(styleElement);
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ export function tc<T>(tryFunc: () => T, catchFunc: T | ((e?: Error) => T)) {
|
||||
val = tryFunc();
|
||||
} catch (e: unknown) {
|
||||
if (typeof catchFunc === 'function') {
|
||||
// @ts-ignore
|
||||
// @ts-expect-error - catchFunc is a function
|
||||
val = catchFunc(e);
|
||||
} else {
|
||||
val = catchFunc;
|
||||
|
||||
Reference in New Issue
Block a user