├── src ├── routes │ ├── auth │ │ ├── +page.svelte │ │ ├── login │ │ │ ├── +page.server.ts │ │ │ └── +page.svelte │ │ ├── success │ │ │ └── +page.svelte │ │ ├── create-account │ │ │ ├── +page.server.ts │ │ │ └── +page.svelte │ │ └── forgot-password │ │ │ └── +page.svelte │ ├── dashboard │ │ ├── +page.svelte │ │ ├── [slug] │ │ │ ├── +page.ts │ │ │ ├── [subslug] │ │ │ │ ├── +page.ts │ │ │ │ └── +page.svelte │ │ │ └── +page.svelte │ │ ├── +layout.server.ts │ │ └── +layout.svelte │ ├── +layout.server.ts │ ├── +layout.svelte │ └── +page.svelte ├── lib │ ├── index.ts │ ├── supabase.ts │ └── leftnavoptions │ │ ├── Title1.svelte │ │ ├── SectionsMinimal.svelte │ │ ├── SectionsUI.svelte │ │ ├── Avatar.svelte │ │ ├── SectionsIcons.svelte │ │ ├── SectionsLine.svelte │ │ └── LeftAlert.svelte ├── app.css ├── stores │ ├── navigation.ts │ └── leftNavData.ts ├── app.html └── app.d.ts ├── .npmrc ├── .prettierignore ├── static ├── favicon.png ├── forest.jpg └── productimage.png ├── postcss.config.js ├── .prettierrc ├── vite.config.ts ├── .gitignore ├── tsconfig.json ├── svelte.config.js ├── README.md ├── tailwind.config.ts └── package.json /src/routes/auth/+page.svelte: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.npmrc: -------------------------------------------------------------------------------- 1 | engine-strict=true 2 | -------------------------------------------------------------------------------- /.prettierignore: -------------------------------------------------------------------------------- 1 | # Package Managers 2 | package-lock.json 3 | pnpm-lock.yaml 4 | yarn.lock 5 | -------------------------------------------------------------------------------- /src/lib/index.ts: -------------------------------------------------------------------------------- 1 | // place files you want to import through the `$lib` alias in this folder. 2 | -------------------------------------------------------------------------------- /static/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomaslappenbusch/svelte-5-dashboard/HEAD/static/favicon.png -------------------------------------------------------------------------------- /static/forest.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomaslappenbusch/svelte-5-dashboard/HEAD/static/forest.jpg -------------------------------------------------------------------------------- /postcss.config.js: -------------------------------------------------------------------------------- 1 | export default { 2 | plugins: { 3 | tailwindcss: {}, 4 | autoprefixer: {} 5 | } 6 | }; 7 | -------------------------------------------------------------------------------- /src/app.css: -------------------------------------------------------------------------------- 1 | @import 'tailwindcss/base'; 2 | @import 'tailwindcss/components'; 3 | @import 'tailwindcss/utilities'; 4 | -------------------------------------------------------------------------------- /src/stores/navigation.ts: -------------------------------------------------------------------------------- 1 | import { writable } from 'svelte/store'; 2 | 3 | export const isNavOpen = writable(true); -------------------------------------------------------------------------------- /static/productimage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/thomaslappenbusch/svelte-5-dashboard/HEAD/static/productimage.png -------------------------------------------------------------------------------- /src/lib/supabase.ts: -------------------------------------------------------------------------------- 1 | import { createClient } from '@supabase/supabase-js' 2 | 3 | export const supabase = createClient( 4 | import.meta.env.VITE_SUPABASE_URL, 5 | import.meta.env.VITE_SUPABASE_ANON_KEY 6 | ) -------------------------------------------------------------------------------- /src/routes/dashboard/+page.svelte: -------------------------------------------------------------------------------- 1 |
2 |
Choose a section to get started.
3 |
4 | -------------------------------------------------------------------------------- /src/routes/dashboard/[slug]/+page.ts: -------------------------------------------------------------------------------- 1 | // @ts-nocheck 2 | import { error } from '@sveltejs/kit'; 3 | import type { PageLoad } from './$types'; 4 | 5 | export const load: PageLoad = ({ params }:any) => { 6 | return { 7 | slug: params.slug 8 | }; 9 | }; -------------------------------------------------------------------------------- /.prettierrc: -------------------------------------------------------------------------------- 1 | { 2 | "useTabs": true, 3 | "singleQuote": true, 4 | "trailingComma": "none", 5 | "printWidth": 100, 6 | "plugins": ["prettier-plugin-svelte"], 7 | "overrides": [ 8 | { 9 | "files": "*.svelte", 10 | "options": { 11 | "parser": "svelte" 12 | } 13 | } 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /vite.config.ts: -------------------------------------------------------------------------------- 1 | import { sveltekit } from '@sveltejs/kit/vite'; 2 | import Icons from 'unplugin-icons/vite' 3 | import { defineConfig } from 'vite'; 4 | 5 | export default defineConfig({ 6 | plugins: [sveltekit(), 7 | Icons({ 8 | compiler: 'svelte', 9 | autoInstall: true, 10 | }) 11 | ] 12 | }); 13 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | 3 | # Output 4 | .output 5 | .vercel 6 | .netlify 7 | .wrangler 8 | /.svelte-kit 9 | /build 10 | 11 | # OS 12 | .DS_Store 13 | Thumbs.db 14 | 15 | # Env 16 | .env 17 | .env.* 18 | !.env.example 19 | !.env.test 20 | 21 | # Vite 22 | vite.config.js.timestamp-* 23 | vite.config.ts.timestamp-* 24 | -------------------------------------------------------------------------------- /src/routes/dashboard/[slug]/[subslug]/+page.ts: -------------------------------------------------------------------------------- 1 | import { error } from '@sveltejs/kit'; 2 | import type { PageLoad } from './$types'; 3 | 4 | export const load: PageLoad = ({ params }) => { 5 | return { 6 | slug: params.slug, 7 | subslug: params.subslug 8 | }; 9 | 10 | error(404, 'Route Not found'); 11 | }; -------------------------------------------------------------------------------- /src/routes/dashboard/[slug]/[subslug]/+page.svelte: -------------------------------------------------------------------------------- 1 | 6 | 7 |
8 |
The {data.subslug} section.
9 |
10 | -------------------------------------------------------------------------------- /src/app.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | %sveltekit.head% 8 | 9 | 10 |
%sveltekit.body%
11 | 12 | 13 | -------------------------------------------------------------------------------- /src/app.d.ts: -------------------------------------------------------------------------------- 1 | import type { Session, SupabaseClient, User } from '@supabase/supabase-js' 2 | 3 | declare global { 4 | namespace App { 5 | // interface Error {} 6 | interface Locals { 7 | supabase: SupabaseClient 8 | safeGetSession: () => Promise<{ session: Session | null; user: User | null }> 9 | session: Session | null 10 | user: User | null 11 | } 12 | interface PageData { 13 | session: Session | null 14 | } 15 | // interface PageState {} 16 | // interface Platform {} 17 | } 18 | } 19 | 20 | export {} -------------------------------------------------------------------------------- /src/routes/+layout.server.ts: -------------------------------------------------------------------------------- 1 | import type { LayoutServerLoad } from './$types'; 2 | import { supabase } from '$lib/supabase'; 3 | 4 | export const load: LayoutServerLoad = async () => { 5 | const { data: { session }, error } = await supabase.auth.getSession(); 6 | console.log('Root layout server session check:', session?.user); 7 | 8 | return { 9 | session, 10 | userData: { 11 | email: session?.user?.email, 12 | id: session?.user?.id, 13 | lastSignIn: session?.user?.last_sign_in_at, 14 | created: session?.user?.created_at 15 | } 16 | }; 17 | }; -------------------------------------------------------------------------------- /src/routes/+layout.svelte: -------------------------------------------------------------------------------- 1 | 25 | 26 | {@render children()} 27 | -------------------------------------------------------------------------------- /src/routes/dashboard/+layout.server.ts: -------------------------------------------------------------------------------- 1 | import type { LayoutServerLoad } from './$types'; 2 | import { supabase } from '$lib/supabase'; 3 | 4 | export const load = (async ({ depends }) => { 5 | // Tell Svelte to re-run this load function when auth changes 6 | depends('supabase:auth'); 7 | 8 | const { data: { session }, error } = await supabase.auth.getSession(); 9 | 10 | return { 11 | session, 12 | userData: { 13 | email: session?.user?.email, 14 | id: session?.user?.id, 15 | lastSignIn: session?.user?.last_sign_in_at, 16 | created: session?.user?.created_at 17 | } 18 | }; 19 | }) satisfies LayoutServerLoad; -------------------------------------------------------------------------------- /tsconfig.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": "./.svelte-kit/tsconfig.json", 3 | "compilerOptions": { 4 | "allowJs": true, 5 | "checkJs": true, 6 | "esModuleInterop": true, 7 | "forceConsistentCasingInFileNames": true, 8 | "resolveJsonModule": true, 9 | "skipLibCheck": true, 10 | "sourceMap": true, 11 | "strict": true, 12 | "moduleResolution": "bundler" 13 | } 14 | // Path aliases are handled by https://svelte.dev/docs/kit/configuration#alias 15 | // except $lib which is handled by https://svelte.dev/docs/kit/configuration#files 16 | // 17 | // If you want to overwrite includes/excludes, make sure to copy over the relevant includes/excludes 18 | // from the referenced tsconfig.json - TypeScript does not merge them in 19 | } 20 | -------------------------------------------------------------------------------- /svelte.config.js: -------------------------------------------------------------------------------- 1 | import adapter from '@sveltejs/adapter-auto'; 2 | import { vitePreprocess } from '@sveltejs/vite-plugin-svelte'; 3 | 4 | /** @type {import('@sveltejs/kit').Config} */ 5 | const config = { 6 | // Consult https://svelte.dev/docs/kit/integrations 7 | // for more information about preprocessors 8 | preprocess: vitePreprocess(), 9 | 10 | kit: { 11 | // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list. 12 | // If your environment is not supported, or you settled on a specific environment, switch out the adapter. 13 | // See https://svelte.dev/docs/kit/adapters for more information about adapters. 14 | adapter: adapter() 15 | } 16 | }; 17 | 18 | export default config; 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # svelte-5-dashboard - A Coastal UI boilerplate 2 | 3 | A powerful, customizable dashboard template built with modern technologies. Perfect for building your next admin panel, analytics dashboard, or SaaS platform. 4 | 5 | Join our growing community on [Discord](https://discord.gg/fB5uJYYD8E) for support, feature discussions, and updates! Also visit [Coastal UI](https://coastalui.com) to learn more about the components and such we work on. 6 | 7 | ## Tech Stack 8 | 9 | - **Svelte** - A radical new approach to building user interfaces 10 | - **Supabase** - Open source Firebase alternative 11 | - **Tailwind CSS** - A utility-first CSS framework 12 | - **TypeScript** - JavaScript that scales 13 | 14 | ## Getting Started 15 | 16 | ```bash 17 | # create a new project in the current directory 18 | npx sv create 19 | 20 | # create a new project in my-app 21 | npx sv create my-app 22 | -------------------------------------------------------------------------------- /src/routes/auth/login/+page.server.ts: -------------------------------------------------------------------------------- 1 | import { fail, redirect } from '@sveltejs/kit'; 2 | import type { Actions } from './$types'; 3 | import { supabase } from '$lib/supabase'; 4 | 5 | export const actions = { 6 | login: async ({ request }) => { 7 | const formData = await request.formData(); 8 | const email = String(formData.get('email')); 9 | const password = String(formData.get('password')); 10 | 11 | console.log('Attempting login with:', email); // Log the attempt 12 | 13 | const { data, error } = await supabase.auth.signInWithPassword({ 14 | email, 15 | password 16 | }); 17 | 18 | console.log('Login response:', { data, error }); // Log the response 19 | 20 | if (error) { 21 | return fail(400, { message: error.message }); 22 | } 23 | 24 | throw redirect(303, '/dashboard'); 25 | } 26 | } satisfies Actions; -------------------------------------------------------------------------------- /tailwind.config.ts: -------------------------------------------------------------------------------- 1 | import type { Config } from 'tailwindcss'; 2 | 3 | export default { 4 | content: ['./src/**/*.{html,js,svelte,ts}'], 5 | 6 | theme: { 7 | extend: { 8 | colors: { 9 | ui: { 10 | // Backgrounds - Lightened for better contrast 11 | bg: '#070707', // Main background 12 | 'bg-2': '#0A0A0A', // Slightly lighter 13 | 'bg-3': '#0D0D0D', // Just a touch lighter 14 | 15 | // Text - Enhanced contrast 16 | tx: '#FFFFFF', // Main text 17 | 'tx-2': '#CCCCCC', // Secondary text (significantly lightened) 18 | 'tx-3': '#A3A3A3', // Tertiary text (lightened more) 19 | 'tx-h': '#E5E5E5', // Hover text (very light) 20 | 'tx-subhead': '#F0F0F0', // Subheadings (almost white) 21 | 22 | // Borders - More visible 23 | br: '#2A2A2A', // Border 24 | 'br-h': '#363636', // Hover border 25 | 26 | // Accent 27 | ac: '#FFFFFF', // Accent color 28 | } 29 | } 30 | } 31 | }, 32 | 33 | plugins: [] 34 | } satisfies Config; -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "dash-boiler", 3 | "private": true, 4 | "version": "0.0.1", 5 | "type": "module", 6 | "scripts": { 7 | "dev": "vite dev", 8 | "build": "vite build", 9 | "preview": "vite preview", 10 | "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", 11 | "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", 12 | "format": "prettier --write .", 13 | "lint": "prettier --check ." 14 | }, 15 | "devDependencies": { 16 | "@iconify-json/cib": "^1.2.1", 17 | "@iconify-json/material-symbols-light": "^1.2.12", 18 | "@iconify-json/ri": "^1.2.1", 19 | "@sveltejs/adapter-auto": "^3.0.0", 20 | "@sveltejs/kit": "^2.9.0", 21 | "@sveltejs/vite-plugin-svelte": "^5.0.0", 22 | "autoprefixer": "^10.4.20", 23 | "prettier": "^3.3.2", 24 | "prettier-plugin-svelte": "^3.2.6", 25 | "svelte": "^5.0.0", 26 | "svelte-check": "^4.0.0", 27 | "tailwindcss": "^3.4.9", 28 | "typescript": "^5.0.0", 29 | "unplugin-icons": "^0.22.0", 30 | "vite": "^6.0.0" 31 | }, 32 | "dependencies": { 33 | "@supabase/ssr": "^0.5.2", 34 | "@supabase/supabase-js": "^2.47.10", 35 | "lucide-svelte": "^0.468.0" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /src/routes/auth/success/+page.svelte: -------------------------------------------------------------------------------- 1 | 5 | 6 |
7 |
SvelteDashboard
8 |
9 |
10 | 11 | 12 | 13 |
14 |
Account Created!
15 |
Your account has been successfully created. You can now access the dashboard.
16 | 21 |
22 |
-------------------------------------------------------------------------------- /src/routes/auth/create-account/+page.server.ts: -------------------------------------------------------------------------------- 1 | import { fail, redirect } from '@sveltejs/kit'; 2 | import type { Actions } from './$types'; 3 | import { supabase } from '$lib/supabase'; 4 | 5 | export const actions = { 6 | emailSignUp: async ({ request }) => { 7 | const formData = await request.formData(); 8 | const email = String(formData.get('email')); 9 | const password = String(formData.get('password')); 10 | 11 | // Create account with email confirmation disabled 12 | const { data: signUpData, error: signUpError } = await supabase.auth.signUp({ 13 | email, 14 | password, 15 | options: { 16 | data: { 17 | email_confirmed: true 18 | } 19 | } 20 | }); 21 | 22 | if (signUpError) { 23 | console.error('Signup Error:', signUpError); 24 | return fail(400, { message: signUpError.message }); 25 | } 26 | 27 | // Sign them in immediately 28 | const { data: signInData, error: signInError } = await supabase.auth.signInWithPassword({ 29 | email, 30 | password 31 | }); 32 | 33 | if (signInError) { 34 | console.error('SignIn Error:', signInError); 35 | return fail(400, { message: signInError.message }); 36 | } 37 | 38 | console.log('Successfully signed in:', signInData); 39 | throw redirect(303, '/auth/success'); 40 | } 41 | } satisfies Actions; -------------------------------------------------------------------------------- /src/lib/leftnavoptions/Title1.svelte: -------------------------------------------------------------------------------- 1 | 25 | 26 |
27 | {#if $isNavOpen} 28 |
33 |
34 | SvelteDashboard 35 |
36 |
37 | {:else} 38 |
39 | {/if} 40 |
41 | 42 | 54 |
-------------------------------------------------------------------------------- /src/routes/auth/forgot-password/+page.svelte: -------------------------------------------------------------------------------- 1 | 8 | 9 |
10 |
SvelteDashboard
11 |
12 |
Reset password
13 |
Enter your email address and we'll send you instructions to reset your password.
14 | 15 | {#if !success} 16 |
17 |
Email
18 | 23 |
24 |
25 | {#if error} 26 |
Error: {error}
27 | {/if} 28 | 31 |
32 | {:else} 33 |
34 | Check your email for password reset instructions. 35 |
36 | {/if} 37 | 38 |
39 | Remember your password? 40 |
41 |
42 |
-------------------------------------------------------------------------------- /src/routes/dashboard/[slug]/+page.svelte: -------------------------------------------------------------------------------- 1 | 58 | 59 |
60 |
61 | The {data.slug} section. 62 |
63 | 64 | 70 |
-------------------------------------------------------------------------------- /src/lib/leftnavoptions/SectionsMinimal.svelte: -------------------------------------------------------------------------------- 1 | 22 | 23 | {#if $isNavOpen} 24 |
29 | {#each allItems as item} 30 | 54 | {/each} 55 |
56 | {/if} -------------------------------------------------------------------------------- /src/lib/leftnavoptions/SectionsUI.svelte: -------------------------------------------------------------------------------- 1 | 16 | 17 | {#if $isNavOpen} 18 |
19 | {#each data as section, sectionIndex} 20 |
21 | 22 | {#if sectionIndex !== 0} 23 |
24 | {section.title} 25 |
26 | {/if} 27 | 28 | 29 |
30 | {#each section.items as item} 31 | {@const route = `/dashboard/${item.title.toLowerCase().replace(' ', '-')}`} 32 | 49 | {/each} 50 |
51 |
52 | {/each} 53 |
54 | {/if} -------------------------------------------------------------------------------- /src/lib/leftnavoptions/Avatar.svelte: -------------------------------------------------------------------------------- 1 | 33 | 34 | 35 |
36 |
37 | currentUser 42 | {#if data.statusColor} 43 |
44 | {/if} 45 |
46 | {#if $isNavOpen} 47 |
48 |
thomaslappenbusch@gmail.com
49 |
50 | 57 |
58 |
59 | {/if} 60 |
-------------------------------------------------------------------------------- /src/lib/leftnavoptions/SectionsIcons.svelte: -------------------------------------------------------------------------------- 1 | 33 | 34 | {#each leftNavData as section, sectionIndex} 35 |
0 ? 'mt-8' : ''}`}> 36 |
37 |
38 | 39 | {section.title} 40 | 41 |
42 |
43 | {#each section.items as text, itemIndex} 44 | {@const route = generateRoute(section.title, text)} 45 | 62 | {/each} 63 |
64 | {/each} -------------------------------------------------------------------------------- /src/lib/leftnavoptions/SectionsLine.svelte: -------------------------------------------------------------------------------- 1 | 31 | 32 | {#if $isNavOpen} 33 |
38 | {#each data as section, sectionIndex} 39 |
40 |
0 ? 'mt-5' : ''} text-ui-tx-subhead`}> 41 | {section.title} 42 |
43 | {#each section.items as item, itemIndex} 44 | {@const route = generateRoute(section.title, item)} 45 | 73 | {/each} 74 |
75 | {/each} 76 |
77 | {/if} -------------------------------------------------------------------------------- /src/stores/leftNavData.ts: -------------------------------------------------------------------------------- 1 | import { writable } from 'svelte/store'; 2 | 3 | export interface Alert { 4 | id: number; 5 | leftIcon: "avatar" | "warning" | "hazard"; 6 | size: "small"; 7 | title: string; 8 | description: string; 9 | interaction?: string; 10 | } 11 | 12 | export interface NavDataType { 13 | title: { 14 | string: string; 15 | logo?: any; // Can be SVG string or URL 16 | }; 17 | sections: { 18 | title: string; 19 | items: { 20 | title: string; 21 | totalNotifications: number; 22 | }[]; 23 | }[]; 24 | alerts: Alert[]; 25 | profile: { 26 | username: string; 27 | line: string; 28 | statusColor: string; 29 | }; 30 | } 31 | 32 | 33 | const createNavStore = () => { 34 | const { subscribe, set, update } = writable({ 35 | title: { 36 | string: "Svelte5", 37 | logo: '' 38 | }, 39 | sections: [ 40 | { 41 | title: "Dashboard", 42 | items: [ 43 | { title: "Home", totalNotifications: 0 }, 44 | { title: "Analytics", totalNotifications: 0 }, 45 | { title: "Reports", totalNotifications: 0 } 46 | ] 47 | }, 48 | { 49 | title: "System", 50 | items: [ 51 | { title: "Performance", totalNotifications: 0 }, 52 | { title: "Monitoring", totalNotifications: 0 }, 53 | { title: "Logs", totalNotifications: 0 } 54 | ] 55 | } 56 | ], 57 | alerts: [ 58 | { 59 | id: 0, 60 | leftIcon: "avatar", 61 | size: "small", 62 | title: "Aspen Septimus", 63 | description: "3 new messages.", 64 | interaction: "open chat" 65 | }, 66 | { 67 | id: 1, 68 | leftIcon: "warning", 69 | size: "small", 70 | title: "Error", 71 | description: "Payment processing." 72 | }, 73 | { 74 | id: 2, 75 | leftIcon: "hazard", 76 | size: "small", 77 | title: "Warning", 78 | description: "You need to update your info." 79 | } 80 | ], 81 | profile: { 82 | username: "", 83 | line: "WWU 2023", 84 | statusColor: "bg-green-600" 85 | } 86 | }); 87 | 88 | return { 89 | subscribe, 90 | setProfile: (username: string) => update(data => ({ 91 | ...data, 92 | profile: { ...data.profile, username } 93 | })), 94 | addAlert: (alert: Omit) => update(data => { 95 | const newAlert = { 96 | ...alert, 97 | id: Math.max(0, ...data.alerts.map(a => a.id)) + 1 98 | }; 99 | return { 100 | ...data, 101 | alerts: [newAlert, ...data.alerts] 102 | }; 103 | }), 104 | deleteAlert: (id: number) => update(data => { 105 | console.log('Store: Deleting alert', id); 106 | console.log('Current alerts:', data.alerts); 107 | const newAlerts = data.alerts.filter(alert => alert.id !== id); 108 | console.log('New alerts:', newAlerts); 109 | return { 110 | ...data, 111 | alerts: newAlerts 112 | }; 113 | }) 114 | }; 115 | }; 116 | 117 | export const navStore = createNavStore(); -------------------------------------------------------------------------------- /src/lib/leftnavoptions/LeftAlert.svelte: -------------------------------------------------------------------------------- 1 | 24 | 25 | {#if size === "small"} 26 |
29 |
33 |
34 | 35 | 41 | 42 |
43 | {#if leftIcon === "warning"} 44 | 45 | 46 | 47 | {:else if leftIcon === "hazard"} 48 | 49 | 50 | 51 | {:else if leftIcon === "avatar"} 52 | User avatar 57 | {:else if leftIcon === "success"} 58 | 59 | 60 | 61 | {:else if leftIcon === "download"} 62 | 63 | 64 | 65 | {:else if leftIcon === "sync"} 66 | 67 | 68 | 69 | {/if} 70 |
71 | 72 |
73 | {#if $isNavOpen} 74 |
79 | {title} 80 |
81 |
86 | {description} 87 |
88 | {/if} 89 |
90 |
91 |
92 | {/if} -------------------------------------------------------------------------------- /src/routes/auth/create-account/+page.svelte: -------------------------------------------------------------------------------- 1 | 48 | 49 |
50 |
SvelteDashboard
51 |
52 |
Create an account
53 |
54 | Already have an account? 55 | 62 |
63 | 64 |
65 |
66 |
Email
67 | 75 |
76 | 77 |
78 |
Password
79 | 87 |
88 | 89 |
90 |
Confirm Password
91 | 98 |
99 | 100 |
101 |
102 |
103 | {#if hasEightChars} 104 | 105 | 106 | 107 | {/if} 108 |
109 |
8 or more characters
110 |
111 | 112 |
113 |
114 | {#if hasSpecialChar} 115 | 116 | 117 | 118 | {/if} 119 |
120 |
One special character
121 |
122 |
123 | 124 |
125 | {#if error} 126 |
Error: {error}
127 | {/if} 128 | 139 |
140 |
141 |
142 |
-------------------------------------------------------------------------------- /src/routes/auth/login/+page.svelte: -------------------------------------------------------------------------------- 1 | 34 | 35 |
36 |
SvelteDashboard
37 |
38 |
Welcome back
39 |
40 | New to SvelteDashboard? 41 | 48 |
49 | 50 |
56 |
57 |
Email
58 | 66 |
67 | 68 |
69 |
Password
70 | 77 |
78 | 79 |
80 |
81 | 87 |
Remember me
88 |
89 | 96 |
97 | 98 |
99 | {#if error} 100 |
Error: {error}
101 | {/if} 102 | 113 |
114 |
115 | 116 |
117 |
118 |
OR
119 |
120 |
121 | 122 | 126 | 127 | 131 |
132 |
-------------------------------------------------------------------------------- /src/routes/dashboard/+layout.svelte: -------------------------------------------------------------------------------- 1 | 42 | 43 | {#if data?.session} 44 |
45 |
48 | 49 |
50 | 51 |
52 |
53 | {#each $navStore.alerts as item (item.id)} 54 |
59 | 60 | 66 |
74 | 75 | 76 |
77 | {#if item.leftIcon === "warning"} 78 | 79 | 80 | 81 | {:else if item.leftIcon === "hazard"} 82 | 83 | 84 | 85 | {:else if item.leftIcon === "avatar"} 86 | User avatar 91 | {:else if item.leftIcon === "success"} 92 | 93 | {:else if item.leftIcon === "download"} 94 | 95 | 96 | 97 | {:else if item.leftIcon === "sync"} 98 | 99 | 100 | 101 | {/if} 102 |
103 | 104 | 105 |
106 | {#if $isNavOpen} 107 |
112 | {item.title} 113 |
114 |
119 | {item.description} 120 | {#if item.interaction} 121 | 124 | {/if} 125 |
126 | {/if} 127 |
128 |
129 | {/each} 130 |
131 | 132 |
133 |
138 |
139 | {@render children()} 140 |
141 |
142 |
143 | {:else} 144 | 147 | {/if} -------------------------------------------------------------------------------- /src/routes/+page.svelte: -------------------------------------------------------------------------------- 1 | 8 | 9 |
10 |
11 | 12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 | 23 | 24 |
25 | 26 | 29 |
30 |
31 |
32 |
33 |
34 |
35 | 36 |
CoastalUI
37 |
38 |
39 | Svelte 5 40 |
41 |
42 | Dashboard Boilerplates 43 |
44 |
45 | 50 | 63 |
64 |
65 | 68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 | 78 |
79 |
80 |
Supabase Integration
81 |
Secure database and authentication, ready to deploy.
82 |
83 |
84 | 85 |
86 |
87 | 88 |
89 |
90 |
Stripe Payments
91 |
Subscription system configured and ready to use.
92 |
93 |
94 | 95 |
96 |
97 |
98 |
99 |
Dashboard Navigation
100 |
Professional dashboard layout with only navigation built-in.
101 |
102 |
103 | 104 |
105 |
106 | 107 |
108 |
109 |
Authentication Routes
110 |
Everything from /login to /reset-password.
111 |
112 |
113 | 114 |
115 |
116 | 117 |
118 |
119 |
Tailwind Config Styling
120 |
Easily change from one color scheme to another.
121 |
122 |
123 | 124 |
125 |
126 | 127 |
128 |
129 |
Always Free
130 |
No hidden costs or premium features. Everything included.*
131 |
132 |
133 |
134 |
135 |
136 |
137 |
138 |
139 |
Get Inspired
140 |
141 |
142 | Dashboard Build-out Showcase 143 |
144 |
145 |
146 |
147 |
148 |
149 |
150 | 154 | 155 |
156 |
157 |
158 |
159 | 163 | 164 |
165 |
166 |
167 |
168 | 172 | 173 |
174 |
175 |
176 |
177 |
178 |
179 |
180 |
181 |
182 |

SvelteDashboard

183 |

A dashboard boilerplate built with Svelte 5, Tailwind CSS, TypeScript and Supabase.

184 |
185 | 191 | 197 | 200 |
201 |
202 | 205 |
206 | 207 |
208 |
209 |

© 2024 CoastalUI. All rights reserved.

210 |

A CoastalUI Project

211 |
212 |
213 |
214 |
215 | --------------------------------------------------------------------------------