Showing preview only (388K chars total). Download the full file or copy to clipboard to get everything.
Repository: daison12006013/sveltekit-starter
Branch: develop
Commit: e761b9f39463
Files: 118
Total size: 357.1 KB
Directory structure:
gitextract_2mqan8mg/
├── .env.example
├── .eslintignore
├── .eslintrc.cjs
├── .gitignore
├── .npmrc
├── .nvmrc
├── .prettierignore
├── .prettierrc
├── README.md
├── guides/
│ └── laravel-sanctum.md
├── package.json
├── playwright.config.ts
├── postcss.config.cjs
├── run
├── src/
│ ├── app.css
│ ├── app.d.ts
│ ├── app.html
│ ├── hooks/
│ │ ├── laravel-sanctum-fake-logged-in.ts
│ │ ├── laravel-sanctum-fake-logged-out.ts
│ │ ├── laravel-sanctum.ts
│ │ └── sveltekit-default.ts
│ ├── lib/
│ │ ├── Counter.svelte
│ │ ├── components/
│ │ │ ├── Accordion.svelte
│ │ │ ├── AccordionItem.svelte
│ │ │ ├── Alert.svelte
│ │ │ ├── Badge.svelte
│ │ │ ├── Breadcrumb.svelte
│ │ │ ├── ButtonGroup.svelte
│ │ │ ├── Buttons.svelte
│ │ │ ├── Card.svelte
│ │ │ ├── Carousel.svelte
│ │ │ ├── CloseButton.svelte
│ │ │ ├── Code.svelte
│ │ │ ├── Collapse.svelte
│ │ │ ├── Docs/
│ │ │ │ ├── DocAccordion.svelte
│ │ │ │ ├── DocAlert.svelte
│ │ │ │ └── DocBadge.svelte
│ │ │ ├── Dropdowns.svelte
│ │ │ ├── ListGroup.svelte
│ │ │ ├── Modal.svelte
│ │ │ ├── NavsAndTabs.svelte
│ │ │ ├── Pagination.svelte
│ │ │ ├── Popovers.svelte
│ │ │ ├── Spinners.svelte
│ │ │ ├── Toasts.svelte
│ │ │ └── Tooltips.svelte
│ │ ├── form.ts
│ │ ├── header/
│ │ │ └── Header.svelte
│ │ ├── ioevents/
│ │ │ ├── click.ts
│ │ │ └── keydown.ts
│ │ ├── tailwind.css
│ │ ├── templates/
│ │ │ ├── Admin/
│ │ │ │ ├── API/
│ │ │ │ │ └── form.ts
│ │ │ │ ├── Config/
│ │ │ │ │ └── charts.ts
│ │ │ │ ├── Header.svelte
│ │ │ │ ├── SideBar.svelte
│ │ │ │ └── ToggleTheme.svelte
│ │ │ └── Blog/
│ │ │ ├── Config/
│ │ │ │ ├── links.json
│ │ │ │ └── particle.json
│ │ │ ├── Header.svelte
│ │ │ ├── Particles/
│ │ │ │ ├── Particles.svelte
│ │ │ │ ├── global.d.ts
│ │ │ │ ├── index.d.ts
│ │ │ │ └── index.ts
│ │ │ └── SideBar.svelte
│ │ └── translator.ts
│ ├── routes/
│ │ ├── admin/
│ │ │ ├── (authenticated)/
│ │ │ │ ├── +layout.svelte
│ │ │ │ ├── +page.svelte
│ │ │ │ ├── buttons/
│ │ │ │ │ └── +page.svelte
│ │ │ │ ├── cards/
│ │ │ │ │ └── +page.svelte
│ │ │ │ ├── charts/
│ │ │ │ │ └── +page.svelte
│ │ │ │ ├── components/
│ │ │ │ │ └── +page.svelte
│ │ │ │ ├── forms/
│ │ │ │ │ └── +page.svelte
│ │ │ │ ├── modals/
│ │ │ │ │ └── +page.svelte
│ │ │ │ └── tables/
│ │ │ │ └── +page.svelte
│ │ │ ├── (guest)/
│ │ │ │ ├── +layout.svelte
│ │ │ │ ├── auth/
│ │ │ │ │ ├── login/
│ │ │ │ │ │ ├── +page.server.ts
│ │ │ │ │ │ └── +page.svelte
│ │ │ │ │ └── logout/
│ │ │ │ │ └── +page.server.ts
│ │ │ │ ├── forgot-password/
│ │ │ │ │ └── +page.svelte
│ │ │ │ └── register/
│ │ │ │ └── +page.svelte
│ │ │ ├── +error.svelte
│ │ │ ├── +layout.server.ts
│ │ │ └── html_head.svelte
│ │ ├── api.ts
│ │ ├── blog/
│ │ │ ├── +layout.svelte
│ │ │ ├── +page.svelte
│ │ │ └── resume/
│ │ │ └── +page.svelte
│ │ └── demo/
│ │ ├── +layout.svelte
│ │ ├── +page.svelte
│ │ ├── +page.ts
│ │ ├── Counter.svelte
│ │ ├── Header.svelte
│ │ ├── about/
│ │ │ ├── +page.svelte
│ │ │ └── +page.ts
│ │ ├── styles.css
│ │ └── sverdle/
│ │ ├── +page.server.ts
│ │ ├── +page.svelte
│ │ ├── game.test.ts
│ │ ├── game.ts
│ │ ├── how-to-play/
│ │ │ ├── +page.svelte
│ │ │ └── +page.ts
│ │ ├── reduced-motion.ts
│ │ └── words.server.ts
│ ├── service-worker.ts
│ └── stores/
│ └── menus.ts
├── start/
│ ├── route.js
│ ├── tailwind/
│ │ ├── admin.cjs
│ │ ├── daisy-ui.cjs
│ │ └── index.cjs
│ └── vite/
│ ├── default.vite.config.js
│ └── index.js
├── static/
│ ├── manifest.json
│ └── robots.txt
├── svelte.config.js
├── tailwind.config.cjs
├── tests/
│ └── demo.ts
├── tsconfig.json
└── vite.config.js
================================================
FILE CONTENTS
================================================
================================================
FILE: .env.example
================================================
VITE_APP_NAME="Project Name"
VITE_BASE_API="http://api.local"
VITE_SESSION_NAME="laravel_session"
# url path
VITE_LOGIN_PATH="/auth/login"
VITE_LOGOUT_PATH="/auth/logout"
================================================
FILE: .eslintignore
================================================
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock
================================================
FILE: .eslintrc.cjs
================================================
module.exports = {
root: true,
parser: '@typescript-eslint/parser',
extends: ['eslint:recommended', 'plugin:@typescript-eslint/recommended', 'prettier'],
plugins: ['svelte3', '@typescript-eslint'],
ignorePatterns: ['*.cjs'],
overrides: [{ files: ['*.svelte'], processor: 'svelte3/svelte3' }],
settings: {
'svelte3/typescript': () => require('typescript'),
},
parserOptions: {
sourceType: 'module',
ecmaVersion: 2020,
},
env: {
browser: true,
es2017: true,
node: true,
},
}
================================================
FILE: .gitignore
================================================
.vscode
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
.vercel
.output
/functions
/.vercel_build_output
/.idea
/vite.config.js.timestamp*
================================================
FILE: .npmrc
================================================
engine-strict=true
================================================
FILE: .nvmrc
================================================
v16.14.2
================================================
FILE: .prettierignore
================================================
.DS_Store
node_modules
/build
/.svelte-kit
/package
.env
.env.*
!.env.example
# Ignore files for PNPM, NPM and YARN
pnpm-lock.yaml
package-lock.json
yarn.lock
================================================
FILE: .prettierrc
================================================
{
"useTabs": true,
"singleQuote": true,
"trailingComma": "none",
"printWidth": 100,
"pluginSearchDirs": ["."],
"overrides": [{ "files": "*.svelte", "options": { "parser": "svelte" } }],
"semi": false
}
================================================
FILE: README.md
================================================
# SvelteKit Projects
- [./run and src/route.js](#run-and-srcroutejs)
- [Playwright Test Cases](#playwright-test-cases)
- [Demo](#demo)
- [Framework Specific Guidelines](#framework-specific-guidelines)
- [Disclaimer](#disclaimer)
The copy of this branch should have at least the `v1.15.10` of `@sveltejs/kit`
## ./run and src/route.js
Dynamic way of serving the `./src/routes/admin`, we've added a condition inside our `start/route.js` to pre-determine the folder we want.
```bash
# this demonstrates a fake logged in
$> ./run admin dev
$> ./run admin-in dev
# this demonstrates a fake logged out
$> ./run admin-out dev
# this connects to your laravel sanctum
$> ./run admin-laravel-sanctum dev
```
The above command is similar to what it looks like below
```bash
$> ROUTE_FOLDER=admin npm run dev
```
We've stored more route projects, such as the original `demo` of sveltekit and my own resumé `blog`
```bash
# this demonstrates my bio and resumé
$> ./run blog dev
# this demonstrates the original sveltekit counter + todo
$> ./run demo dev
```
## Playwright Test Cases
When writing a test cases, rule of thumb is to name your tests with/by specific words, such as **"demo:"**
```js
// tests/demo.js
test('demo: about page has expected h1', async ({ page }) => {
// ...
});
```
Then you can run specific folders by executing it this way
```bash
./run demo test -- -g "demo:"
```
## Demo
- [Admin logged-in](https://sveltekit-windmill-admin.vercel.app/)
- [Admin logged-out](https://sveltekit-windmill-admin-out.vercel.app/)
- [Bio / Resumé](https://daison.vercel.app/)
## Framework Specific Guidelines
- [Setup Laravel Sanctum](/guides/laravel-sanctum.md)
- ***You have backend framework? Add your sveltekit guidelines here!***
## Disclaimer
- (Admin UI) Most of the design was based originally from [Estevan Maito's](https://github.com/estevanmaito/windmill-dashboard)
## Project Sponsors
- https://formatterjson.com/
- https://jsonlinter.com/
================================================
FILE: guides/laravel-sanctum.md
================================================
# SvelteKit + Laravel Sanctum Setup
Install sanctum under your laravel
```bash
laravel/ :~$ composer require laravel/sanctum
```
Add a new route group under your `app/Http/Kernel.php`
```php
'api' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
```
Under `routes/api.php`
```php
Route::middleware('auth:sanctum')->group(['middleware' => 'auth:sanctum'], function () {
Route::post('/login', function (Request $request) {
$credentials = $request->validate([
'email' => ['required', 'email'],
'password' => ['required'],
]);
return response()->json(['authenticated' => Auth::attempt($credentials)]);
});
Route::get('/logged-in', function (Request $request) {
return response()->json([
'user' => $request->user()->only('id', 'email', 'first_name', 'last_name', 'image'),
]);
});
Route::match(['get', 'post'], '/logout', function (Request $request) {
\Illuminate\Support\Facades\Auth::logout();
return response()->json(['authenticated' => false]);
});
});
```
The above code, we serve 3 routes, that is `/login`, `/logged-in` and `/logout`
## SvelteKit Starter Configuration
Update the `hooks` inside **svelte.config.js**
```diff
- hooks: `src/hooks/laravel-sanctum-fake-logged-in.ts`,
+ hooks: `src/hooks/laravel-sanctum.ts`,
```
Copy `.env.example` and make it `.env`
```bash
sveltekit-starter/ :~$ cp .env.example .env
```
Then update the `VITE_BASE_API` based on your laravel url.
### How the hooks work?
To explain about `laravel-sanctum.js` file
- it will check if there are `locals.user` loaded, or else it fetches to your laravel endpoint `/logged-in` and passing the **user** object inside **locals.user**
- then, if `laravel_session` does not exists, it will fetch `/sanctum/csrf-cookie` and sets the cookie
================================================
FILE: package.json
================================================
{
"name": "sveltekit-starter",
"version": "0.0.1",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"test": "playwright test",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"test:unit": "vitest",
"lint": "prettier --plugin-search-dir . --check . && eslint .",
"format": "prettier --plugin-search-dir . --write ."
},
"devDependencies": {
"@fontsource/fira-mono": "^4.5.10",
"@neoconfetti/svelte": "^1.0.0",
"@playwright/test": "^1.28.1",
"@sveltejs/adapter-auto": "^2.0.0",
"@sveltejs/kit": "^1.5.0",
"@types/cookie": "^0.5.1",
"@typescript-eslint/eslint-plugin": "^5.45.0",
"@typescript-eslint/parser": "^5.45.0",
"eslint": "^8.28.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-svelte": "^2.26.0",
"prettier": "^2.8.0",
"prettier-plugin-svelte": "^2.8.1",
"svelte": "^3.54.0",
"svelte-check": "^3.0.1",
"tslib": "^2.4.1",
"typescript": "^5.0.0",
"vite": "^4.3.0",
"vitest": "^0.25.3",
"@sveltejs/adapter-vercel": "^1.0.0-next.62",
"autoprefixer": "^10.2.5",
"postcss": "^8.2.15",
"svelte-bootstrap-icons": "^1.8.0",
"tailwindcss": "^3.1.8",
"tsparticles": "^2.2.4",
"@esbuild-plugins/node-globals-polyfill": "^0.1.1",
"@esbuild-plugins/node-modules-polyfill": "^0.1.4",
"@lukeed/uuid": "^2.0.0",
"@tailwindcss/typography": "^0.5.7",
"browserify-zlib": "^0.2.0",
"buffer": "^6.0.3",
"cookie": "^0.4.1",
"daisyui": "^2.27.0",
"events": "^3.3.0",
"leaflet": "^1.9.2",
"process": "^0.11.10",
"stream": "^0.0.2",
"stream-browserify": "^3.0.0",
"svelte-chartjs": "^1.0.1",
"svelte-particles": "^2.2.4",
"util": "^0.12.4"
},
"type": "module"
}
================================================
FILE: playwright.config.ts
================================================
import type { PlaywrightTestConfig } from '@playwright/test';
const config: PlaywrightTestConfig = {
webServer: {
command: 'npm run build && npm run preview',
port: 4173
},
testDir: 'tests',
testMatch: /(.+\.)?(test|spec)\.[jt]s/
};
export default config;
================================================
FILE: postcss.config.cjs
================================================
module.exports = {
plugins: [require('tailwindcss'), require('autoprefixer')]
}
================================================
FILE: run
================================================
#!/bin/bash
# How to?
# ./run {route-folder} {packages.scripts}
#
# As an example below:
# ./run demo dev
# ./run admin dev
# ./run admin-in dev
# ./run admin-out dev
# ./run blog dev
# ./run landing dev
#
# Others such as:
# ./run admin build
# ./run admin package
ROUTE_FOLDER=$1 $(which npm) run $2 ${@:3}
================================================
FILE: src/app.css
================================================
@import '@fontsource/fira-mono';
:root {
font-family: Arial, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu,
Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
--font-mono: 'Fira Mono', monospace;
--pure-white: #ffffff;
--primary-color: #b9c6d2;
--secondary-color: #d0dde9;
--tertiary-color: #edf0f8;
--accent-color: #ff3e00;
--heading-color: rgba(0, 0, 0, 0.7);
--text-color: #444444;
--background-without-opacity: rgba(255, 255, 255, 0.7);
--column-width: 42rem;
--column-margin-top: 4rem;
}
body {
min-height: 100vh;
margin: 0;
background-color: var(--primary-color);
background: linear-gradient(
180deg,
var(--primary-color) 0%,
var(--secondary-color) 10.45%,
var(--tertiary-color) 41.35%
);
}
body::before {
content: '';
width: 80vw;
height: 100vh;
position: absolute;
top: 0;
left: 10vw;
z-index: -1;
background: radial-gradient(
50% 50% at 50% 50%,
var(--pure-white) 0%,
rgba(255, 255, 255, 0) 100%
);
opacity: 0.05;
}
#svelte {
min-height: 100vh;
display: flex;
flex-direction: column;
}
h1,
h2,
p {
font-weight: 400;
color: var(--heading-color);
}
p {
line-height: 1.5;
}
a {
color: var(--accent-color);
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
h1 {
font-size: 2rem;
text-align: center;
}
h2 {
font-size: 1rem;
}
pre {
font-size: 16px;
font-family: var(--font-mono);
background-color: rgba(255, 255, 255, 0.45);
border-radius: 3px;
box-shadow: 2px 2px 6px rgb(255 255 255 / 25%);
padding: 0.5em;
overflow-x: auto;
color: var(--text-color);
}
input,
button {
font-size: inherit;
font-family: inherit;
}
button:focus:not(:focus-visible) {
outline: none;
}
@media (min-width: 720px) {
h1 {
font-size: 2.4rem;
}
}
================================================
FILE: src/app.d.ts
================================================
// See https://kit.svelte.dev/docs#typescript
// for information about these interfaces
declare global {
namespace App {
// interface Error {}
interface Locals {
// sveltekit default
userid: string;
// laravel sanctum
user: any;
session: string;
}
interface Session {
// laravel sanctum
user: any;
}
// interface PageData {}
// interface Platform {}
}
}
export { };
================================================
FILE: src/app.html
================================================
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%sveltekit.assets%/favicon.png" />
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
%sveltekit.head%
</head>
<body data-sveltekit-preload-data="hover">
<div style="display: contents">%sveltekit.body%</div>
</body>
</html>
================================================
FILE: src/hooks/laravel-sanctum-fake-logged-in.ts
================================================
import cookie, { parse } from 'cookie';
import type { Handle } from '@sveltejs/kit';
// inside laravel-sanctum.ts
// -> we're actually fetching the user who logged in
// -> as well fetching a new session if the cookie is not present
export const handle: Handle = async ({ event, resolve }) => {
if (!event.locals.user) {
event.locals.user = {
id: 1,
email: "janedoe@email.com",
photo: "https://images.unsplash.com/photo-1502378735452-bc7d86632805?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&s=aa3a807e1bbdfd4364d1f449eaa96d82",
first_name: "Jane",
last_name: "Doe",
}
}
const sessionName = import.meta.env.VITE_SESSION_NAME
const cookies = cookie.parse(event.request.headers.get('cookie') || '')
event.locals.session = cookies[sessionName]
const response = await resolve(event)
if (!event.locals.session) {
// set cookie in the client
response.headers.set(
'set-cookie',
cookie.serialize(import.meta.env.VITE_SESSION_NAME, "this-is-a-fake-session")
)
}
return response
};
================================================
FILE: src/hooks/laravel-sanctum-fake-logged-out.ts
================================================
import type { Handle } from '@sveltejs/kit';
// since we want to simulate a FAKE log out
// inside this hooks, we will do nothing!
export const handle: Handle = async ({ event, resolve }) => {
const response = await resolve(event)
return response
};
================================================
FILE: src/hooks/laravel-sanctum.ts
================================================
import { api } from '$src/routes/api';
import cookie, { parse } from 'cookie';
import type { Handle } from '@sveltejs/kit';
export const handle: Handle = async ({ event, resolve }) => {
if (!event.locals.user) {
const loggedIn = await api({
method: 'get',
resource: 'logged-in',
event,
});
event.locals.user = (await loggedIn.json()).user
}
const sessionName = import.meta.env.VITE_SESSION_NAME
const cookies = cookie.parse(event.request.headers.get('cookie') || '')
event.locals.session = cookies[sessionName]
const response = await resolve(event)
if (!event.locals.session) {
const sanctum = await api({
method: 'get',
resource: 'sanctum/csrf-cookie',
event,
});
if (sanctum.status === 204) {
// set cookie in the client
response.headers.set(
'set-cookie',
sanctum.headers.get('set-cookie') ?? ''
)
}
}
return response
};
================================================
FILE: src/hooks/sveltekit-default.ts
================================================
import type { Handle } from '@sveltejs/kit';
import * as cookie from 'cookie';
export const handle: Handle = async ({ event, resolve }) => {
const cookies = cookie.parse(event.request.headers.get('cookie') || '');
event.locals.userid = cookies['userid'] || crypto.randomUUID();
const response = await resolve(event);
if (!cookies['userid']) {
// if this is the first time the user has visited this app,
// set a cookie so that we recognise them when they return
response.headers.set(
'set-cookie',
cookie.serialize('userid', event.locals.userid, {
path: '/',
httpOnly: true
})
);
}
return response;
};
================================================
FILE: src/lib/Counter.svelte
================================================
<script lang="ts">
import { spring } from 'svelte/motion'
let count = 0
const displayed_count = spring()
$: displayed_count.set(count)
$: offset = modulo($displayed_count, 1)
function modulo(n: number, m: number) {
// handle negative numbers
return ((n % m) + m) % m
}
</script>
<div class="counter">
<button on:click={() => (count -= 1)} aria-label="Decrease the counter by one">
<svg aria-hidden="true" viewBox="0 0 1 1">
<path d="M0,0.5 L1,0.5" />
</svg>
</button>
<div class="counter-viewport">
<div class="counter-digits" style="transform: translate(0, {100 * offset}%)">
<strong class="hidden" aria-hidden="true">{Math.floor($displayed_count + 1)}</strong>
<strong>{Math.floor($displayed_count)}</strong>
</div>
</div>
<button on:click={() => (count += 1)} aria-label="Increase the counter by one">
<svg aria-hidden="true" viewBox="0 0 1 1">
<path d="M0,0.5 L1,0.5 M0.5,0 L0.5,1" />
</svg>
</button>
</div>
<style>
.counter {
display: flex;
border-top: 1px solid rgba(0, 0, 0, 0.1);
border-bottom: 1px solid rgba(0, 0, 0, 0.1);
margin: 1rem 0;
}
.counter button {
width: 2em;
padding: 0;
display: flex;
align-items: center;
justify-content: center;
border: 0;
background-color: transparent;
touch-action: manipulation;
color: var(--text-color);
font-size: 2rem;
}
.counter button:hover {
background-color: var(--secondary-color);
}
svg {
width: 25%;
height: 25%;
}
path {
vector-effect: non-scaling-stroke;
stroke-width: 2px;
stroke: var(--text-color);
}
.counter-viewport {
width: 8em;
height: 4em;
overflow: hidden;
text-align: center;
position: relative;
}
.counter-viewport strong {
position: absolute;
display: flex;
width: 100%;
height: 100%;
font-weight: 400;
color: var(--accent-color);
font-size: 4rem;
align-items: center;
justify-content: center;
}
.counter-digits {
position: absolute;
width: 100%;
height: 100%;
}
.hidden {
top: -100%;
user-select: none;
}
</style>
================================================
FILE: src/lib/components/Accordion.svelte
================================================
<div class="border border-b-0 border-gray-500 dark:border-gray-600 rounded-md">
<slot />
</div>
================================================
FILE: src/lib/components/AccordionItem.svelte
================================================
<script lang="ts">
import { fly } from 'svelte/transition'
import ChevronUp from '$icon/ChevronUp/ChevronUp.svelte'
import ChevronDown from '$icon/ChevronDown/ChevronDown.svelte'
export let title = 'My accordion title'
export let type = 'primary'
export let show = false
$: show
</script>
<div class="border-b border-gray-500 dark:border-gray-600">
<button
class="w-full px-4 py-3 text-sm font-semibold focus:outline-none {show &&
`border-b border-gray-500 dark:border-gray-600 ${type}`}"
type="button"
on:click={() => {
show = !show
}}
>
<div class="float-left">{title}</div>
<div class="float-right mt-1">
{#if show}
<ChevronDown />
{:else}
<ChevronUp />
{/if}
</div>
</button>
{#if show}
<div transition:fly={{ duration: 50 }} class="py-3 px-6 text-sm">
<slot />
</div>
{/if}
</div>
================================================
FILE: src/lib/components/Alert.svelte
================================================
<script lang="ts">
export let type = 'primary'
export let body = null
let color = ''
// reactive
$: switch (type) {
case 'primary':
color = 'primary focus:shadow-outline-purple'
break
case 'secondary':
color = 'secondary focus:shadow-outline-gray'
break
case 'success':
color = 'success focus:shadow-outline-green'
break
case 'danger':
color = 'danger focus:shadow-outline-red'
break
case 'warning':
color = 'warning focus:shadow-outline-orange'
break
case 'info':
color = 'info focus:shadow-outline-blue'
break
case 'light':
color = 'light focus:shadow-outline-white'
break
case 'dark':
color = 'dark focus:shadow-outline-gray'
break
}
</script>
<div
class="flex items-center justify-between p-4 mb-8 text-sm font-semibold rounded-lg shadow-md focus:outline-none {color}"
>
{#if body}
{body}
{:else}
<slot />
{/if}
</div>
================================================
FILE: src/lib/components/Badge.svelte
================================================
<script lang="ts">
export let type = 'primary'
export let body: string | null = null
export let roundedSize = 'sm'
$: type
$: body
</script>
<span class="inline-block {type} rounded-{roundedSize} {$$props.class}">
{#if body}
{body}
{:else}
<slot />
{/if}
</span>
================================================
FILE: src/lib/components/Breadcrumb.svelte
================================================
================================================
FILE: src/lib/components/ButtonGroup.svelte
================================================
================================================
FILE: src/lib/components/Buttons.svelte
================================================
================================================
FILE: src/lib/components/Card.svelte
================================================
================================================
FILE: src/lib/components/Carousel.svelte
================================================
================================================
FILE: src/lib/components/CloseButton.svelte
================================================
================================================
FILE: src/lib/components/Code.svelte
================================================
<script lang="ts">
export let language = null
export let data = []
</script>
<code
class="block rounded-lg text-sm text-gray-200 bg-gray-800 dark:text-gray-800 dark:bg-gray-200 px-3 pb-4 mb-2"
>
{#if language}
<span class="text-xs block py-2 px-0 text-orange-400 dark:text-orange-600">// {language}</span>
{:else}
<span class="block py-2 px-0" />
{/if}
{#if data.length}
{#each data as datum, i}
<pre class="inline-block">{datum}</pre>
{#if data.length !== i + 1}
<br />
{/if}
{/each}
{:else}
<slot />
{/if}
</code>
================================================
FILE: src/lib/components/Collapse.svelte
================================================
================================================
FILE: src/lib/components/Docs/DocAccordion.svelte
================================================
<script lang="ts">
import Accordion from '$lib/components/Accordion.svelte'
import AccordionItem from '$lib/components/AccordionItem.svelte'
import Code from '$lib/components/Code.svelte'
</script>
<span class="text-xl">Accordion</span>
<Accordion>
<AccordionItem title="Normal text accordion" type="primary"
>Eu laboris officia dolore non anim qui fugiat duis. Consectetur anim consequat commodo
excepteur dolor commodo sint proident eu deserunt ea incididunt minim sint. Aliqua dolor tempor
ex dolore magna tempor ullamco sunt sit sit veniam. Nisi proident cupidatat labore aliqua minim.
Eiusmod ad laborum commodo elit anim cupidatat elit quis.</AccordionItem
>
<AccordionItem title="HTML Accordion" type="danger" show={true}>
My 2nd accordition with html element
<div>
<p class="text-xs">
Esse labore dolore reprehenderit est laboris labore. Deserunt pariatur nisi enim nulla elit
minim laborum sunt sunt labore duis sit. Dolore incididunt minim eu est dolor velit
adipisicing deserunt labore. Culpa aute nostrud magna aliqua exercitation reprehenderit sunt
sit.
</p>
<strong>strong</strong>
<i>italic</i>
</div>
</AccordionItem>
</Accordion>
<h3 class="text-sm mt-2">Example:</h3>
<Code language="svelte">
{"import Accordion from '$lib/components/Accordion.svelte'"}<br />
{"import AccordionItem from '$lib/components/AccordionItem.svelte'"}<br /><br />
{'// can be (primary, secondary, success, danger, warning, info, light, dark)'}<br />
{"let type = 'danger'"}<br />
<br />
{'<Accordion>'}<br />
{'<AccordionItem type show={true}>Text or HTML element here..</Accordion>'}<br />
{'<AccordionItem type="light" show={false}>Text or HTML element here..</Accordion>'}<br
/>
{'</Accordion>'}
</Code>
================================================
FILE: src/lib/components/Docs/DocAlert.svelte
================================================
<script lang="ts">
import Alert from '$lib/components/Alert.svelte'
import Code from '$lib/components/Code.svelte'
</script>
<span class="text-xl">Alerts</span>
<Alert type="primary">A simple primary alert</Alert>
<Alert type="secondary">A simple secondary alert</Alert>
<Alert type="success">A simple success alert</Alert>
<Alert type="danger">A simple danger alert</Alert>
<Alert type="warning">A simple warning alert</Alert>
<Alert type="info">A simple info alert</Alert>
<Alert type="light">A simple light alert</Alert>
<Alert type="dark">A simple dark alert</Alert>
<h3 class="text-sm mt-2">Example:</h3>
<Code language="svelte">
{"import Alert from '$lib/components/Alert.svelte'"}<br /><br />
{'<Alert type="info" body="Hello World!" />'}<br />
{'<Alert type="primary">A simple primary alert</Alert>'}
</Code>
================================================
FILE: src/lib/components/Docs/DocBadge.svelte
================================================
<script lang="ts">
import Badge from '$lib/components/Badge.svelte'
import Code from '$lib/components/Code.svelte'
</script>
<span class="text-xl">Badges</span>
<div class="relative">
<Badge type="primary" body="primary" />
<Badge type="secondary" body="secondary" />
<Badge type="success" body="success" />
<Badge type="danger" body="danger" />
<Badge type="warning" body="warning" />
<Badge type="info" body="info" />
<Badge type="light" body="light" />
<Badge type="dark" body="dark" />
<Badge type="info" class="px-2 py-1">Hello World!</Badge>
</div>
<h3 class="text-sm mt-2">Example:</h3>
<Code language="svelte">
{"import Badge from '$lib/components/Badge.svelte'"}<br /><br />
{'<Badge type="primary" body="primary" />'}<br />
{'<Badge type="secondary" body="secondary" />'}<br />
{'<Badge type="success" body="success" />'}<br />
{'<Badge type="danger" body="danger" />'}<br />
{'<Badge type="warning" body="warning" />'}<br />
{'<Badge type="info" body="info" />'}<br />
{'<Badge type="light" body="light" />'}<br />
{'<Badge type="dark" body="dark" />'}<br />
{'<Badge type="info" class="px-2 py-1">Hello World!</Badge>'}
</Code>
================================================
FILE: src/lib/components/Dropdowns.svelte
================================================
================================================
FILE: src/lib/components/ListGroup.svelte
================================================
================================================
FILE: src/lib/components/Modal.svelte
================================================
================================================
FILE: src/lib/components/NavsAndTabs.svelte
================================================
================================================
FILE: src/lib/components/Pagination.svelte
================================================
================================================
FILE: src/lib/components/Popovers.svelte
================================================
================================================
FILE: src/lib/components/Spinners.svelte
================================================
================================================
FILE: src/lib/components/Toasts.svelte
================================================
================================================
FILE: src/lib/components/Tooltips.svelte
================================================
================================================
FILE: src/lib/form.ts
================================================
import { invalidateAll } from '$app/navigation';
// this action (https://svelte.dev/tutorial/actions) allows us to
// progressively enhance a <form> that already works without JS
export function enhance(
form: HTMLFormElement,
{
pending,
error,
result
}: {
pending?: ({ data, form }: { data: FormData; form: HTMLFormElement }) => void;
error?: ({
data,
form,
response,
error
}: {
data: FormData;
form: HTMLFormElement;
response: Response | null;
error: Error | null;
}) => void;
result?: ({
data,
form,
response
}: {
data: FormData;
response: Response;
form: HTMLFormElement;
}) => void;
} = {}
) {
let current_token: unknown;
async function handle_submit(event: SubmitEvent) {
const token = (current_token = {});
event.preventDefault();
const data = new FormData(form);
if (pending) pending({ data, form });
try {
const response = await fetch(form.action, {
method: form.method,
headers: {
accept: 'application/json'
},
body: data
});
if (token !== current_token) return;
if (response.ok) {
if (result) result({ data, form, response });
invalidateAll();
} else if (error) {
error({ data, form, error: null, response });
} else {
console.error(await response.text());
}
} catch (err: unknown) {
if (error && err instanceof Error) {
error({ data, form, error: err, response: null });
} else {
throw err;
}
}
}
form.addEventListener('submit', handle_submit);
return {
destroy() {
form.removeEventListener('submit', handle_submit);
}
};
}
================================================
FILE: src/lib/header/Header.svelte
================================================
<script lang="ts">
import { page } from '$app/stores'
import logo from './svelte-logo.svg'
</script>
<header>
<div class="corner">
<a href="https://kit.svelte.dev">
<img src={logo} alt="SvelteKit" />
</a>
</div>
<nav data-sveltekit-prefetch>
<svg viewBox="0 0 2 3" aria-hidden="true">
<path d="M0,0 L1,2 C1.5,3 1.5,3 2,3 L2,0 Z" />
</svg>
<ul>
<li class:active={$page.url.pathname === '/'}>
<a href="/">Home</a>
</li>
<li class:active={$page.url.pathname === '/about'}>
<a href="/about">About</a>
</li>
<li class:active={$page.url.pathname === '/todos'}>
<a href="/todos">Todos</a>
</li>
</ul>
<svg viewBox="0 0 2 3" aria-hidden="true">
<path d="M0,0 L0,3 C0.5,3 0.5,3 1,2 L2,0 Z" />
</svg>
</nav>
<div class="corner">
<!-- TODO put something else here? github link? -->
</div>
</header>
<style>
header {
display: flex;
justify-content: space-between;
}
.corner {
width: 3em;
height: 3em;
}
.corner a {
display: flex;
align-items: center;
justify-content: center;
width: 100%;
height: 100%;
}
.corner img {
width: 2em;
height: 2em;
object-fit: contain;
}
nav {
display: flex;
justify-content: center;
--background: rgba(255, 255, 255, 0.7);
}
svg {
width: 2em;
height: 3em;
display: block;
}
path {
fill: var(--background);
}
ul {
position: relative;
padding: 0;
margin: 0;
height: 3em;
display: flex;
justify-content: center;
align-items: center;
list-style: none;
background: var(--background);
background-size: contain;
}
li {
position: relative;
height: 100%;
}
li.active::before {
--size: 6px;
content: '';
width: 0;
height: 0;
position: absolute;
top: 0;
left: calc(50% - var(--size));
border: var(--size) solid transparent;
border-top: var(--size) solid var(--accent-color);
}
nav a {
display: flex;
height: 100%;
align-items: center;
padding: 0 1em;
color: var(--heading-color);
font-weight: 700;
font-size: 0.8rem;
text-transform: uppercase;
letter-spacing: 0.1em;
text-decoration: none;
transition: color 0.2s linear;
}
a:hover {
color: var(--accent-color);
}
</style>
================================================
FILE: src/lib/ioevents/click.ts
================================================
/** Dispatch event on click outside of node */
export function clickOutside(node: any, except: any[] = []) {
const handle = (event: any) => {
let shouldSkip = false
except.forEach((val) => {
if (document.getElementById(val)?.contains(event.target)) {
shouldSkip = true
}
})
if (shouldSkip) {
return
}
if (node && !node.contains(event.target) && !event.defaultPrevented) {
node.dispatchEvent(new CustomEvent('click-outside', node))
}
}
document.addEventListener('click', handle, true)
return {
destroy() {
document.removeEventListener('click', handle, true)
},
}
}
================================================
FILE: src/lib/ioevents/keydown.ts
================================================
/** Dispatch event on keydown Escape of node */
export function keydownEscape(node: any) {
const handle = (event: any) => {
if (event.key === 'Escape') {
node.dispatchEvent(new CustomEvent('keydown-escape', node))
}
}
document.addEventListener('keydown', handle, true)
return {
destroy() {
document.removeEventListener('keydown', handle, true)
},
}
}
================================================
FILE: src/lib/tailwind.css
================================================
@tailwind base;
@tailwind components;
@tailwind utilities;
.bg-blog {
@apply bg-blue-500;
}
.primary {
@apply text-purple-100 bg-purple-600;
}
.secondary {
@apply text-gray-100 bg-gray-500;
}
.success {
@apply text-green-100 bg-green-600;
}
.danger {
@apply text-red-100 bg-red-600;
}
.warning {
@apply text-orange-100 bg-orange-600;
}
.info {
@apply text-blue-100 bg-blue-600;
}
.light {
@apply text-gray-700 bg-white;
}
.dark {
@apply text-gray-100 bg-gray-700;
}
================================================
FILE: src/lib/templates/Admin/API/form.ts
================================================
export default function enhance(
form: HTMLFormElement,
{
pending,
error,
result,
}: {
pending?: (data: FormData, form: HTMLFormElement) => void
error?: (res: Response, error: Error, form: HTMLFormElement) => void
result: (res: Response, form: HTMLFormElement) => void
}
) {
async function handle(e: Event) {
e.preventDefault()
const body = new FormData(form)
if (pending) pending(body, form)
try {
const res = await fetch(form.action, {
method: form.method,
headers: {
accept: 'application/json',
},
body,
})
if (res.ok) {
result(res, form)
} else if (error) {
error(res, null, form)
} else {
console.error(await res.text())
}
} catch (e) {
if (error) {
error(null, e, form)
} else {
throw e
}
}
}
form.addEventListener('submit', handle)
return {
destroy() {
form.removeEventListener('submit', handle)
},
}
}
================================================
FILE: src/lib/templates/Admin/Config/charts.ts
================================================
/**
* For usage, visit Chart.js docs https://www.chartjs.org/docs/latest/
*/
export const barConfig = {
type: 'bar',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [
{
label: 'Shoes',
backgroundColor: '#0694a2',
// borderColor: window.chartColors.red,
borderWidth: 1,
data: [-3, 14, 52, 74, 33, 90, 70],
},
{
label: 'Bags',
backgroundColor: '#7e3af2',
// borderColor: window.chartColors.blue,
borderWidth: 1,
data: [66, 33, 43, 12, 54, 62, 84],
},
],
},
options: {
responsive: true,
legend: {
display: false,
},
},
}
export const lineConfig = {
type: 'line',
data: {
labels: ['January', 'February', 'March', 'April', 'May', 'June', 'July'],
datasets: [
{
label: 'Organic',
/**
* These colors come from Tailwind CSS palette
* https://tailwindcss.com/docs/customizing-colors/#default-color-palette
*/
backgroundColor: '#0694a2',
borderColor: '#0694a2',
data: [43, 48, 40, 54, 67, 73, 70],
fill: false,
},
{
label: 'Paid',
fill: false,
/**
* These colors come from Tailwind CSS palette
* https://tailwindcss.com/docs/customizing-colors/#default-color-palette
*/
backgroundColor: '#7e3af2',
borderColor: '#7e3af2',
data: [24, 50, 64, 74, 52, 51, 65],
},
],
},
options: {
responsive: true,
/**
* Default legends are ugly and impossible to style.
* See examples in charts.html to add your own legends
* */
legend: {
display: false,
},
tooltips: {
mode: 'index',
intersect: false,
},
hover: {
mode: 'nearest',
intersect: true,
},
scales: {
x: {
display: true,
scaleLabel: {
display: true,
labelString: 'Month',
},
},
y: {
display: true,
scaleLabel: {
display: true,
labelString: 'Value',
},
},
},
},
}
export const pieConfig = {
type: 'doughnut',
data: {
datasets: [
{
data: [33, 33, 33],
/**
* These colors come from Tailwind CSS palette
* https://tailwindcss.com/docs/customizing-colors/#default-color-palette
*/
backgroundColor: ['#0694a2', '#1c64f2', '#7e3af2'],
label: 'Dataset 1',
},
],
labels: ['Shoes', 'Shirts', 'Bags'],
},
options: {
responsive: true,
cutoutPercentage: 80,
/**
* Default legends are ugly and impossible to style.
* See examples in charts.html to add your own legends
* */
legend: {
display: false,
},
},
}
================================================
FILE: src/lib/templates/Admin/Header.svelte
================================================
<script lang="ts">
import {
isDark,
isNotificationsMenuOpen,
isProfileMenuOpen,
toggleSideMenu,
toggleNotificationsMenu,
toggleProfileMenu,
closeNotificationsMenu,
closeProfileMenu
} from '$stores/menus'
import { clickOutside } from '$lib/ioevents/click'
import { keydownEscape } from '$lib/ioevents/keydown'
import ToggleTheme from './ToggleTheme.svelte'
export let user: any
let withSearch = true
</script>
<header class="z-10 py-4 bg-white shadow-md dark:bg-gray-800">
<div
class="container flex items-center justify-between h-full px-6 mx-auto text-purple-600 dark:text-purple-300"
>
<!-- Mobile hamburger -->
<button
id="nav-mobile-hamburger"
class="p-1 mr-5 -ml-1 rounded-md md:hidden focus:outline-none focus:shadow-outline-purple"
on:click={toggleSideMenu}
aria-label="Menu"
>
<svg class="w-6 h-6" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
d="M3 5a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 10a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1zM3 15a1 1 0 011-1h12a1 1 0 110 2H4a1 1 0 01-1-1z"
clip-rule="evenodd"
/>
</svg>
</button>
{#if withSearch}
<!-- Search input -->
<div class="flex justify-center flex-1 lg:mr-32">
<div class="relative w-full max-w-xl mr-6 focus-within:text-purple-500">
<div class="absolute inset-y-0 flex items-center pl-2">
<svg class="w-4 h-4" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z"
clip-rule="evenodd"
/>
</svg>
</div>
<input
class="w-full pl-8 pr-2 py-2 text-sm text-gray-700 placeholder-gray-600 bg-gray-100 border-0 rounded-md dark:placeholder-gray-500 dark:focus:shadow-outline-gray dark:focus:placeholder-gray-600 dark:bg-gray-700 dark:text-gray-200 focus:placeholder-gray-500 focus:bg-white focus:border-purple-300 focus:outline-none focus:shadow-outline-purple form-input"
type="text"
placeholder="Search for Profiles (uid / email / username)"
aria-label="Search"
/>
</div>
</div>
{/if}
<div class:w-full={!withSearch}>
<ul class="flex justify-end items-center flex-shrink-0 space-x-6">
<!-- Theme toggler -->
<li class="flex">
<ToggleTheme />
</li>
<!-- Notifications menu -->
<li class="relative">
<button
id="nav-notification-btn"
class="relative align-middle rounded-md focus:outline-none focus:shadow-outline-purple"
on:click={toggleNotificationsMenu}
use:keydownEscape
on:keydown-escape={closeNotificationsMenu}
aria-label="Notifications"
aria-haspopup="true"
>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
d="M10 2a6 6 0 00-6 6v3.586l-.707.707A1 1 0 004 14h12a1 1 0 00.707-1.707L16 11.586V8a6 6 0 00-6-6zM10 18a3 3 0 01-3-3h6a3 3 0 01-3 3z"
/>
</svg>
<span
aria-hidden="true"
class="absolute top-0 right-0 inline-block w-3 h-3 transform translate-x-1 -translate-y-1 bg-red-600 border-2 border-white rounded-full dark:border-gray-800"
/>
</button>
{#if $isNotificationsMenuOpen}
<ul
use:clickOutside={['nav-notification-btn']}
on:click-outside={closeNotificationsMenu}
use:keydownEscape
on:keydown-escape={closeNotificationsMenu}
class="absolute right-0 w-56 p-2 mt-2 space-y-2 text-gray-600 bg-white border border-gray-100 rounded-md shadow-md dark:text-gray-300 dark:border-gray-700 dark:bg-gray-700"
>
<li class="flex">
<a
class="inline-flex items-center justify-between w-full px-2 py-1 text-sm font-semibold transition-colors duration-150 rounded-md hover:bg-gray-100 hover:text-gray-800 dark:hover:bg-gray-800 dark:hover:text-gray-200"
href="/"
>
<span>Messages</span>
<span
class="inline-flex items-center justify-center px-2 py-1 text-xs font-bold leading-none text-red-600 bg-red-100 rounded-full dark:text-red-100 dark:bg-red-600"
>
13
</span>
</a>
</li>
<li class="flex">
<a
class="inline-flex items-center justify-between w-full px-2 py-1 text-sm font-semibold transition-colors duration-150 rounded-md hover:bg-gray-100 hover:text-gray-800 dark:hover:bg-gray-800 dark:hover:text-gray-200"
href="/"
>
<span>Sales</span>
<span
class="inline-flex items-center justify-center px-2 py-1 text-xs font-bold leading-none text-red-600 bg-red-100 rounded-full dark:text-red-100 dark:bg-red-600"
>
2
</span>
</a>
</li>
<li class="flex">
<a
class="inline-flex items-center justify-between w-full px-2 py-1 text-sm font-semibold transition-colors duration-150 rounded-md hover:bg-gray-100 hover:text-gray-800 dark:hover:bg-gray-800 dark:hover:text-gray-200"
href="/"
>
<span>Alerts</span>
</a>
</li>
</ul>
{/if}
</li>
<!-- Profile menu -->
<li class="relative">
<button
id="nav-profile-photo"
class="align-middle rounded-full focus:shadow-outline-purple focus:outline-none"
on:click={toggleProfileMenu}
use:keydownEscape
on:keydown-escape={closeProfileMenu}
aria-label="Account"
aria-haspopup="true"
>
<img
class="object-cover w-8 h-8 rounded-full"
src={user?.photo}
alt="{user?.first_name} {user?.last_name}"
aria-hidden="true"
/>
</button>
{#if $isProfileMenuOpen}
<ul
use:clickOutside={['nav-profile-photo']}
on:click-outside={closeProfileMenu}
use:keydownEscape
on:keydown-escape={closeProfileMenu}
class="absolute right-0 w-56 p-2 mt-2 space-y-2 text-gray-600 bg-white border border-gray-100 rounded-md shadow-md dark:border-gray-700 dark:text-gray-300 dark:bg-gray-700"
aria-label="submenu"
>
<li class="flex">
<a
class="inline-flex items-center w-full px-2 py-1 text-sm font-semibold transition-colors duration-150 rounded-md hover:bg-gray-100 hover:text-gray-800 dark:hover:bg-gray-800 dark:hover:text-gray-200"
href="/"
>
<svg
class="w-4 h-4 mr-3"
aria-hidden="true"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z" />
</svg>
<span>Profile</span>
</a>
</li>
<li class="flex">
<a
class="inline-flex items-center w-full px-2 py-1 text-sm font-semibold transition-colors duration-150 rounded-md hover:bg-gray-100 hover:text-gray-800 dark:hover:bg-gray-800 dark:hover:text-gray-200"
href="/"
>
<svg
class="w-4 h-4 mr-3"
aria-hidden="true"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z"
/>
<path d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" />
</svg>
<span>Settings</span>
</a>
</li>
<li class="flex">
<a
class="inline-flex items-center w-full px-2 py-1 text-sm font-semibold transition-colors duration-150 rounded-md hover:bg-gray-100 hover:text-gray-800 dark:hover:bg-gray-800 dark:hover:text-gray-200"
href={import.meta.env.VITE_LOGOUT_PATH}
>
<svg
class="w-4 h-4 mr-3"
aria-hidden="true"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
d="M11 16l-4-4m0 0l4-4m-4 4h14m-5 4v1a3 3 0 01-3 3H6a3 3 0 01-3-3V7a3 3 0 013-3h7a3 3 0 013 3v1"
/>
</svg>
<span>Log out</span>
</a>
</li>
</ul>
{/if}
</li>
</ul>
</div>
</div>
</header>
================================================
FILE: src/lib/templates/Admin/SideBar.svelte
================================================
<script lang="ts">
import { closeSideMenu, pageMenus, togglePageMenu, toggleSideMenu } from '$stores/menus'
import { page } from '$app/stores'
import { goto } from '$app/navigation'
const appName = import.meta.env.VITE_APP_NAME
$: changeLink = (link: any) => {
closeSideMenu()
goto(link.url)
}
$: isMainLink = (link: any) => {
if (!link.url) {
return false
}
return link.url === activeUrl.pathname
}
$: isChildLink = (link: any) => {
if (!link.url) {
return false
}
return activeUrl.pathname.indexOf(link.url, 0) >= 0
}
$: activeUrl = $page.url
export let withTitle = true
export let links = [
{
name: 'Dashboard',
url: '/',
svg: [
'M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6'
]
},
{
name: 'Forms',
url: '/forms',
svg: [
'M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2m-3 7h3m-3 4h3m-6-4h.01M9 16h.01'
]
},
{
name: 'Cards',
url: '/cards',
svg: [
'M19 11H5m14 0a2 2 0 012 2v6a2 2 0 01-2 2H5a2 2 0 01-2-2v-6a2 2 0 012-2m14 0V9a2 2 0 00-2-2M5 11V9a2 2 0 012-2m0 0V5a2 2 0 012-2h6a2 2 0 012 2v2M7 7h10'
]
},
{
name: 'Charts',
url: '/charts',
svg: [
'M11 3.055A9.001 9.001 0 1020.945 13H11V3.055z',
'M20.488 9H15V3.512A9.025 9.025 0 0120.488 9z'
]
},
{
name: 'Buttons',
url: '/buttons',
svg: [
'M15 15l-2 5L9 9l11 4-5 2zm0 0l5 5M7.188 2.239l.777 2.897M5.136 7.965l-2.898-.777M13.95 4.05l-2.122 2.122m-5.657 5.656l-2.12 2.122'
]
},
{
name: 'Modals',
url: '/modals',
svg: [
'M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z'
]
},
{ name: 'Tables', url: '/tables', svg: ['M4 6h16M4 10h16M4 14h16M4 18h16'] },
{
name: 'Pages',
url: '/pages',
svg: [
'M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z'
],
sublinks: [
{ name: 'Login', url: import.meta.env.VITE_LOGIN_PATH },
{ name: 'Register', url: '/register' },
{ name: 'Forgot Password', url: '/forgot-password' },
{ name: '404', url: '/this-page-does-not-exists-at-all' }
]
}
]
</script>
<div class="py-4 text-gray-500 dark:text-gray-400">
{#if withTitle}
<a class="ml-6 text-lg font-bold text-gray-800 dark:text-gray-200" href="/">{appName}</a>
{/if}
<ul class="mt-6">
{#each links as link, a}
<li class="relative px-6 py-3">
{#if isMainLink(link)}
<span
class="absolute inset-y-0 left-0 w-1 bg-purple-600 rounded-tr-lg rounded-br-lg"
aria-hidden="true"
/>
{/if}
{#if !link.sublinks}
<a
class="{isMainLink(link) &&
'text-gray-800 dark:text-gray-100'} inline-flex items-center w-full text-sm font-semibold transition-colors duration-150 hover:text-gray-800 dark:hover:text-gray-200"
href={link.url}
on:click={(e) => {
e.preventDefault()
changeLink(link)
}}
>
{#if link.svg}
<svg
class="w-5 h-5"
aria-hidden="true"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
stroke="currentColor"
>
{#each link.svg as s, b}
<path d={s} />
{/each}
</svg>
{/if}
<span class="ml-4">{link.name}</span>
</a>
{:else}
<button
on:click={() => togglePageMenu(link.name)}
class="{isChildLink(link) &&
'text-gray-800 dark:text-gray-100'} inline-flex items-center justify-between w-full text-sm font-semibold transition-colors duration-150 hover:text-gray-800 dark:hover:text-gray-200"
aria-haspopup="true"
>
<span class="inline-flex items-center">
<svg
class="w-5 h-5"
aria-hidden="true"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
d="M4 5a1 1 0 011-1h14a1 1 0 011 1v2a1 1 0 01-1 1H5a1 1 0 01-1-1V5zM4 13a1 1 0 011-1h6a1 1 0 011 1v6a1 1 0 01-1 1H5a1 1 0 01-1-1v-6zM16 13a1 1 0 011-1h2a1 1 0 011 1v6a1 1 0 01-1 1h-2a1 1 0 01-1-1v-6z"
/>
</svg>
<span class="ml-4">{link.name}</span>
</span>
<svg class="w-4 h-4" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
d="M5.293 7.293a1 1 0 011.414 0L10 10.586l3.293-3.293a1 1 0 111.414 1.414l-4 4a1 1 0 01-1.414 0l-4-4a1 1 0 010-1.414z"
clip-rule="evenodd"
/>
</svg>
</button>
{#if $pageMenus[link.name] || isChildLink(link)}
<ul
class="p-2 mt-2 space-y-2 overflow-hidden text-sm font-medium text-gray-500 rounded-md shadow-inner bg-gray-50 dark:text-gray-400 dark:bg-gray-900"
aria-label="submenu"
>
{#each link.sublinks as sublink, c}
<li
class="px-2 py-1 transition-colors duration-150 hover:text-gray-800 dark:hover:text-gray-200"
>
<a class="w-full" href={sublink.url}>{sublink.name}</a>
</li>
{/each}
</ul>
{/if}
{/if}
</li>
{/each}
</ul>
</div>
================================================
FILE: src/lib/templates/Admin/ToggleTheme.svelte
================================================
<script lang="ts">
import {
isDark,
toggleTheme,
} from '$stores/menus'
</script>
<button
class="rounded-md focus:outline-none focus:shadow-outline-purple"
on:click={toggleTheme}
aria-label="Toggle color mode"
>
{#if $isDark}
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
clip-rule="evenodd"
d="M10 2a1 1 0 011 1v1a1 1 0 11-2 0V3a1 1 0 011-1zm4 8a4 4 0 11-8 0 4 4 0 018 0zm-.464 4.95l.707.707a1 1 0 001.414-1.414l-.707-.707a1 1 0 00-1.414 1.414zm2.12-10.607a1 1 0 010 1.414l-.706.707a1 1 0 11-1.414-1.414l.707-.707a1 1 0 011.414 0zM17 11a1 1 0 100-2h-1a1 1 0 100 2h1zm-7 4a1 1 0 011 1v1a1 1 0 11-2 0v-1a1 1 0 011-1zM5.05 6.464A1 1 0 106.465 5.05l-.708-.707a1 1 0 00-1.414 1.414l.707.707zm1.414 8.486l-.707.707a1 1 0 01-1.414-1.414l.707-.707a1 1 0 011.414 1.414zM4 11a1 1 0 100-2H3a1 1 0 000 2h1z"
/>
</svg>
{:else}
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path d="M17.293 13.293A8 8 0 016.707 2.707a8.001 8.001 0 1010.586 10.586z" />
</svg>
{/if}
</button>
================================================
FILE: src/lib/templates/Blog/Config/links.json
================================================
[
{
"name": "Home",
"url": "/"
},
{
"name": "Resumé",
"url": "/resume"
}
]
================================================
FILE: src/lib/templates/Blog/Config/particle.json
================================================
{
"particles": {
"number": {
"value": 24,
"density": {
"enable": true,
"value_area": 800
}
},
"color": {
"value": "#ffffff"
},
"shape": {
"type": "circle",
"stroke": {
"width": 0,
"color": "#000000"
},
"polygon": {
"nb_sides": 12
},
"image": {
"src": "img/github.svg",
"width": 100,
"height": 100
}
},
"opacity": {
"value": 0.3,
"random": false,
"anim": {
"enable": false,
"speed": 1,
"opacity_min": 0.1,
"sync": false
}
},
"size": {
"value": 3,
"random": true,
"anim": {
"enable": false,
"speed": 40,
"size_min": 0.1,
"sync": false
}
},
"line_linked": {
"enable": true,
"distance": 150,
"color": "#ffffff",
"opacity": 0.4,
"width": 1
},
"move": {
"enable": true,
"speed": 0.5,
"direction": "top-right",
"random": true,
"straight": false,
"out_mode": "out",
"bounce": false,
"attract": {
"enable": true,
"rotateX": 600,
"rotateY": 1200
}
}
},
"interactivity": {
"detect_on": "canvas",
"events": {
"onhover": {
"enable": false,
"mode": "repulse"
},
"onclick": {
"enable": false,
"mode": "push"
},
"resize": true
},
"modes": {
"grab": {
"distance": 400,
"line_linked": {
"opacity": 1
}
},
"bubble": {
"distance": 400,
"size": 40,
"duration": 2,
"opacity": 5,
"speed": 3
},
"repulse": {
"distance": 200,
"duration": 0.4
},
"push": {
"particles_nb": 4
},
"remove": {
"particles_nb": 2
}
}
},
"retina_detect": true
}
================================================
FILE: src/lib/templates/Blog/Header.svelte
================================================
<script lang="ts">
import { isSideMenuOpen, toggleSideMenu } from '$stores/menus'
import List from '$icon/List/List.svelte'
import X from '$icon/X/X.svelte'
import links from './Config/links.json'
</script>
<header class="py-4 shadow-md">
<div class="container flex items-center justify-between h-full px-6 mx-auto text-purple-600 ">
<!-- Mobile hamburger -->
<button
id="nav-mobile-hamburger"
class="p-1 mr-5 -ml-1 rounded-md md:hidden focus:outline-none focus:shadow-outline-purple text-white"
on:click={toggleSideMenu}
aria-label="Menu"
>
{#if $isSideMenuOpen}
<X width="24" height="24" />
{:else}
<List width="24" height="24" />
{/if}
</button>
<div class="hidden md:block w-full">
<ul class="flex justify-end items-center flex-shrink-0 space-x-10 text-white">
{#each links as link, i}
<li>
<a href={link.url}>{link.name}</a>
</li>
{/each}
</ul>
</div>
</div>
</header>
================================================
FILE: src/lib/templates/Blog/Particles/Particles.svelte
================================================
<svelte:options accessors={true} />
<script lang="ts">
import { afterUpdate, createEventDispatcher } from 'svelte'
import type { ISourceOptions } from 'tsparticles-engine'
import { tsParticles } from 'tsparticles-engine'
export let options: ISourceOptions = {}
export let url = ''
export let id = 'tsparticles'
export let particlesInit: any
const dispatch = createEventDispatcher()
const particlesLoadedEvent = 'particlesLoaded'
let oldId = id
afterUpdate(async () => {
tsParticles.init()
if (particlesInit) {
await particlesInit(tsParticles)
}
if (oldId) {
const oldContainer = tsParticles.dom().find((c) => c.id === oldId)
if (oldContainer) {
oldContainer.destroy()
}
}
if (id) {
const cb = (container: any) => {
dispatch(particlesLoadedEvent, {
particles: container
})
oldId = id
}
let container
if (url) {
container = await tsParticles.loadJSON(id, url)
} else if (options) {
container = await tsParticles.load(id, options)
} else {
console.error('You must specify options or url to load tsParticles')
return
}
cb(container)
} else {
dispatch(particlesLoadedEvent, {
particles: undefined
})
}
})
</script>
<div {id} class={$$props.class} />
================================================
FILE: src/lib/templates/Blog/Particles/global.d.ts
================================================
/// <reference types="svelte" />
================================================
FILE: src/lib/templates/Blog/Particles/index.d.ts
================================================
import type { SvelteComponentTyped } from "svelte";
import type { ISourceOptions, Engine, Container } from "tsparticles-engine";
declare module "svelte-particles" {
type CustomEventWrapper<T> = {
[K in keyof T]: CustomEvent<T[K]>;
};
type ParticlesProps = {
options?: ISourceOptions;
url?: string;
id?: string;
particlesInit: (engine: Engine) => Promise<void>;
};
type ParticlesEvents = CustomEventWrapper<{
particlesLoaded: {
particles?: Container;
};
}>;
export default class extends SvelteComponentTyped<ParticlesProps, ParticlesEvents, {}> {
}
}
================================================
FILE: src/lib/templates/Blog/Particles/index.ts
================================================
export { default as default } from './Particles.svelte';
================================================
FILE: src/lib/templates/Blog/SideBar.svelte
================================================
<script lang="ts">
import { closeSideMenu, pageMenus, togglePageMenu } from '$stores/menus'
import { page } from '$app/stores'
import { goto } from '$app/navigation'
import links from './Config/links.json'
const changeUrl = (url: string) => {
closeSideMenu()
goto(url)
}
let activeMenu = $page.url
$: if ($page.url) {
activeMenu = $page.url
}
</script>
<div class="py-4 text-white">
<ul class="mt-6">
{#each links as link, a}
<li class="relative px-6 py-3">
{#if activeMenu == link.url}
<span
class="absolute inset-y-0 left-0 w-2 bg-blue-500 rounded-tr-lg rounded-br-lg"
aria-hidden="true"
/>
{/if}
<a
class="{activeMenu == link.url &&
'text-blue-200'} inline-flex items-center w-full text-3xl font-semibold transition-colors duration-150 hover:text-blue-300"
href={link.url}
on:click={(e) => {
e.preventDefault()
changeUrl(link.url)
}}
>
<span class="ml-4 mt-4">{link.name}</span>
</a>
</li>
{/each}
</ul>
</div>
================================================
FILE: src/lib/translator.ts
================================================
const getLang = (): string => {
// well, maybe base the language from
// -> where the guest coming from? via API to determine their IP Address
// -> or when they're logged in, base it from their
// preferred language by storing that in the hooks
// ohh, you should cache that too, :P
return 'en'
}
const getData = (lang: string) => {
// ofcourse get the data via api, below is just a sample!
const data = {
en: {
Dashboard: 'Dashboard',
'Lorem :ipsum whatever': ':ipsum Lorem Sikador',
'Lorem {ipsum} whatever': '{ipsum} Lorem Sikador',
},
}
return data[lang]
}
export const trans = (text: string, replacers?: any, strict = false): string => {
const lang = getLang()
const data = getData(lang)
let resp = data[text]
if (resp === undefined) {
if (strict) {
throw Error(`Translation for ${text} not found under [${lang}] language.`)
}
resp = text
}
if (replacers !== undefined) {
Object.keys(replacers).forEach((idx) => {
resp = resp.replace(`:${idx}`, replacers[idx]) // Laravel like translations...
resp = resp.replace(`{${idx}}`, replacers[idx]) // maybe uses curly braces? "My {text} whatever"
})
}
return resp
}
export default trans
================================================
FILE: src/routes/admin/(authenticated)/+layout.svelte
================================================
<script lang="ts">
import '$lib/tailwind.css'
import { isDark, isSideMenuOpen, closeSideMenu } from '$stores/menus'
import { clickOutside } from '$lib/ioevents/click'
import { keydownEscape } from '$lib/ioevents/keydown'
import SideBar from '$lib/templates/Admin/SideBar.svelte'
import Header from '$lib/templates/Admin/Header.svelte'
import HtmlHead from '$src/routes/admin/html_head.svelte'
import { browser } from '$app/environment'
if (browser && localStorage.theme === 'dark') {
isDark.update((v) => true)
} else {
isDark.update((v) => false)
}
export let data: any
const user = data.user
</script>
<HtmlHead {isDark} />
<section id="body">
<div class="flex h-screen bg-gray-50 dark:bg-gray-900" class:overflow-hidden={$isSideMenuOpen}>
<!-- Desktop sidebar -->
<aside
class="z-20 hidden w-64 overflow-y-auto bg-white dark:bg-gray-800 md:block flex-shrink-0"
>
<SideBar />
</aside>
<!-- Mobile sidebar -->
<!-- Backdrop -->
{#if $isSideMenuOpen}
<div
class="fixed inset-0 z-10 flex items-end bg-black bg-opacity-50 sm:items-center sm:justify-center"
/>
<aside
class="fixed inset-y-0 z-20 flex-shrink-0 w-64 mt-16 overflow-y-auto bg-white dark:bg-gray-800 md:hidden"
use:clickOutside={['nav-mobile-hamburger']}
on:click-outside={closeSideMenu}
use:keydownEscape
on:keydown-escape={closeSideMenu}
>
<SideBar />
</aside>
{/if}
<div class="flex flex-col flex-1 w-full">
<Header {user} />
<slot />
</div>
</div>
</section>
================================================
FILE: src/routes/admin/(authenticated)/+page.svelte
================================================
<svelte:head>
<title>Dashboard</title>
</svelte:head>
<main class="h-full overflow-y-auto">
<div class="container px-6 mx-auto grid">
<h2 class="my-6 text-2xl font-semibold text-gray-700 dark:text-gray-200">Dashboard</h2>
<!-- CTA -->
<a
class="flex items-center justify-between p-4 mb-8 text-sm font-semibold text-purple-100 bg-purple-600 rounded-lg shadow-md focus:outline-none focus:shadow-outline-purple"
href="https://github.com/daison12006013/sveltekit-windmill-admin"
>
<div class="flex items-center">
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20">
<path
d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"
/>
</svg>
<span>Star this project on GitHub</span>
</div>
<span>View more →</span>
</a>
<!-- Cards -->
<div class="grid gap-6 mb-8 md:grid-cols-2 xl:grid-cols-4">
<!-- Card -->
<div class="flex items-center p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
<div
class="p-3 mr-4 text-orange-500 bg-orange-100 rounded-full dark:text-orange-100 dark:bg-orange-500"
>
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path
d="M13 6a3 3 0 11-6 0 3 3 0 016 0zM18 8a2 2 0 11-4 0 2 2 0 014 0zM14 15a4 4 0 00-8 0v3h8v-3zM6 8a2 2 0 11-4 0 2 2 0 014 0zM16 18v-3a5.972 5.972 0 00-.75-2.906A3.005 3.005 0 0119 15v3h-3zM4.75 12.094A5.973 5.973 0 004 15v3H1v-3a3 3 0 013.75-2.906z"
/>
</svg>
</div>
<div>
<p class="mb-2 text-sm font-medium text-gray-600 dark:text-gray-400">Total clients</p>
<p class="text-lg font-semibold text-gray-700 dark:text-gray-200">6389</p>
</div>
</div>
<!-- Card -->
<div class="flex items-center p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
<div
class="p-3 mr-4 text-green-500 bg-green-100 rounded-full dark:text-green-100 dark:bg-green-500"
>
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
d="M4 4a2 2 0 00-2 2v4a2 2 0 002 2V6h10a2 2 0 00-2-2H4zm2 6a2 2 0 012-2h8a2 2 0 012 2v4a2 2 0 01-2 2H8a2 2 0 01-2-2v-4zm6 4a2 2 0 100-4 2 2 0 000 4z"
clip-rule="evenodd"
/>
</svg>
</div>
<div>
<p class="mb-2 text-sm font-medium text-gray-600 dark:text-gray-400">Account balance</p>
<p class="text-lg font-semibold text-gray-700 dark:text-gray-200">$ 46,760.89</p>
</div>
</div>
<!-- Card -->
<div class="flex items-center p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
<div
class="p-3 mr-4 text-blue-500 bg-blue-100 rounded-full dark:text-blue-100 dark:bg-blue-500"
>
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path
d="M3 1a1 1 0 000 2h1.22l.305 1.222a.997.997 0 00.01.042l1.358 5.43-.893.892C3.74 11.846 4.632 14 6.414 14H15a1 1 0 000-2H6.414l1-1H14a1 1 0 00.894-.553l3-6A1 1 0 0017 3H6.28l-.31-1.243A1 1 0 005 1H3zM16 16.5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zM6.5 18a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"
/>
</svg>
</div>
<div>
<p class="mb-2 text-sm font-medium text-gray-600 dark:text-gray-400">New sales</p>
<p class="text-lg font-semibold text-gray-700 dark:text-gray-200">376</p>
</div>
</div>
<!-- Card -->
<div class="flex items-center p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
<div
class="p-3 mr-4 text-teal-500 bg-teal-100 rounded-full dark:text-teal-100 dark:bg-teal-500"
>
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
d="M18 5v8a2 2 0 01-2 2h-5l-5 4v-4H4a2 2 0 01-2-2V5a2 2 0 012-2h12a2 2 0 012 2zM7 8H5v2h2V8zm2 0h2v2H9V8zm6 0h-2v2h2V8z"
clip-rule="evenodd"
/>
</svg>
</div>
<div>
<p class="mb-2 text-sm font-medium text-gray-600 dark:text-gray-400">Pending contacts</p>
<p class="text-lg font-semibold text-gray-700 dark:text-gray-200">35</p>
</div>
</div>
</div>
<!-- New Table -->
<div class="w-full overflow-hidden rounded-lg shadow-xs">
<div class="w-full overflow-x-auto">
<table class="w-full whitespace-no-wrap">
<thead>
<tr
class="text-xs font-semibold tracking-wide text-left text-gray-500 uppercase border-b dark:border-gray-700 bg-gray-50 dark:text-gray-400 dark:bg-gray-800"
>
<th class="px-4 py-3">Client</th>
<th class="px-4 py-3">Amount</th>
<th class="px-4 py-3">Status</th>
<th class="px-4 py-3">Date</th>
</tr>
</thead>
<tbody class="bg-white divide-y dark:divide-gray-700 dark:bg-gray-800">
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/flagged/photo-1570612861542-284f4c12e75f?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE3Nzg0fQ"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Hans Burger</p>
<p class="text-xs text-gray-600 dark:text-gray-400">10x Developer</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 863.45 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-green-700 bg-green-100 rounded-full dark:bg-green-700 dark:text-green-100"
>
Approved
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&facepad=3&fit=facearea&s=707b9c33066bf8808c934c8ab394dff6"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Jolina Angelie</p>
<p class="text-xs text-gray-600 dark:text-gray-400">Unemployed</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 369.95 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-orange-700 bg-orange-100 rounded-full dark:text-white dark:bg-orange-600"
>
Pending
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/photo-1551069613-1904dbdcda11?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE3Nzg0fQ"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Sarah Curry</p>
<p class="text-xs text-gray-600 dark:text-gray-400">Designer</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 86.00 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-red-700 bg-red-100 rounded-full dark:text-red-100 dark:bg-red-700"
>
Denied
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/photo-1551006917-3b4c078c47c9?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE3Nzg0fQ"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Rulia Joberts</p>
<p class="text-xs text-gray-600 dark:text-gray-400">Actress</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 1276.45 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-green-700 bg-green-100 rounded-full dark:bg-green-700 dark:text-green-100"
>
Approved
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/photo-1546456073-6712f79251bb?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE3Nzg0fQ"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Wenzel Dashington</p>
<p class="text-xs text-gray-600 dark:text-gray-400">Actor</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 863.45 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-gray-700 bg-gray-100 rounded-full dark:text-gray-100 dark:bg-gray-700"
>
Expired
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/photo-1502720705749-871143f0e671?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&s=b8377ca9f985d80264279f277f3a67f5"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Dave Li</p>
<p class="text-xs text-gray-600 dark:text-gray-400">Influencer</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 863.45 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-green-700 bg-green-100 rounded-full dark:bg-green-700 dark:text-green-100"
>
Approved
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/photo-1531746020798-e6953c6e8e04?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE3Nzg0fQ"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Maria Ramovic</p>
<p class="text-xs text-gray-600 dark:text-gray-400">Runner</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 863.45 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-green-700 bg-green-100 rounded-full dark:bg-green-700 dark:text-green-100"
>
Approved
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/photo-1566411520896-01e7ca4726af?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE3Nzg0fQ"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Hitney Wouston</p>
<p class="text-xs text-gray-600 dark:text-gray-400">Singer</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 863.45 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-green-700 bg-green-100 rounded-full dark:bg-green-700 dark:text-green-100"
>
Approved
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/flagged/photo-1570612861542-284f4c12e75f?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE3Nzg0fQ"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Hans Burger</p>
<p class="text-xs text-gray-600 dark:text-gray-400">10x Developer</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 863.45 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-green-700 bg-green-100 rounded-full dark:bg-green-700 dark:text-green-100"
>
Approved
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
</tr>
</tbody>
</table>
</div>
<div
class="grid px-4 py-3 text-xs font-semibold tracking-wide text-gray-500 uppercase border-t dark:border-gray-700 bg-gray-50 sm:grid-cols-9 dark:text-gray-400 dark:bg-gray-800"
>
<span class="flex items-center col-span-3"> Showing 21-30 of 100 </span>
<span class="col-span-2" />
<!-- Pagination -->
<span class="flex col-span-4 mt-2 sm:mt-auto sm:justify-end">
<nav aria-label="Table navigation">
<ul class="inline-flex items-center">
<li>
<button
class="px-3 py-1 rounded-md rounded-l-lg focus:outline-none focus:shadow-outline-purple"
aria-label="Previous"
>
<svg aria-hidden="true" class="w-4 h-4 fill-current" viewBox="0 0 20 20">
<path
d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
clip-rule="evenodd"
fill-rule="evenodd"
/>
</svg>
</button>
</li>
<li>
<button class="px-3 py-1 rounded-md focus:outline-none focus:shadow-outline-purple">
1
</button>
</li>
<li>
<button class="px-3 py-1 rounded-md focus:outline-none focus:shadow-outline-purple">
2
</button>
</li>
<li>
<button
class="px-3 py-1 text-white transition-colors duration-150 bg-purple-600 border border-r-0 border-purple-600 rounded-md focus:outline-none focus:shadow-outline-purple"
>
3
</button>
</li>
<li>
<button class="px-3 py-1 rounded-md focus:outline-none focus:shadow-outline-purple">
4
</button>
</li>
<li>
<span class="px-3 py-1">...</span>
</li>
<li>
<button class="px-3 py-1 rounded-md focus:outline-none focus:shadow-outline-purple">
8
</button>
</li>
<li>
<button class="px-3 py-1 rounded-md focus:outline-none focus:shadow-outline-purple">
9
</button>
</li>
<li>
<button
class="px-3 py-1 rounded-md rounded-r-lg focus:outline-none focus:shadow-outline-purple"
aria-label="Next"
>
<svg class="w-4 h-4 fill-current" aria-hidden="true" viewBox="0 0 20 20">
<path
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
clip-rule="evenodd"
fill-rule="evenodd"
/>
</svg>
</button>
</li>
</ul>
</nav>
</span>
</div>
</div>
<!-- Charts -->
<h2 class="my-6 text-2xl font-semibold text-gray-700 dark:text-gray-200">Charts</h2>
<div class="grid gap-6 mb-8 md:grid-cols-2">
<div class="min-w-0 p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
<h4 class="mb-4 font-semibold text-gray-800 dark:text-gray-300">Revenue</h4>
<canvas id="pie" />
<div class="flex justify-center mt-4 space-x-3 text-sm text-gray-600 dark:text-gray-400">
<!-- Chart legend -->
<div class="flex items-center">
<span class="inline-block w-3 h-3 mr-1 bg-blue-500 rounded-full" />
<span>Shirts</span>
</div>
<div class="flex items-center">
<span class="inline-block w-3 h-3 mr-1 bg-teal-600 rounded-full" />
<span>Shoes</span>
</div>
<div class="flex items-center">
<span class="inline-block w-3 h-3 mr-1 bg-purple-600 rounded-full" />
<span>Bags</span>
</div>
</div>
</div>
<div class="min-w-0 p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
<h4 class="mb-4 font-semibold text-gray-800 dark:text-gray-300">Traffic</h4>
<canvas id="line" />
<div class="flex justify-center mt-4 space-x-3 text-sm text-gray-600 dark:text-gray-400">
<!-- Chart legend -->
<div class="flex items-center">
<span class="inline-block w-3 h-3 mr-1 bg-teal-600 rounded-full" />
<span>Organic</span>
</div>
<div class="flex items-center">
<span class="inline-block w-3 h-3 mr-1 bg-purple-600 rounded-full" />
<span>Paid</span>
</div>
</div>
</div>
</div>
</div>
</main>
================================================
FILE: src/routes/admin/(authenticated)/buttons/+page.svelte
================================================
<svelte:head>
<title>Buttons</title>
</svelte:head>
<main class="h-full overflow-y-auto">
<div class="container grid px-6 mx-auto">
<h2 class="my-6 text-2xl font-semibold text-gray-700 dark:text-gray-200">Buttons</h2>
<!-- CTA -->
<a
class="flex items-center justify-between p-4 mb-8 text-sm font-semibold text-purple-100 bg-purple-600 rounded-lg shadow-md focus:outline-none focus:shadow-outline-purple"
href="https://github.com/daison12006013/sveltekit-windmill-admin"
>
<div class="flex items-center">
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20">
<path
d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"
/>
</svg>
<span>Star this project on GitHub</span>
</div>
<span>View more →</span>
</a>
<!-- Button sizes -->
<h4 class="mb-4 text-lg font-semibold text-gray-600 dark:text-gray-300">Sizes</h4>
<div class="flex flex-col flex-wrap mb-4 space-y-4 md:flex-row md:items-end md:space-x-4">
<!-- Divs are used just to display the examples. Use only the button. -->
<div>
<button
class="px-10 py-4 font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-lg active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"
>
Larger button
</button>
</div>
<!-- Divs are used just to display the examples. Use only the button. -->
<div>
<button
class="px-5 py-3 font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-lg active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"
>
Large button
</button>
</div>
<!-- Divs are used just to display the examples. Use only the button. -->
<div>
<button
class="px-4 py-2 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-lg active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"
>
Regular
</button>
</div>
<!-- Divs are used just to display the examples. Use only the button. -->
<div>
<!-- For disabled buttons ADD these classes:
opacity-50 cursor-not-allowed
And REMOVE these classes:
active:bg-purple-600 hover:bg-purple-700 focus:shadow-outline-purple
-->
<button
class="px-4 py-2 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-lg opacity-50 cursor-not-allowed focus:outline-none"
>
Disabled
</button>
</div>
<!-- Divs are used just to display the examples. Use only the button. -->
<div>
<button
class="px-3 py-1 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-md active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"
>
Small
</button>
</div>
</div>
<p class="mb-8 text-gray-700 dark:text-gray-400">
Apply
<code>w-full</code>
to any button to create a block level button.
</p>
<!-- Buttons with icons -->
<h4 class="mb-4 text-lg font-semibold text-gray-600 dark:text-gray-300">Icons</h4>
<div class="flex flex-col flex-wrap mb-8 space-y-4 md:flex-row md:items-end md:space-x-4">
<!-- Divs are used just to display the examples. Use only the button. -->
<div>
<button
class="flex items-center justify-between px-4 py-2 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-lg active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"
>
<span>Icon right</span>
<svg
class="w-4 h-4 ml-2 -mr-1"
fill="currentColor"
aria-hidden="true"
viewBox="0 0 20 20"
>
<path
d="M3.172 5.172a4 4 0 015.656 0L10 6.343l1.172-1.171a4 4 0 115.656 5.656L10 17.657l-6.828-6.829a4 4 0 010-5.656z"
clip-rule="evenodd"
fill-rule="evenodd"
/>
</svg>
</button>
</div>
<!-- Divs are used just to display the examples. Use only the button. -->
<div>
<button
class="flex items-center justify-between px-4 py-2 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-lg active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"
>
<svg
class="w-4 h-4 mr-2 -ml-1"
fill="currentColor"
aria-hidden="true"
viewBox="0 0 20 20"
>
<path
d="M3.172 5.172a4 4 0 015.656 0L10 6.343l1.172-1.171a4 4 0 115.656 5.656L10 17.657l-6.828-6.829a4 4 0 010-5.656z"
clip-rule="evenodd"
fill-rule="evenodd"
/>
</svg>
<span>Icon left</span>
</button>
</div>
<!-- Divs are used just to display the examples. Use only the button. -->
<div>
<button
class="flex items-center justify-between px-2 py-2 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-lg active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"
aria-label="Like"
>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
d="M3.172 5.172a4 4 0 015.656 0L10 6.343l1.172-1.171a4 4 0 115.656 5.656L10 17.657l-6.828-6.829a4 4 0 010-5.656z"
clip-rule="evenodd"
fill-rule="evenodd"
/>
</svg>
</button>
</div>
<!-- Divs are used just to display the examples. Use only the button. -->
<div>
<button
class="flex items-center justify-between px-2 py-2 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-full active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"
aria-label="Edit"
>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z"
/>
</svg>
</button>
</div>
</div>
</div>
</main>
================================================
FILE: src/routes/admin/(authenticated)/cards/+page.svelte
================================================
<svelte:head>
<title>Cards</title>
</svelte:head>
<main class="h-full pb-16 overflow-y-auto">
<div class="container px-6 mx-auto grid">
<h2 class="my-6 text-2xl font-semibold text-gray-700 dark:text-gray-200">Cards</h2>
<!-- CTA -->
<a
class="flex items-center justify-between p-4 mb-8 text-sm font-semibold text-purple-100 bg-purple-600 rounded-lg shadow-md focus:outline-none focus:shadow-outline-purple"
href="https://github.com/daison12006013/sveltekit-windmill-admin"
>
<div class="flex items-center">
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20">
<path
d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"
/>
</svg>
<span>Star this project on GitHub</span>
</div>
<span>View more →</span>
</a>
<!-- Big section cards -->
<h4 class="mb-4 text-lg font-semibold text-gray-600 dark:text-gray-300">Big section cards</h4>
<div class="px-4 py-3 mb-8 bg-white rounded-lg shadow-md dark:bg-gray-800">
<p class="text-sm text-gray-600 dark:text-gray-400">Large, full width sections goes here</p>
</div>
<!-- Responsive cards -->
<h4 class="mb-4 text-lg font-semibold text-gray-600 dark:text-gray-300">Responsive cards</h4>
<div class="grid gap-6 mb-8 md:grid-cols-2 xl:grid-cols-4">
<!-- Card -->
<div class="flex items-center p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
<div
class="p-3 mr-4 text-orange-500 bg-orange-100 rounded-full dark:text-orange-100 dark:bg-orange-500"
>
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path
d="M13 6a3 3 0 11-6 0 3 3 0 016 0zM18 8a2 2 0 11-4 0 2 2 0 014 0zM14 15a4 4 0 00-8 0v3h8v-3zM6 8a2 2 0 11-4 0 2 2 0 014 0zM16 18v-3a5.972 5.972 0 00-.75-2.906A3.005 3.005 0 0119 15v3h-3zM4.75 12.094A5.973 5.973 0 004 15v3H1v-3a3 3 0 013.75-2.906z"
/>
</svg>
</div>
<div>
<p class="mb-2 text-sm font-medium text-gray-600 dark:text-gray-400">Total clients</p>
<p class="text-lg font-semibold text-gray-700 dark:text-gray-200">6389</p>
</div>
</div>
<!-- Card -->
<div class="flex items-center p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
<div
class="p-3 mr-4 text-green-500 bg-green-100 rounded-full dark:text-green-100 dark:bg-green-500"
>
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
d="M4 4a2 2 0 00-2 2v4a2 2 0 002 2V6h10a2 2 0 00-2-2H4zm2 6a2 2 0 012-2h8a2 2 0 012 2v4a2 2 0 01-2 2H8a2 2 0 01-2-2v-4zm6 4a2 2 0 100-4 2 2 0 000 4z"
clip-rule="evenodd"
/>
</svg>
</div>
<div>
<p class="mb-2 text-sm font-medium text-gray-600 dark:text-gray-400">Account balance</p>
<p class="text-lg font-semibold text-gray-700 dark:text-gray-200">$ 46,760.89</p>
</div>
</div>
<!-- Card -->
<div class="flex items-center p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
<div
class="p-3 mr-4 text-blue-500 bg-blue-100 rounded-full dark:text-blue-100 dark:bg-blue-500"
>
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path
d="M3 1a1 1 0 000 2h1.22l.305 1.222a.997.997 0 00.01.042l1.358 5.43-.893.892C3.74 11.846 4.632 14 6.414 14H15a1 1 0 000-2H6.414l1-1H14a1 1 0 00.894-.553l3-6A1 1 0 0017 3H6.28l-.31-1.243A1 1 0 005 1H3zM16 16.5a1.5 1.5 0 11-3 0 1.5 1.5 0 013 0zM6.5 18a1.5 1.5 0 100-3 1.5 1.5 0 000 3z"
/>
</svg>
</div>
<div>
<p class="mb-2 text-sm font-medium text-gray-600 dark:text-gray-400">New sales</p>
<p class="text-lg font-semibold text-gray-700 dark:text-gray-200">376</p>
</div>
</div>
<!-- Card -->
<div class="flex items-center p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
<div
class="p-3 mr-4 text-teal-500 bg-teal-100 rounded-full dark:text-teal-100 dark:bg-teal-500"
>
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
d="M18 5v8a2 2 0 01-2 2h-5l-5 4v-4H4a2 2 0 01-2-2V5a2 2 0 012-2h12a2 2 0 012 2zM7 8H5v2h2V8zm2 0h2v2H9V8zm6 0h-2v2h2V8z"
clip-rule="evenodd"
/>
</svg>
</div>
<div>
<p class="mb-2 text-sm font-medium text-gray-600 dark:text-gray-400">Pending contacts</p>
<p class="text-lg font-semibold text-gray-700 dark:text-gray-200">35</p>
</div>
</div>
</div>
<!-- Cards with title -->
<h4 class="mb-4 text-lg font-semibold text-gray-600 dark:text-gray-300">Cards with title</h4>
<div class="grid gap-6 mb-8 md:grid-cols-2">
<div class="min-w-0 p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
<h4 class="mb-4 font-semibold text-gray-600 dark:text-gray-300">Revenue</h4>
<p class="text-gray-600 dark:text-gray-400">
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fuga, cum commodi a omnis
numquam quod? Totam exercitationem quos hic ipsam at qui cum numquam, sed amet ratione!
Ratione, nihil dolorum.
</p>
</div>
<div class="min-w-0 p-4 text-white bg-purple-600 rounded-lg shadow-xs">
<h4 class="mb-4 font-semibold">Colored card</h4>
<p>
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Fuga, cum commodi a omnis
numquam quod? Totam exercitationem quos hic ipsam at qui cum numquam, sed amet ratione!
Ratione, nihil dolorum.
</p>
</div>
</div>
</div>
</main>
================================================
FILE: src/routes/admin/(authenticated)/charts/+page.svelte
================================================
<script lang="ts">
// import { barConfig, lineConfig, pieConfig } from '$lib/templates/Admin/Config/charts'
// import Bar from 'svelte-chartjs/src/Bar.svelte'
// import Line from 'svelte-chartjs/src/Line.svelte'
// import Pie from 'svelte-chartjs/src/Pie.svelte'
import _i from '$lib/translator'
</script>
<svelte:head>
<title>{_i('Charts')}</title>
</svelte:head>
<main class="h-full pb-16 overflow-y-auto">
<div class="container px-6 mx-auto grid">
<h2 class="my-6 text-2xl font-semibold text-gray-700 dark:text-gray-200">Charts</h2>
<!-- CTA -->
<a
class="flex items-center justify-between p-4 mb-8 text-sm font-semibold text-purple-100 bg-purple-600 rounded-lg shadow-md focus:outline-none focus:shadow-outline-purple"
href="https://github.com/daison12006013/sveltekit-windmill-admin"
>
<div class="flex items-center">
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20">
<path
d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"
/>
</svg>
<span>{_i('Star this project on GitHub')}</span>
</div>
<span>{_i('View more')} →</span>
</a>
<p class="mb-8 text-gray-600 dark:text-gray-400">
{_i('Charts are provided by')}
<a
class="text-purple-600 dark:text-purple-400 hover:underline"
href="https://www.chartjs.org/"
>
{_i('Chart.js')}
</a>
. {_i(
'Note that the default legends are disabled and you should provide a description for your charts in HTML. See source code for examples.'
)}
</p>
<div class="grid gap-6 mb-8 md:grid-cols-2">
<!-- Doughnut/Pie chart -->
<div class="min-w-0 p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
<h4 class="mb-4 font-semibold text-gray-800 dark:text-gray-300">Doughnut/Pie</h4>
<!-- <Pie data={pieConfig} /> -->
<div class="flex justify-center mt-4 space-x-3 text-sm text-gray-600 dark:text-gray-400">
<!-- Chart legend -->
<div class="flex items-center">
<span class="inline-block w-3 h-3 mr-1 bg-blue-600 rounded-full" />
<span>{_i('Shirts')}</span>
</div>
<div class="flex items-center">
<span class="inline-block w-3 h-3 mr-1 bg-teal-500 rounded-full" />
<span>{_i('Shoes')}</span>
</div>
<div class="flex items-center">
<span class="inline-block w-3 h-3 mr-1 bg-purple-600 rounded-full" />
<span>{_i('Bags')}</span>
</div>
</div>
</div>
<!-- Lines chart -->
<div class="min-w-0 p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
<h4 class="mb-4 font-semibold text-gray-800 dark:text-gray-300">Lines</h4>
<!-- <Line data={lineConfig} /> -->
<div class="flex justify-center mt-4 space-x-3 text-sm text-gray-600 dark:text-gray-400">
<!-- Chart legend -->
<div class="flex items-center">
<span class="inline-block w-3 h-3 mr-1 bg-teal-500 rounded-full" />
<span>Organic</span>
</div>
<div class="flex items-center">
<span class="inline-block w-3 h-3 mr-1 bg-purple-600 rounded-full" />
<span>Paid</span>
</div>
</div>
</div>
<!-- Bars chart -->
<div class="min-w-0 p-4 bg-white rounded-lg shadow-xs dark:bg-gray-800">
<h4 class="mb-4 font-semibold text-gray-800 dark:text-gray-300">Bars</h4>
<!-- <Bar data={barConfig} /> -->
<div class="flex justify-center mt-4 space-x-3 text-sm text-gray-600 dark:text-gray-400">
<!-- Chart legend -->
<div class="flex items-center">
<span class="inline-block w-3 h-3 mr-1 bg-teal-500 rounded-full" />
<span>{_i('Shoes')}</span>
</div>
<div class="flex items-center">
<span class="inline-block w-3 h-3 mr-1 bg-purple-600 rounded-full" />
<span>{_i('Bags')}</span>
</div>
</div>
</div>
</div>
</div>
</main>
================================================
FILE: src/routes/admin/(authenticated)/components/+page.svelte
================================================
<script lang="ts">
import DocAccordion from '$lib/components/Docs/DocAccordion.svelte'
import DocAlert from '$lib/components/Docs/DocAlert.svelte'
import DocBadge from '$lib/components/Docs/DocBadge.svelte'
import Breadcrumb from '$lib/components/Breadcrumb.svelte'
import ButtonGroup from '$lib/components/ButtonGroup.svelte'
import Card from '$lib/components/Card.svelte'
import Carousel from '$lib/components/Carousel.svelte'
import CloseButton from '$lib/components/CloseButton.svelte'
import Code from '$lib/components/Code.svelte'
import Collapse from '$lib/components/Collapse.svelte'
import Dropdowns from '$lib/components/Dropdowns.svelte'
import ListGroup from '$lib/components/ListGroup.svelte'
import Modal from '$lib/components/Modal.svelte'
import NavsAndTabs from '$lib/components/NavsAndTabs.svelte'
import Pagination from '$lib/components/Pagination.svelte'
import Popovers from '$lib/components/Popovers.svelte'
import Spinners from '$lib/components/Spinners.svelte'
import Toasts from '$lib/components/Toasts.svelte'
import Tooltips from '$lib/components/Tooltips.svelte'
const showScript = (elem: string) => {
console.log(document.getElementById(elem).innerHTML)
}
</script>
<svelte:head>
<title>Components</title>
</svelte:head>
<main class="h-full overflow-y-auto">
<div class="bg-gray-50 dark:bg-gray-900 dark:text-white">
<div class="container px-6 mx-auto grid">
<div class="mt-5 pb-5">
<DocAccordion />
</div>
<hr />
<div class="pb-5">
<DocAlert />
</div>
<hr />
<div class="pb-5">
<DocBadge />
</div>
<hr />
<Breadcrumb />
<ButtonGroup />
<Card />
<Carousel />
<CloseButton />
<Collapse />
<Dropdowns />
<ListGroup />
<Modal />
<NavsAndTabs />
<Pagination />
<Popovers />
<Spinners />
<Toasts />
<Tooltips />
</div>
</div>
</main>
<style>
hr {
@apply border;
@apply text-gray-500;
@apply m-10;
}
</style>
================================================
FILE: src/routes/admin/(authenticated)/forms/+page.svelte
================================================
<svelte:head>
<title>Forms</title>
</svelte:head>
<main class="h-full pb-16 overflow-y-auto">
<div class="container px-6 mx-auto grid">
<h2 class="my-6 text-2xl font-semibold text-gray-700 dark:text-gray-200">Forms</h2>
<!-- CTA -->
<a
class="flex items-center justify-between p-4 mb-8 text-sm font-semibold text-purple-100 bg-purple-600 rounded-lg shadow-md focus:outline-none focus:shadow-outline-purple"
href="https://github.com/daison12006013/sveltekit-windmill-admin"
>
<div class="flex items-center">
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20">
<path
d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"
/>
</svg>
<span>Star this project on GitHub</span>
</div>
<span>View more →</span>
</a>
<!-- General elements -->
<h4 class="mb-4 text-lg font-semibold text-gray-600 dark:text-gray-300">Elements</h4>
<div class="px-4 py-3 mb-8 bg-white rounded-lg shadow-md dark:bg-gray-800">
<label class="block text-sm">
<span class="text-gray-700 dark:text-gray-400">Name</span>
<input
class="block w-full mt-1 text-sm dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray form-input"
placeholder="Jane Doe"
/>
</label>
<div class="mt-4 text-sm">
<span class="text-gray-700 dark:text-gray-400"> Account Type </span>
<div class="mt-2">
<label class="inline-flex items-center text-gray-600 dark:text-gray-400">
<input
type="radio"
class="text-purple-600 form-radio focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray"
name="accountType"
value="personal"
/>
<span class="ml-2">Personal</span>
</label>
<label class="inline-flex items-center ml-6 text-gray-600 dark:text-gray-400">
<input
type="radio"
class="text-purple-600 form-radio focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray"
name="accountType"
value="busines"
/>
<span class="ml-2">Business</span>
</label>
</div>
</div>
<label class="block mt-4 text-sm">
<span class="text-gray-700 dark:text-gray-400"> Requested Limit </span>
<select
class="block w-full mt-1 text-sm dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700 form-select focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray"
>
<option>$1,000</option>
<option>$5,000</option>
<option>$10,000</option>
<option>$25,000</option>
</select>
</label>
<label class="block mt-4 text-sm">
<span class="text-gray-700 dark:text-gray-400"> Multiselect </span>
<select
class="block w-full mt-1 text-sm dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700 form-multiselect focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray"
multiple
>
<option>Option 1</option>
<option>Option 2</option>
<option>Option 3</option>
<option>Option 4</option>
<option>Option 5</option>
</select>
</label>
<label class="block mt-4 text-sm">
<span class="text-gray-700 dark:text-gray-400">Message</span>
<textarea
class="block w-full mt-1 text-sm dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700 form-textarea focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray"
rows="3"
placeholder="Enter some long form content."
/>
</label>
<div class="flex mt-6 text-sm">
<label class="flex items-center dark:text-gray-400">
<input
type="checkbox"
class="text-purple-600 form-checkbox focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray"
/>
<span class="ml-2">
I agree to the
<span class="underline">privacy policy</span>
</span>
</label>
</div>
</div>
<!-- Validation inputs -->
<h4 class="mb-4 text-lg font-semibold text-gray-600 dark:text-gray-300">Validation</h4>
<div class="px-4 py-3 mb-8 bg-white rounded-lg shadow-md dark:bg-gray-800">
<!-- Invalid input -->
<label class="block text-sm">
<span class="text-gray-700 dark:text-gray-400"> Invalid input </span>
<input
class="block w-full mt-1 text-sm border-red-600 dark:text-gray-300 dark:bg-gray-700 focus:border-red-400 focus:outline-none focus:shadow-outline-red form-input"
placeholder="Jane Doe"
/>
<span class="text-xs text-red-600 dark:text-red-400"> Your password is too short. </span>
</label>
<!-- Valid input -->
<label class="block mt-4 text-sm">
<span class="text-gray-700 dark:text-gray-400"> Valid input </span>
<input
class="block w-full mt-1 text-sm border-green-600 dark:text-gray-300 dark:bg-gray-700 focus:border-green-400 focus:outline-none focus:shadow-outline-green form-input"
placeholder="Jane Doe"
/>
<span class="text-xs text-green-600 dark:text-green-400"> Your password is strong. </span>
</label>
<!-- Helper text -->
<label class="block mt-4 text-sm">
<span class="text-gray-700 dark:text-gray-400"> Helper text </span>
<input
class="block w-full mt-1 text-sm dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray form-input"
placeholder="Jane Doe"
/>
<span class="text-xs text-gray-600 dark:text-gray-400">
Your password must be at least 6 characters long.
</span>
</label>
</div>
<!-- Inputs with icons -->
<h4 class="mb-4 text-lg font-semibold text-gray-600 dark:text-gray-300">Icons</h4>
<div class="px-4 py-3 mb-8 bg-white rounded-lg shadow-md dark:bg-gray-800">
<label class="block text-sm">
<span class="text-gray-700 dark:text-gray-400">Icon left</span>
<!-- focus-within sets the color for the icon when input is focused -->
<div
class="relative text-gray-500 focus-within:text-purple-600 dark:focus-within:text-purple-400"
>
<input
class="block w-full pl-10 mt-1 text-sm text-black dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray form-input"
placeholder="Jane Doe"
/>
<div class="absolute inset-y-0 flex items-center ml-3 pointer-events-none">
<svg
class="w-5 h-5"
aria-hidden="true"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
/>
</svg>
</div>
</div>
</label>
<label class="block mt-4 text-sm">
<span class="text-gray-700 dark:text-gray-400">Icon right</span>
<!-- focus-within sets the color for the icon when input is focused -->
<div
class="relative text-gray-500 focus-within:text-purple-600 dark:focus-within:text-purple-400"
>
<input
class="block w-full pr-10 mt-1 text-sm text-black dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray form-input"
placeholder="Jane Doe"
/>
<div class="absolute inset-y-0 right-0 flex items-center mr-3 pointer-events-none">
<svg
class="w-5 h-5"
aria-hidden="true"
fill="none"
stroke-linecap="round"
stroke-linejoin="round"
stroke-width="2"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
d="M3 8l7.89 5.26a2 2 0 002.22 0L21 8M5 19h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z"
/>
</svg>
</div>
</div>
</label>
</div>
<!-- Inputs with buttons -->
<h4 class="mb-4 text-lg font-semibold text-gray-600 dark:text-gray-300">Buttons</h4>
<div class="px-4 py-3 mb-8 bg-white rounded-lg shadow-md dark:bg-gray-800">
<label class="block text-sm">
<span class="text-gray-700 dark:text-gray-400"> Button left </span>
<div class="relative">
<input
class="block w-full pl-20 mt-1 text-sm dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray form-input"
placeholder="Jane Doe"
/>
<button
class="absolute inset-y-0 px-4 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-l-md active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray"
>
Click
</button>
</div>
</label>
<label class="block mt-4 text-sm">
<span class="text-gray-700 dark:text-gray-400"> Button right </span>
<div class="relative text-gray-500 focus-within:text-purple-600">
<input
class="block w-full pr-20 mt-1 text-sm text-black dark:text-gray-300 dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray form-input"
placeholder="Jane Doe"
/>
<button
class="absolute inset-y-0 right-0 px-4 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-r-md active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"
>
Click
</button>
</div>
</label>
</div>
</div>
</main>
================================================
FILE: src/routes/admin/(authenticated)/modals/+page.svelte
================================================
<script lang="ts">
import { clickOutside } from '$lib/ioevents/click'
import { keydownEscape } from '$lib/ioevents/keydown'
let isModalOpen = false
const openModal = () => {
isModalOpen = true
}
const closeModal = () => {
isModalOpen = false
}
</script>
<svelte:head>
<title>Modals</title>
</svelte:head>
<!-- Modal backdrop. This what you want to place close to the closing body tag -->
<div
class:hidden={!isModalOpen}
class="fixed inset-0 z-30 flex items-end bg-black bg-opacity-50 sm:items-center sm:justify-center"
>
<!-- Modal -->
<div
class:hidden={!isModalOpen}
use:clickOutside
on:click-outside={closeModal}
use:keydownEscape
on:keydown-escape={closeModal}
class="w-full px-6 py-4 overflow-hidden bg-white rounded-t-lg dark:bg-gray-800 sm:rounded-lg sm:m-4 sm:max-w-xl"
role="dialog"
id="modal"
>
<!-- Remove header if you don't want a close icon. Use modal body to place modal tile. -->
<header class="flex justify-end">
<button
class="inline-flex items-center justify-center w-6 h-6 text-gray-400 transition-colors duration-150 rounded dark:hover:text-gray-200 hover: hover:text-gray-700"
aria-label="close"
on:click={closeModal}
>
<svg class="w-4 h-4" fill="currentColor" viewBox="0 0 20 20" role="img" aria-hidden="true">
<path
d="M4.293 4.293a1 1 0 011.414 0L10 8.586l4.293-4.293a1 1 0 111.414 1.414L11.414 10l4.293 4.293a1 1 0 01-1.414 1.414L10 11.414l-4.293 4.293a1 1 0 01-1.414-1.414L8.586 10 4.293 5.707a1 1 0 010-1.414z"
clip-rule="evenodd"
fill-rule="evenodd"
/>
</svg>
</button>
</header>
<!-- Modal body -->
<div class="mt-4 mb-6">
<!-- Modal title -->
<p class="mb-2 text-lg font-semibold text-gray-700 dark:text-gray-300">Modal header</p>
<!-- Modal description -->
<p class="text-sm text-gray-700 dark:text-gray-400">
Lorem, ipsum dolor sit amet consectetur adipisicing elit. Nostrum et eligendi repudiandae
voluptatem tempore!
</p>
</div>
<footer
class="flex flex-col items-center justify-end px-6 py-3 -mx-6 -mb-4 space-y-4 sm:space-y-0 sm:space-x-6 sm:flex-row bg-gray-50 dark:bg-gray-800"
>
<button
on:click={closeModal}
class="w-full px-5 py-3 text-sm font-medium leading-5 text-gray-700 transition-colors duration-150 border border-gray-300 rounded-lg dark:text-gray-400 sm:px-4 sm:py-2 sm:w-auto active:bg-transparent hover:border-gray-500 focus:border-gray-500 active:text-gray-500 focus:outline-none focus:shadow-outline-gray"
>
Cancel
</button>
<button
class="w-full px-5 py-3 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-lg sm:w-auto sm:px-4 sm:py-2 active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"
>
Accept
</button>
</footer>
</div>
</div>
<main class="h-full pb-16 overflow-y-auto">
<div class="container grid px-6 mx-auto">
<h2 class="my-6 text-2xl font-semibold text-gray-700 dark:text-gray-200">Modals</h2>
<!-- CTA -->
<a
class="flex items-center justify-between p-4 mb-8 text-sm font-semibold text-purple-100 bg-purple-600 rounded-lg shadow-md focus:outline-none focus:shadow-outline-purple"
href="https://github.com/daison12006013/sveltekit-windmill-admin"
>
<div class="flex items-center">
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20">
<path
d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"
/>
</svg>
<span>Star this project on GitHub</span>
</div>
<span>View more →</span>
</a>
<div class="max-w-2xl px-4 py-3 mb-8 bg-white rounded-lg shadow-md dark:bg-gray-800">
<p class="mb-4 text-gray-600 dark:text-gray-400">
This is possibly
<strong>the most accessible a modal can get</strong>
, using JavaScript. When opened, it uses
<code>assets/js/focus-trap.js</code>
to create a
<em>focus trap</em>
, which means that if you use your keyboard to navigate around, focus won't leak to the elements
behind, staying inside the modal in a loop, until you take any action.
</p>
<p class="text-gray-600 dark:text-gray-400">
Also, on small screens it is placed at the bottom of the screen, to account for larger
devices and make it easier to click the larger buttons.
</p>
</div>
<div>
<button
on:click={openModal}
class="px-4 py-2 text-sm font-medium leading-5 text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-lg active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"
>
Open Modal
</button>
</div>
</div>
</main>
================================================
FILE: src/routes/admin/(authenticated)/tables/+page.svelte
================================================
<svelte:head>
<title>Tables</title>
</svelte:head>
<main class="h-full pb-16 overflow-y-auto">
<div class="container grid px-6 mx-auto">
<h2 class="my-6 text-2xl font-semibold text-gray-700 dark:text-gray-200">Tables</h2>
<!-- CTA -->
<a
class="flex items-center justify-between p-4 mb-8 text-sm font-semibold text-purple-100 bg-purple-600 rounded-lg shadow-md focus:outline-none focus:shadow-outline-purple"
href="https://github.com/daison12006013/sveltekit-windmill-admin"
>
<div class="flex items-center">
<svg class="w-5 h-5 mr-2" fill="currentColor" viewBox="0 0 20 20">
<path
d="M9.049 2.927c.3-.921 1.603-.921 1.902 0l1.07 3.292a1 1 0 00.95.69h3.462c.969 0 1.371 1.24.588 1.81l-2.8 2.034a1 1 0 00-.364 1.118l1.07 3.292c.3.921-.755 1.688-1.54 1.118l-2.8-2.034a1 1 0 00-1.175 0l-2.8 2.034c-.784.57-1.838-.197-1.539-1.118l1.07-3.292a1 1 0 00-.364-1.118L2.98 8.72c-.783-.57-.38-1.81.588-1.81h3.461a1 1 0 00.951-.69l1.07-3.292z"
/>
</svg>
<span>Star this project on GitHub</span>
</div>
<span>View more →</span>
</a>
<!-- With avatar -->
<h4 class="mb-4 text-lg font-semibold text-gray-600 dark:text-gray-300">Table with avatars</h4>
<div class="w-full mb-8 overflow-hidden rounded-lg shadow-xs">
<div class="w-full overflow-x-auto">
<table class="w-full whitespace-no-wrap">
<thead>
<tr
class="text-xs font-semibold tracking-wide text-left text-gray-500 uppercase border-b dark:border-gray-700 bg-gray-50 dark:text-gray-400 dark:bg-gray-800"
>
<th class="px-4 py-3">Client</th>
<th class="px-4 py-3">Amount</th>
<th class="px-4 py-3">Status</th>
<th class="px-4 py-3">Date</th>
</tr>
</thead>
<tbody class="bg-white divide-y dark:divide-gray-700 dark:bg-gray-800">
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/flagged/photo-1570612861542-284f4c12e75f?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE3Nzg0fQ"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Hans Burger</p>
<p class="text-xs text-gray-600 dark:text-gray-400">10x Developer</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 863.45 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-green-700 bg-green-100 rounded-full dark:bg-green-700 dark:text-green-100"
>
Approved
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&facepad=3&fit=facearea&s=707b9c33066bf8808c934c8ab394dff6"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Jolina Angelie</p>
<p class="text-xs text-gray-600 dark:text-gray-400">Unemployed</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 369.95 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-orange-700 bg-orange-100 rounded-full dark:text-white dark:bg-orange-600"
>
Pending
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/photo-1551069613-1904dbdcda11?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE3Nzg0fQ"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Sarah Curry</p>
<p class="text-xs text-gray-600 dark:text-gray-400">Designer</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 86.00 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-red-700 bg-red-100 rounded-full dark:text-red-100 dark:bg-red-700"
>
Denied
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/photo-1551006917-3b4c078c47c9?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE3Nzg0fQ"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Rulia Joberts</p>
<p class="text-xs text-gray-600 dark:text-gray-400">Actress</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 1276.45 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-green-700 bg-green-100 rounded-full dark:bg-green-700 dark:text-green-100"
>
Approved
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/photo-1546456073-6712f79251bb?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE3Nzg0fQ"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Wenzel Dashington</p>
<p class="text-xs text-gray-600 dark:text-gray-400">Actor</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 863.45 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-gray-700 bg-gray-100 rounded-full dark:text-gray-100 dark:bg-gray-700"
>
Expired
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/photo-1502720705749-871143f0e671?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&s=b8377ca9f985d80264279f277f3a67f5"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Dave Li</p>
<p class="text-xs text-gray-600 dark:text-gray-400">Influencer</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 863.45 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-green-700 bg-green-100 rounded-full dark:bg-green-700 dark:text-green-100"
>
Approved
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/photo-1531746020798-e6953c6e8e04?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE3Nzg0fQ"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Maria Ramovic</p>
<p class="text-xs text-gray-600 dark:text-gray-400">Runner</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 863.45 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-green-700 bg-green-100 rounded-full dark:bg-green-700 dark:text-green-100"
>
Approved
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/photo-1566411520896-01e7ca4726af?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE3Nzg0fQ"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Hitney Wouston</p>
<p class="text-xs text-gray-600 dark:text-gray-400">Singer</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 863.45 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-green-700 bg-green-100 rounded-full dark:bg-green-700 dark:text-green-100"
>
Approved
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/flagged/photo-1570612861542-284f4c12e75f?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE3Nzg0fQ"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Hans Burger</p>
<p class="text-xs text-gray-600 dark:text-gray-400">10x Developer</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 863.45 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-green-700 bg-green-100 rounded-full dark:bg-green-700 dark:text-green-100"
>
Approved
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
</tr>
</tbody>
</table>
</div>
<div
class="grid px-4 py-3 text-xs font-semibold tracking-wide text-gray-500 uppercase border-t dark:border-gray-700 bg-gray-50 sm:grid-cols-9 dark:text-gray-400 dark:bg-gray-800"
>
<span class="flex items-center col-span-3"> Showing 21-30 of 100 </span>
<span class="col-span-2" />
<!-- Pagination -->
<span class="flex col-span-4 mt-2 sm:mt-auto sm:justify-end">
<nav aria-label="Table navigation">
<ul class="inline-flex items-center">
<li>
<button
class="px-3 py-1 rounded-md rounded-l-lg focus:outline-none focus:shadow-outline-purple"
aria-label="Previous"
>
<svg aria-hidden="true" class="w-4 h-4 fill-current" viewBox="0 0 20 20">
<path
d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
clip-rule="evenodd"
fill-rule="evenodd"
/>
</svg>
</button>
</li>
<li>
<button class="px-3 py-1 rounded-md focus:outline-none focus:shadow-outline-purple">
1
</button>
</li>
<li>
<button class="px-3 py-1 rounded-md focus:outline-none focus:shadow-outline-purple">
2
</button>
</li>
<li>
<button
class="px-3 py-1 text-white transition-colors duration-150 bg-purple-600 border border-r-0 border-purple-600 rounded-md focus:outline-none focus:shadow-outline-purple"
>
3
</button>
</li>
<li>
<button class="px-3 py-1 rounded-md focus:outline-none focus:shadow-outline-purple">
4
</button>
</li>
<li>
<span class="px-3 py-1">...</span>
</li>
<li>
<button class="px-3 py-1 rounded-md focus:outline-none focus:shadow-outline-purple">
8
</button>
</li>
<li>
<button class="px-3 py-1 rounded-md focus:outline-none focus:shadow-outline-purple">
9
</button>
</li>
<li>
<button
class="px-3 py-1 rounded-md rounded-r-lg focus:outline-none focus:shadow-outline-purple"
aria-label="Next"
>
<svg class="w-4 h-4 fill-current" aria-hidden="true" viewBox="0 0 20 20">
<path
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
clip-rule="evenodd"
fill-rule="evenodd"
/>
</svg>
</button>
</li>
</ul>
</nav>
</span>
</div>
</div>
<!-- With actions -->
<h4 class="mb-4 text-lg font-semibold text-gray-600 dark:text-gray-300">Table with actions</h4>
<div class="w-full overflow-hidden rounded-lg shadow-xs">
<div class="w-full overflow-x-auto">
<table class="w-full whitespace-no-wrap">
<thead>
<tr
class="text-xs font-semibold tracking-wide text-left text-gray-500 uppercase border-b dark:border-gray-700 bg-gray-50 dark:text-gray-400 dark:bg-gray-800"
>
<th class="px-4 py-3">Client</th>
<th class="px-4 py-3">Amount</th>
<th class="px-4 py-3">Status</th>
<th class="px-4 py-3">Date</th>
<th class="px-4 py-3">Actions</th>
</tr>
</thead>
<tbody class="bg-white divide-y dark:divide-gray-700 dark:bg-gray-800">
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/flagged/photo-1570612861542-284f4c12e75f?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE3Nzg0fQ"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Hans Burger</p>
<p class="text-xs text-gray-600 dark:text-gray-400">10x Developer</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 863.45 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-green-700 bg-green-100 rounded-full dark:bg-green-700 dark:text-green-100"
>
Approved
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
<td class="px-4 py-3">
<div class="flex items-center space-x-4 text-sm">
<button
class="flex items-center justify-between px-2 py-2 text-sm font-medium leading-5 text-purple-600 rounded-lg dark:text-gray-400 focus:outline-none focus:shadow-outline-gray"
aria-label="Edit"
>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z"
/>
</svg>
</button>
<button
class="flex items-center justify-between px-2 py-2 text-sm font-medium leading-5 text-purple-600 rounded-lg dark:text-gray-400 focus:outline-none focus:shadow-outline-gray"
aria-label="Delete"
>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
clip-rule="evenodd"
/>
</svg>
</button>
</div>
</td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&facepad=3&fit=facearea&s=707b9c33066bf8808c934c8ab394dff6"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Jolina Angelie</p>
<p class="text-xs text-gray-600 dark:text-gray-400">Unemployed</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 369.95 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-orange-700 bg-orange-100 rounded-full dark:text-white dark:bg-orange-600"
>
Pending
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
<td class="px-4 py-3">
<div class="flex items-center space-x-4 text-sm">
<button
class="flex items-center justify-between px-2 py-2 text-sm font-medium leading-5 text-purple-600 rounded-lg dark:text-gray-400 focus:outline-none focus:shadow-outline-gray"
aria-label="Edit"
>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z"
/>
</svg>
</button>
<button
class="flex items-center justify-between px-2 py-2 text-sm font-medium leading-5 text-purple-600 rounded-lg dark:text-gray-400 focus:outline-none focus:shadow-outline-gray"
aria-label="Delete"
>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
clip-rule="evenodd"
/>
</svg>
</button>
</div>
</td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/photo-1551069613-1904dbdcda11?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE3Nzg0fQ"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Sarah Curry</p>
<p class="text-xs text-gray-600 dark:text-gray-400">Designer</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 86.00 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-red-700 bg-red-100 rounded-full dark:text-red-100 dark:bg-red-700"
>
Denied
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
<td class="px-4 py-3">
<div class="flex items-center space-x-4 text-sm">
<button
class="flex items-center justify-between px-2 py-2 text-sm font-medium leading-5 text-purple-600 rounded-lg dark:text-gray-400 focus:outline-none focus:shadow-outline-gray"
aria-label="Edit"
>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z"
/>
</svg>
</button>
<button
class="flex items-center justify-between px-2 py-2 text-sm font-medium leading-5 text-purple-600 rounded-lg dark:text-gray-400 focus:outline-none focus:shadow-outline-gray"
aria-label="Delete"
>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
clip-rule="evenodd"
/>
</svg>
</button>
</div>
</td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/photo-1551006917-3b4c078c47c9?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE3Nzg0fQ"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Rulia Joberts</p>
<p class="text-xs text-gray-600 dark:text-gray-400">Actress</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 1276.45 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-green-700 bg-green-100 rounded-full dark:bg-green-700 dark:text-green-100"
>
Approved
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
<td class="px-4 py-3">
<div class="flex items-center space-x-4 text-sm">
<button
class="flex items-center justify-between px-2 py-2 text-sm font-medium leading-5 text-purple-600 rounded-lg dark:text-gray-400 focus:outline-none focus:shadow-outline-gray"
aria-label="Edit"
>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z"
/>
</svg>
</button>
<button
class="flex items-center justify-between px-2 py-2 text-sm font-medium leading-5 text-purple-600 rounded-lg dark:text-gray-400 focus:outline-none focus:shadow-outline-gray"
aria-label="Delete"
>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
clip-rule="evenodd"
/>
</svg>
</button>
</div>
</td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/photo-1546456073-6712f79251bb?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE3Nzg0fQ"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Wenzel Dashington</p>
<p class="text-xs text-gray-600 dark:text-gray-400">Actor</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 863.45 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-gray-700 bg-gray-100 rounded-full dark:text-gray-100 dark:bg-gray-700"
>
Expired
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
<td class="px-4 py-3">
<div class="flex items-center space-x-4 text-sm">
<button
class="flex items-center justify-between px-2 py-2 text-sm font-medium leading-5 text-purple-600 rounded-lg dark:text-gray-400 focus:outline-none focus:shadow-outline-gray"
aria-label="Edit"
>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z"
/>
</svg>
</button>
<button
class="flex items-center justify-between px-2 py-2 text-sm font-medium leading-5 text-purple-600 rounded-lg dark:text-gray-400 focus:outline-none focus:shadow-outline-gray"
aria-label="Delete"
>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
clip-rule="evenodd"
/>
</svg>
</button>
</div>
</td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/photo-1502720705749-871143f0e671?ixlib=rb-0.3.5&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&s=b8377ca9f985d80264279f277f3a67f5"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Dave Li</p>
<p class="text-xs text-gray-600 dark:text-gray-400">Influencer</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 863.45 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-green-700 bg-green-100 rounded-full dark:bg-green-700 dark:text-green-100"
>
Approved
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
<td class="px-4 py-3">
<div class="flex items-center space-x-4 text-sm">
<button
class="flex items-center justify-between px-2 py-2 text-sm font-medium leading-5 text-purple-600 rounded-lg dark:text-gray-400 focus:outline-none focus:shadow-outline-gray"
aria-label="Edit"
>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z"
/>
</svg>
</button>
<button
class="flex items-center justify-between px-2 py-2 text-sm font-medium leading-5 text-purple-600 rounded-lg dark:text-gray-400 focus:outline-none focus:shadow-outline-gray"
aria-label="Delete"
>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
clip-rule="evenodd"
/>
</svg>
</button>
</div>
</td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/photo-1531746020798-e6953c6e8e04?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE3Nzg0fQ"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Maria Ramovic</p>
<p class="text-xs text-gray-600 dark:text-gray-400">Runner</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 863.45 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-green-700 bg-green-100 rounded-full dark:bg-green-700 dark:text-green-100"
>
Approved
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
<td class="px-4 py-3">
<div class="flex items-center space-x-4 text-sm">
<button
class="flex items-center justify-between px-2 py-2 text-sm font-medium leading-5 text-purple-600 rounded-lg dark:text-gray-400 focus:outline-none focus:shadow-outline-gray"
aria-label="Edit"
>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z"
/>
</svg>
</button>
<button
class="flex items-center justify-between px-2 py-2 text-sm font-medium leading-5 text-purple-600 rounded-lg dark:text-gray-400 focus:outline-none focus:shadow-outline-gray"
aria-label="Delete"
>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
clip-rule="evenodd"
/>
</svg>
</button>
</div>
</td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/photo-1566411520896-01e7ca4726af?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE3Nzg0fQ"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Hitney Wouston</p>
<p class="text-xs text-gray-600 dark:text-gray-400">Singer</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 863.45 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-green-700 bg-green-100 rounded-full dark:bg-green-700 dark:text-green-100"
>
Approved
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
<td class="px-4 py-3">
<div class="flex items-center space-x-4 text-sm">
<button
class="flex items-center justify-between px-2 py-2 text-sm font-medium leading-5 text-purple-600 rounded-lg dark:text-gray-400 focus:outline-none focus:shadow-outline-gray"
aria-label="Edit"
>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z"
/>
</svg>
</button>
<button
class="flex items-center justify-between px-2 py-2 text-sm font-medium leading-5 text-purple-600 rounded-lg dark:text-gray-400 focus:outline-none focus:shadow-outline-gray"
aria-label="Delete"
>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
clip-rule="evenodd"
/>
</svg>
</button>
</div>
</td>
</tr>
<tr class="text-gray-700 dark:text-gray-400">
<td class="px-4 py-3">
<div class="flex items-center text-sm">
<!-- Avatar with inset shadow -->
<div class="relative hidden w-8 h-8 mr-3 rounded-full md:block">
<img
class="object-cover w-full h-full rounded-full"
src="https://images.unsplash.com/flagged/photo-1570612861542-284f4c12e75f?ixlib=rb-1.2.1&q=80&fm=jpg&crop=entropy&cs=tinysrgb&w=200&fit=max&ixid=eyJhcHBfaWQiOjE3Nzg0fQ"
alt=""
loading="lazy"
/>
<div class="absolute inset-0 rounded-full shadow-inner" aria-hidden="true" />
</div>
<div>
<p class="font-semibold">Hans Burger</p>
<p class="text-xs text-gray-600 dark:text-gray-400">10x Developer</p>
</div>
</div>
</td>
<td class="px-4 py-3 text-sm"> $ 863.45 </td>
<td class="px-4 py-3 text-xs">
<span
class="px-2 py-1 font-semibold leading-tight text-green-700 bg-green-100 rounded-full dark:bg-green-700 dark:text-green-100"
>
Approved
</span>
</td>
<td class="px-4 py-3 text-sm"> 6/10/2020 </td>
<td class="px-4 py-3">
<div class="flex items-center space-x-4 text-sm">
<button
class="flex items-center justify-between px-2 py-2 text-sm font-medium leading-5 text-purple-600 rounded-lg dark:text-gray-400 focus:outline-none focus:shadow-outline-gray"
aria-label="Edit"
>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
d="M13.586 3.586a2 2 0 112.828 2.828l-.793.793-2.828-2.828.793-.793zM11.379 5.793L3 14.172V17h2.828l8.38-8.379-2.83-2.828z"
/>
</svg>
</button>
<button
class="flex items-center justify-between px-2 py-2 text-sm font-medium leading-5 text-purple-600 rounded-lg dark:text-gray-400 focus:outline-none focus:shadow-outline-gray"
aria-label="Delete"
>
<svg class="w-5 h-5" aria-hidden="true" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
d="M9 2a1 1 0 00-.894.553L7.382 4H4a1 1 0 000 2v10a2 2 0 002 2h8a2 2 0 002-2V6a1 1 0 100-2h-3.382l-.724-1.447A1 1 0 0011 2H9zM7 8a1 1 0 012 0v6a1 1 0 11-2 0V8zm5-1a1 1 0 00-1 1v6a1 1 0 102 0V8a1 1 0 00-1-1z"
clip-rule="evenodd"
/>
</svg>
</button>
</div>
</td>
</tr>
</tbody>
</table>
</div>
<div
class="grid px-4 py-3 text-xs font-semibold tracking-wide text-gray-500 uppercase border-t dark:border-gray-700 bg-gray-50 sm:grid-cols-9 dark:text-gray-400 dark:bg-gray-800"
>
<span class="flex items-center col-span-3"> Showing 21-30 of 100 </span>
<span class="col-span-2" />
<!-- Pagination -->
<span class="flex col-span-4 mt-2 sm:mt-auto sm:justify-end">
<nav aria-label="Table navigation">
<ul class="inline-flex items-center">
<li>
<button
class="px-3 py-1 rounded-md rounded-l-lg focus:outline-none focus:shadow-outline-purple"
aria-label="Previous"
>
<svg class="w-4 h-4 fill-current" aria-hidden="true" viewBox="0 0 20 20">
<path
d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
clip-rule="evenodd"
fill-rule="evenodd"
/>
</svg>
</button>
</li>
<li>
<button class="px-3 py-1 rounded-md focus:outline-none focus:shadow-outline-purple">
1
</button>
</li>
<li>
<button class="px-3 py-1 rounded-md focus:outline-none focus:shadow-outline-purple">
2
</button>
</li>
<li>
<button
class="px-3 py-1 text-white transition-colors duration-150 bg-purple-600 border border-r-0 border-purple-600 rounded-md focus:outline-none focus:shadow-outline-purple"
>
3
</button>
</li>
<li>
<button class="px-3 py-1 rounded-md focus:outline-none focus:shadow-outline-purple">
4
</button>
</li>
<li>
<span class="px-3 py-1">...</span>
</li>
<li>
<button class="px-3 py-1 rounded-md focus:outline-none focus:shadow-outline-purple">
8
</button>
</li>
<li>
<button class="px-3 py-1 rounded-md focus:outline-none focus:shadow-outline-purple">
9
</button>
</li>
<li>
<button
class="px-3 py-1 rounded-md rounded-r-lg focus:outline-none focus:shadow-outline-purple"
aria-label="Next"
>
<svg class="w-4 h-4 fill-current" aria-hidden="true" viewBox="0 0 20 20">
<path
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
clip-rule="evenodd"
fill-rule="evenodd"
/>
</svg>
</button>
</li>
</ul>
</nav>
</span>
</div>
</div>
</div>
</main>
================================================
FILE: src/routes/admin/(guest)/+layout.svelte
================================================
<script lang="ts">
import '$lib/tailwind.css'
import { isDark } from '$stores/menus'
import { browser } from '$app/environment'
import HtmlHead from '../html_head.svelte'
if (browser && localStorage.theme === 'dark') {
isDark.update((v) => true)
} else {
isDark.update((v) => false)
}
</script>
<HtmlHead {isDark} />
<slot />
================================================
FILE: src/routes/admin/(guest)/auth/login/+page.server.ts
================================================
import { api } from '$src/routes/api';
import { redirect, type RequestEvent } from '@sveltejs/kit';
import type { Actions } from './$types';
export const actions: Actions = {
login: async (event: RequestEvent) => {
const form = await event.request.formData();
const response = await api({
method: 'post',
resource: 'login',
data: {
'email': form.has('email') ? form.get('email') : undefined,
'password': form.has('password') ? form.get('password') : undefined,
},
event,
});
if (response.status === 404) {
return {
body: []
};
}
if (response.status >= 200 && response.status <= 299) {
throw redirect(302, '/')
}
return {
status: response.status
};
},
}
================================================
FILE: src/routes/admin/(guest)/auth/login/+page.svelte
================================================
<script lang="ts">
import loginOffice from '$lib/templates/Admin/Images/login-office.jpeg'
import loginOfficeDark from '$lib/templates/Admin/Images/login-office-dark.jpeg'
import ToggleTheme from '$src/lib/templates/Admin/ToggleTheme.svelte'
</script>
<section id="body">
<div class="flex items-center min-h-screen p-6 bg-gray-50 dark:bg-gray-900">
<div class="flex-1 mx-auto">
<div class="flex justify-center mb-5">
<ToggleTheme />
</div>
<div
class="flex-1 h-full max-w-4xl mx-auto overflow-hidden bg-white rounded-lg shadow-xl dark:bg-gray-800"
>
<div class="flex flex-col overflow-y-auto md:flex-row">
<div class="h-32 md:h-auto md:w-1/2">
<img
aria-hidden="true"
class="object-cover w-full h-full dark:hidden"
src={loginOffice}
alt="Office"
/>
<img
aria-hidden="true"
class="hidden object-cover w-full h-full dark:block"
src={loginOfficeDark}
alt="Office"
/>
</div>
<div class="flex items-center justify-center p-6 sm:p-12 md:w-1/2">
<div class="w-full">
<h1 class="mb-4 text-xl font-semibold text-gray-700 dark:text-gray-200">Login</h1>
<form method="post" action="?/login">
<label class="block text-sm">
<span class="text-gray-700 dark:text-gray-400">Email</span>
<input
name="email"
type="email"
class="block w-full mt-1 text-sm dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray form-input"
placeholder="Jane Doe"
/>
</label>
<label class="block mt-4 text-sm">
<span class="text-gray-700 dark:text-gray-400">Password</span>
<input
name="password"
class="block w-full mt-1 text-sm dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray form-input"
placeholder="***************"
type="password"
/>
</label>
<!-- You should use a button here, as the anchor is only used for the example -->
<button
type="submit"
class="block w-full px-4 py-2 mt-4 text-sm font-medium leading-5 text-center text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-lg active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"
>
Log in
</button>
</form>
<hr class="my-8" />
<button
class="flex items-center justify-center w-full px-4 py-2 text-sm font-medium leading-5 transition-colors duration-150 border border-gray-300 rounded-lg dark:text-gray-400 active:bg-transparent hover:border-gray-500 focus:border-gray-500 active:text-gray-500 focus:outline-none focus:shadow-outline-gray"
>
<svg
class="w-4 h-4 mr-2"
aria-hidden="true"
viewBox="0 0 24 24"
fill="currentColor"
>
<path
d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"
/>
</svg>
Github
</button>
<button
class="flex items-center justify-center w-full px-4 py-2 mt-4 text-sm font-medium leading-5 transition-colors duration-150 border border-gray-300 rounded-lg dark:text-gray-400 active:bg-transparent hover:border-gray-500 focus:border-gray-500 active:text-gray-500 focus:outline-none focus:shadow-outline-gray"
>
<svg
class="w-4 h-4 mr-2"
aria-hidden="true"
viewBox="0 0 24 24"
fill="currentColor"
>
<path
d="M23.954 4.569c-.885.389-1.83.654-2.825.775 1.014-.611 1.794-1.574 2.163-2.723-.951.555-2.005.959-3.127 1.184-.896-.959-2.173-1.559-3.591-1.559-2.717 0-4.92 2.203-4.92 4.917 0 .39.045.765.127 1.124C7.691 8.094 4.066 6.13 1.64 3.161c-.427.722-.666 1.561-.666 2.475 0 1.71.87 3.213 2.188 4.096-.807-.026-1.566-.248-2.228-.616v.061c0 2.385 1.693 4.374 3.946 4.827-.413.111-.849.171-1.296.171-.314 0-.615-.03-.916-.086.631 1.953 2.445 3.377 4.604 3.417-1.68 1.319-3.809 2.105-6.102 2.105-.39 0-.779-.023-1.17-.067 2.189 1.394 4.768 2.209 7.557 2.209 9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63.961-.689 1.8-1.56 2.46-2.548l-.047-.02z"
/>
</svg>
Twitter
</button>
<p class="mt-4">
<a
class="text-sm font-medium text-purple-600 dark:text-purple-400 hover:underline"
href="./forgot-password.html"
>
Forgot your password?
</a>
</p>
<p class="mt-1">
<a
class="text-sm font-medium text-purple-600 dark:text-purple-400 hover:underline"
href="./create-account.html"
>
Create account
</a>
</p>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
================================================
FILE: src/routes/admin/(guest)/auth/logout/+page.server.ts
================================================
import { api } from '$src/routes/api';
import { redirect, type RequestEvent } from '@sveltejs/kit';
import type { Actions } from '@sveltejs/kit';
import cookie from 'cookie'
export const actions: Actions = {
logout: async (event: RequestEvent) => {
const response = await api({
method: 'get',
resource: 'logout',
data: null,
event,
});
if (response.status === 404) {
return {
body: []
};
}
if (response.status >= 200 && response.status <= 299) {
event.cookies.delete(import.meta.env.VITE_SESSION_NAME)
throw redirect(302, import.meta.env.VITE_LOGIN_PATH)
// return {
// status: 302,
// headers: {
// location: import.meta.env.VITE_LOGIN_PATH,
// 'set-cookie': cookie.serialize(import.meta.env.VITE_SESSION_NAME, '', {
// path: "/",
// maxAge: -1,
// }),
// },
// };
}
return {
status: response.status,
};
},
}
================================================
FILE: src/routes/admin/(guest)/forgot-password/+page.svelte
================================================
<script lang="ts">
import forgotPasswordOffice from '$lib/templates/Admin/Images/forgot-password-office.jpeg'
import forgotPasswordOfficeDark from '$lib/templates/Admin/Images/forgot-password-office-dark.jpeg'
</script>
<section id="body">
<div class="flex items-center min-h-screen p-6 bg-gray-50 dark:bg-gray-900">
<div
class="flex-1 h-full max-w-4xl mx-auto overflow-hidden bg-white rounded-lg shadow-xl dark:bg-gray-800"
>
<div class="flex flex-col overflow-y-auto md:flex-row">
<div class="h-32 md:h-auto md:w-1/2">
<img
aria-hidden="true"
class="object-cover w-full h-full dark:hidden"
src={forgotPasswordOffice}
alt="Office"
/>
<img
aria-hidden="true"
class="hidden object-cover w-full h-full dark:block"
src={forgotPasswordOfficeDark}
alt="Office"
/>
</div>
<div class="flex items-center justify-center p-6 sm:p-12 md:w-1/2">
<div class="w-full">
<h1 class="mb-4 text-xl font-semibold text-gray-700 dark:text-gray-200">
Forgot password
</h1>
<label class="block text-sm">
<span class="text-gray-700 dark:text-gray-400">Email</span>
<input
class="block w-full mt-1 text-sm dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray form-input"
placeholder="Jane Doe"
/>
</label>
<!-- You should use a button here, as the anchor is only used for the example -->
<a
class="block w-full px-4 py-2 mt-4 text-sm font-medium leading-5 text-center text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-lg active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"
href="./login.html"
>
Recover password
</a>
</div>
</div>
</div>
</div>
</div>
</section>
================================================
FILE: src/routes/admin/(guest)/register/+page.svelte
================================================
<script lang="ts">
import createAccountOffice from '$lib/templates/Admin/Images/create-account-office.jpeg'
import createAccountOfficeDark from '$lib/templates/Admin/Images/create-account-office-dark.jpeg'
</script>
<section id="body">
<div class="flex items-center min-h-screen p-6 bg-gray-50 dark:bg-gray-900">
<div
class="flex-1 h-full max-w-4xl mx-auto overflow-hidden bg-white rounded-lg shadow-xl dark:bg-gray-800"
>
<div class="flex flex-col overflow-y-auto md:flex-row">
<div class="h-32 md:h-auto md:w-1/2">
<img
aria-hidden="true"
class="object-cover w-full h-full dark:hidden"
src={createAccountOffice}
alt="Office"
/>
<img
aria-hidden="true"
class="hidden object-cover w-full h-full dark:block"
src={createAccountOfficeDark}
alt="Office"
/>
</div>
<div class="flex items-center justify-center p-6 sm:p-12 md:w-1/2">
<div class="w-full">
<h1 class="mb-4 text-xl font-semibold text-gray-700 dark:text-gray-200">
Create account
</h1>
<label class="block text-sm">
<span class="text-gray-700 dark:text-gray-400">Email</span>
<input
class="block w-full mt-1 text-sm dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray form-input"
placeholder="Jane Doe"
/>
</label>
<label class="block mt-4 text-sm">
<span class="text-gray-700 dark:text-gray-400">Password</span>
<input
class="block w-full mt-1 text-sm dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray form-input"
placeholder="***************"
type="password"
/>
</label>
<label class="block mt-4 text-sm">
<span class="text-gray-700 dark:text-gray-400"> Confirm password </span>
<input
class="block w-full mt-1 text-sm dark:border-gray-600 dark:bg-gray-700 focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:text-gray-300 dark:focus:shadow-outline-gray form-input"
placeholder="***************"
type="password"
/>
</label>
<div class="flex mt-6 text-sm">
<label class="flex items-center dark:text-gray-400">
<input
type="checkbox"
class="text-purple-600 form-checkbox focus:border-purple-400 focus:outline-none focus:shadow-outline-purple dark:focus:shadow-outline-gray"
/>
<span class="ml-2">
I agree to the
<span class="underline">privacy policy</span>
</span>
</label>
</div>
<!-- You should use a button here, as the anchor is only used for the example -->
<a
class="block w-full px-4 py-2 mt-4 text-sm font-medium leading-5 text-center text-white transition-colors duration-150 bg-purple-600 border border-transparent rounded-lg active:bg-purple-600 hover:bg-purple-700 focus:outline-none focus:shadow-outline-purple"
href="./login.html"
>
Create account
</a>
<hr class="my-8" />
<button
class="flex items-center justify-center w-full px-4 py-2 text-sm font-medium leading-5 text-white text-gray-700 transition-colors duration-150 border border-gray-300 rounded-lg dark:text-gray-400 active:bg-transparent hover:border-gray-500 focus:border-gray-500 active:text-gray-500 focus:outline-none focus:shadow-outline-gray"
>
<svg class="w-4 h-4 mr-2" aria-hidden="true" viewBox="0 0 24 24" fill="currentColor">
<path
d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"
/>
</svg>
Github
</button>
<button
class="flex items-center justify-center w-full px-4 py-2 mt-4 text-sm font-medium leading-5 text-white text-gray-700 transition-colors duration-150 border border-gray-300 rounded-lg dark:text-gray-400 active:bg-transparent hover:border-gray-500 focus:border-gray-500 active:text-gray-500 focus:outline-none focus:shadow-outline-gray"
>
<svg class="w-4 h-4 mr-2" aria-hidden="true" viewBox="0 0 24 24" fill="currentColor">
<path
d="M23.954 4.569c-.885.389-1.83.654-2.825.775 1.014-.611 1.794-1.574 2.163-2.723-.951.555-2.005.959-3.127 1.184-.896-.959-2.173-1.559-3.591-1.559-2.717 0-4.92 2.203-4.92 4.917 0 .39.045.765.127 1.124C7.691 8.094 4.066 6.13 1.64 3.161c-.427.722-.666 1.561-.666 2.475 0 1.71.87 3.213 2.188 4.096-.807-.026-1.566-.248-2.228-.616v.061c0 2.385 1.693 4.374 3.946 4.827-.413.111-.849.171-1.296.171-.314 0-.615-.03-.916-.086.631 1.953 2.445 3.377 4.604 3.417-1.68 1.319-3.809 2.105-6.102 2.105-.39 0-.779-.023-1.17-.067 2.189 1.394 4.768 2.209 7.557 2.209 9.054 0 13.999-7.496 13.999-13.986 0-.209 0-.42-.015-.63.961-.689 1.8-1.56 2.46-2.548l-.047-.02z"
/>
</svg>
Twitter
</button>
<p class="mt-4">
<a
class="text-sm font-medium text-purple-600 dark:text-purple-400 hover:underline"
href="./login.html"
>
Already have an account? Login
</a>
</p>
</div>
</div>
</div>
</div>
</div>
</section>
================================================
FILE: src/routes/admin/+error.svelte
================================================
<script lang="ts">
import '$lib/tailwind.css'
import { isDark } from '$stores/menus'
import { browser } from '$app/environment'
import HtmlHead from './html_head.svelte'
if (browser && localStorage.theme === 'dark') {
isDark.update((v) => true)
} else {
isDark.update((v) => false)
}
</script>
<HtmlHead {isDark} />
<main class="h-full pb-16 overflow-y-auto">
<div class="container flex flex-col items-center px-6 mx-auto">
<svg class="w-12 h-12 mt-8 text-purple-200" fill="currentColor" viewBox="0 0 20 20">
<path
fill-rule="evenodd"
d="M13.477 14.89A6 6 0 015.11 6.524l8.367 8.368zm1.414-1.414L6.524 5.11a6 6 0 018.367 8.367zM18 10a8 8 0 11-16 0 8 8 0 0116 0z"
clip-rule="evenodd"
/>
</svg>
<h1 class="text-6xl font-semibold text-gray-700 dark:text-gray-200">404</h1>
<p class="text-gray-700 dark:text-gray-300">
Page not found. Check the address or
<a class="text-purple-600 hover:underline dark:text-purple-300" href="/"> go back </a>
.
</p>
</div>
</main>
================================================
FILE: src/routes/admin/+layout.server.ts
================================================
import { redirect } from '@sveltejs/kit';
import type { PageServerLoad } from './$types';
export const load: PageServerLoad = async ({ locals, url }) => {
const user = locals?.user
const isGuestPage = url.pathname.indexOf(import.meta.env.VITE_LOGIN_PATH) >= 0
|| url.pathname.indexOf("/register") >= 0
|| url.pathname.indexOf("/forgot-password") >= 0
if (user && isGuestPage) {
throw redirect(302, '/')
}
if (!user && !isGuestPage) {
throw redirect(302, import.meta.env.VITE_LOGIN_PATH)
}
return { user }
}
================================================
FILE: src/routes/admin/html_head.svelte
================================================
<script lang="ts">
export let isDark
</script>
<svelte:head>
<meta name="theme-color" content={$isDark ? '#1a1c23' : '#FFF'} />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700;800&display=swap"
rel="stylesheet"
/>
<script>
if (
localStorage.theme === 'dark' ||
(!('theme' in localStorage) && window.matchMedia('(prefers-color-scheme: dark)').matches)
) {
document.documentElement.classList.add('dark')
localStorage.theme = 'dark'
} else {
document.documentElement.classList.remove('dark')
}
</script>
</svelte:head>
================================================
FILE: src/routes/api.ts
================================================
import type { RequestEvent } from "@sveltejs/kit";
interface ApiParams {
method: string;
event?: RequestEvent;
resource?: string;
data?: Record<string, unknown> | null;
}
export async function api(params: ApiParams) {
const base = import.meta.env.VITE_BASE_API
let fullurl = base
if (params.resource) {
fullurl = `${base}/${params.resource}`
}
const response = await fetch(fullurl, {
method: params.method,
headers: {
'content-type': 'application/json',
'accept': 'application/json',
'cookie': params?.event?.request?.headers?.get('cookie') as string,
},
body: params.data && JSON.stringify(params.data),
})
return response;
}
================================================
FILE: src/routes/blog/+layout.svelte
================================================
<script lang="ts">
import '$lib/tailwind.css'
import { fly } from 'svelte/transition'
import { isSideMenuOpen, closeSideMenu } from '$stores/menus'
import { clickOutside } from '$lib/ioevents/click'
import { keydownEscape } from '$lib/ioevents/keydown'
import SideBar from '$lib/templates/Blog/SideBar.svelte'
import Header from '$src/lib/templates/Blog/Header.svelte'
import { onMount } from 'svelte'
import { loadFull } from 'tsparticles'
import particlesConfig from '$lib/templates/Blog/Config/particle.json'
let ParticlesComponent: any
onMount(async () => {
const module = await import('$lib/templates/Blog/Particles')
ParticlesComponent = module.default
})
let onParticlesLoaded = (event: any) => {
const particlesContainer = event.detail.particles
}
let particlesInit = async (main: any) => {
await loadFull(main)
}
</script>
<svelte:head>
<link rel="preconnect" href="https://fonts.gstatic.com" />
<link
href="https://fonts.googleapis.com/css2?family=Montserrat:ital,wght@0,100;0,200;0,300;0,400;0,500;0,600;0,700;0,800;0,900;1,100;1,200;1,300;1,400;1,500;1,600;1,700;1,800;1,900&display=swap"
rel="stylesheet"
/>
</svelte:head>
<div class="w-full fixed bg-blog">
<svelte:component
this={ParticlesComponent}
id="tsparticles"
options={particlesConfig}
class="h-screen"
on:particlesLoaded={onParticlesLoaded}
{particlesInit}
/>
</div>
<div class="z-20 absolute w-full">
<Header />
</div>
<section id="body" class="relative">
<!-- Mobile sidebar -->
<!-- Backdrop -->
{#if $isSideMenuOpen}
<div
transition:fly={{ y: -800, x: -500, duration: 100 }}
class="fixed inset-0 z-10 flex items-end bg-black bg-opacity-50 sm:items-center sm:justify-center"
/>
<aside
class="fixed inset-y-0 z-20 flex-shrink-0 w-full mt-16 overflow-y-auto md:hidden"
use:clickOutside={['nav-mobile-hamburger']}
on:click-outside={closeSideMenu}
use:keydownEscape
on:keydown-escape={closeSideMenu}
>
<SideBar />
</aside>
{/if}
<slot />
</section>
================================================
FILE: src/routes/blog/+page.svelte
================================================
<script lang="ts">
import Github from '$icon/Github/Github.svelte'
import Building from '$icon/Building/Building.svelte'
import CardList from '$icon/CardList/CardList.svelte'
import pilipinasTeleservImg from '$lib/templates/Blog/Images/company1.png'
import vroom3Img from '$lib/templates/Blog/Images/company2.svg'
import plus65Img from '$lib/templates/Blog/Images/company3.png'
import incube8Img from '$lib/templates/Blog/Images/company4.jpeg'
</script>
<div class="container mx-auto">
<div class="flex items-center w-full h-screen">
<div class="text-center 2xl:text-left">
<p class="text-white text-3xl md:text-4xl lg:text-5xl 2xl:text-7xl">
Hey! I'm <span class="font-bold">Daison!</span>
</p>
<p class="opacity-30 text-gray-900 text-4xl md:text-6xl lg:text-8xl 2xl:text-10xl font-bold">
A SOFTWARE ENGINEER
</p>
</div>
</div>
<div class="bg-white rounded-xl mx-3 md:mx-3 my-5 p-5">
<div class="flex flex-col xl:flex-row items-center justify-center">
<div class="xl:px-10">
<img
class="rounded-full w-40 xl:w-auto mx-auto shadow-md 2xl:shadow-2xl border-2 lg:border-5 2xl:border-8 border-gray-100"
src="https://avatars.githubusercontent.com/u/4581415"
alt="my-profile"
/>
</div>
<div class="xl:border-l border-gray-300 border-dashed text-center mt-5 xl:px-10">
<h1 class="text-3xl">About Me</h1>
<div class="xl:text-left">
<p class="pt-5">
<span class="pl-5" />My name is
<a
href="https://www.linkedin.com/in/daison-cari%C3%B1o-56319471"
target="_blank"
gitextract_2mqan8mg/ ├── .env.example ├── .eslintignore ├── .eslintrc.cjs ├── .gitignore ├── .npmrc ├── .nvmrc ├── .prettierignore ├── .prettierrc ├── README.md ├── guides/ │ └── laravel-sanctum.md ├── package.json ├── playwright.config.ts ├── postcss.config.cjs ├── run ├── src/ │ ├── app.css │ ├── app.d.ts │ ├── app.html │ ├── hooks/ │ │ ├── laravel-sanctum-fake-logged-in.ts │ │ ├── laravel-sanctum-fake-logged-out.ts │ │ ├── laravel-sanctum.ts │ │ └── sveltekit-default.ts │ ├── lib/ │ │ ├── Counter.svelte │ │ ├── components/ │ │ │ ├── Accordion.svelte │ │ │ ├── AccordionItem.svelte │ │ │ ├── Alert.svelte │ │ │ ├── Badge.svelte │ │ │ ├── Breadcrumb.svelte │ │ │ ├── ButtonGroup.svelte │ │ │ ├── Buttons.svelte │ │ │ ├── Card.svelte │ │ │ ├── Carousel.svelte │ │ │ ├── CloseButton.svelte │ │ │ ├── Code.svelte │ │ │ ├── Collapse.svelte │ │ │ ├── Docs/ │ │ │ │ ├── DocAccordion.svelte │ │ │ │ ├── DocAlert.svelte │ │ │ │ └── DocBadge.svelte │ │ │ ├── Dropdowns.svelte │ │ │ ├── ListGroup.svelte │ │ │ ├── Modal.svelte │ │ │ ├── NavsAndTabs.svelte │ │ │ ├── Pagination.svelte │ │ │ ├── Popovers.svelte │ │ │ ├── Spinners.svelte │ │ │ ├── Toasts.svelte │ │ │ └── Tooltips.svelte │ │ ├── form.ts │ │ ├── header/ │ │ │ └── Header.svelte │ │ ├── ioevents/ │ │ │ ├── click.ts │ │ │ └── keydown.ts │ │ ├── tailwind.css │ │ ├── templates/ │ │ │ ├── Admin/ │ │ │ │ ├── API/ │ │ │ │ │ └── form.ts │ │ │ │ ├── Config/ │ │ │ │ │ └── charts.ts │ │ │ │ ├── Header.svelte │ │ │ │ ├── SideBar.svelte │ │ │ │ └── ToggleTheme.svelte │ │ │ └── Blog/ │ │ │ ├── Config/ │ │ │ │ ├── links.json │ │ │ │ └── particle.json │ │ │ ├── Header.svelte │ │ │ ├── Particles/ │ │ │ │ ├── Particles.svelte │ │ │ │ ├── global.d.ts │ │ │ │ ├── index.d.ts │ │ │ │ └── index.ts │ │ │ └── SideBar.svelte │ │ └── translator.ts │ ├── routes/ │ │ ├── admin/ │ │ │ ├── (authenticated)/ │ │ │ │ ├── +layout.svelte │ │ │ │ ├── +page.svelte │ │ │ │ ├── buttons/ │ │ │ │ │ └── +page.svelte │ │ │ │ ├── cards/ │ │ │ │ │ └── +page.svelte │ │ │ │ ├── charts/ │ │ │ │ │ └── +page.svelte │ │ │ │ ├── components/ │ │ │ │ │ └── +page.svelte │ │ │ │ ├── forms/ │ │ │ │ │ └── +page.svelte │ │ │ │ ├── modals/ │ │ │ │ │ └── +page.svelte │ │ │ │ └── tables/ │ │ │ │ └── +page.svelte │ │ │ ├── (guest)/ │ │ │ │ ├── +layout.svelte │ │ │ │ ├── auth/ │ │ │ │ │ ├── login/ │ │ │ │ │ │ ├── +page.server.ts │ │ │ │ │ │ └── +page.svelte │ │ │ │ │ └── logout/ │ │ │ │ │ └── +page.server.ts │ │ │ │ ├── forgot-password/ │ │ │ │ │ └── +page.svelte │ │ │ │ └── register/ │ │ │ │ └── +page.svelte │ │ │ ├── +error.svelte │ │ │ ├── +layout.server.ts │ │ │ └── html_head.svelte │ │ ├── api.ts │ │ ├── blog/ │ │ │ ├── +layout.svelte │ │ │ ├── +page.svelte │ │ │ └── resume/ │ │ │ └── +page.svelte │ │ └── demo/ │ │ ├── +layout.svelte │ │ ├── +page.svelte │ │ ├── +page.ts │ │ ├── Counter.svelte │ │ ├── Header.svelte │ │ ├── about/ │ │ │ ├── +page.svelte │ │ │ └── +page.ts │ │ ├── styles.css │ │ └── sverdle/ │ │ ├── +page.server.ts │ │ ├── +page.svelte │ │ ├── game.test.ts │ │ ├── game.ts │ │ ├── how-to-play/ │ │ │ ├── +page.svelte │ │ │ └── +page.ts │ │ ├── reduced-motion.ts │ │ └── words.server.ts │ ├── service-worker.ts │ └── stores/ │ └── menus.ts ├── start/ │ ├── route.js │ ├── tailwind/ │ │ ├── admin.cjs │ │ ├── daisy-ui.cjs │ │ └── index.cjs │ └── vite/ │ ├── default.vite.config.js │ └── index.js ├── static/ │ ├── manifest.json │ └── robots.txt ├── svelte.config.js ├── tailwind.config.cjs ├── tests/ │ └── demo.ts ├── tsconfig.json └── vite.config.js
SYMBOL INDEX (18 symbols across 9 files)
FILE: src/app.d.ts
type Locals (line 7) | interface Locals {
type Session (line 16) | interface Session {
FILE: src/lib/form.ts
function enhance (line 5) | function enhance(
FILE: src/lib/ioevents/click.ts
function clickOutside (line 2) | function clickOutside(node: any, except: any[] = []) {
FILE: src/lib/ioevents/keydown.ts
function keydownEscape (line 2) | function keydownEscape(node: any) {
FILE: src/lib/templates/Admin/API/form.ts
function enhance (line 1) | function enhance(
FILE: src/lib/templates/Blog/Particles/index.d.ts
type CustomEventWrapper (line 5) | type CustomEventWrapper<T> = {
type ParticlesProps (line 8) | type ParticlesProps = {
type ParticlesEvents (line 14) | type ParticlesEvents = CustomEventWrapper<{
FILE: src/routes/api.ts
type ApiParams (line 3) | interface ApiParams {
function api (line 10) | async function api(params: ApiParams) {
FILE: src/routes/demo/sverdle/game.ts
class Game (line 3) | class Game {
method constructor (line 12) | constructor(serialized: string | undefined = undefined) {
method enter (line 32) | enter(letters: string[]) {
method toString (line 72) | toString() {
FILE: src/service-worker.ts
constant STATIC_CACHE_NAME (line 6) | const STATIC_CACHE_NAME = `cache${version}`;
constant APP_CACHE_NAME (line 7) | const APP_CACHE_NAME = `offline${version}`;
function fetchAndCache (line 73) | async function fetchAndCache(request: Request) {
Condensed preview — 118 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (419K chars).
[
{
"path": ".env.example",
"chars": 172,
"preview": "VITE_APP_NAME=\"Project Name\"\nVITE_BASE_API=\"http://api.local\"\nVITE_SESSION_NAME=\"laravel_session\"\n\n# url path\nVITE_LOGIN"
},
{
"path": ".eslintignore",
"chars": 160,
"preview": ".DS_Store\nnode_modules\n/build\n/.svelte-kit\n/package\n.env\n.env.*\n!.env.example\n\n# Ignore files for PNPM, NPM and YARN\npnp"
},
{
"path": ".eslintrc.cjs",
"chars": 521,
"preview": "module.exports = {\n root: true,\n parser: '@typescript-eslint/parser',\n extends: ['eslint:recommended', 'plugin:@types"
},
{
"path": ".gitignore",
"chars": 169,
"preview": ".vscode\n.DS_Store\nnode_modules\n/build\n/.svelte-kit\n/package\n.env\n.env.*\n!.env.example\n.vercel\n.output\n/functions\n/.verce"
},
{
"path": ".npmrc",
"chars": 19,
"preview": "engine-strict=true\n"
},
{
"path": ".nvmrc",
"chars": 9,
"preview": "v16.14.2\n"
},
{
"path": ".prettierignore",
"chars": 160,
"preview": ".DS_Store\nnode_modules\n/build\n/.svelte-kit\n/package\n.env\n.env.*\n!.env.example\n\n# Ignore files for PNPM, NPM and YARN\npnp"
},
{
"path": ".prettierrc",
"chars": 209,
"preview": "{\n\t\"useTabs\": true,\n\t\"singleQuote\": true,\n\t\"trailingComma\": \"none\",\n\t\"printWidth\": 100,\n\t\"pluginSearchDirs\": [\".\"],\n\t\"ov"
},
{
"path": "README.md",
"chars": 1971,
"preview": "# SvelteKit Projects\n\n- [./run and src/route.js](#run-and-srcroutejs)\n- [Playwright Test Cases](#playwright-test-cases)\n"
},
{
"path": "guides/laravel-sanctum.md",
"chars": 1916,
"preview": "# SvelteKit + Laravel Sanctum Setup\n\nInstall sanctum under your laravel\n\n```bash\nlaravel/ :~$ composer require laravel/s"
},
{
"path": "package.json",
"chars": 1795,
"preview": "{\n\t\"name\": \"sveltekit-starter\",\n\t\"version\": \"0.0.1\",\n\t\"scripts\": {\n\t\t\"dev\": \"vite dev\",\n\t\t\"build\": \"vite build\",\n\t\t\"prev"
},
{
"path": "playwright.config.ts",
"chars": 266,
"preview": "import type { PlaywrightTestConfig } from '@playwright/test';\n\nconst config: PlaywrightTestConfig = {\n\twebServer: {\n\t\tco"
},
{
"path": "postcss.config.cjs",
"chars": 82,
"preview": "module.exports = {\n plugins: [require('tailwindcss'), require('autoprefixer')]\n}\n"
},
{
"path": "run",
"chars": 336,
"preview": "#!/bin/bash\n# How to?\n# ./run {route-folder} {packages.scripts}\n#\n# As an example below:\n# ./run demo dev\n# ./r"
},
{
"path": "src/app.css",
"chars": 1823,
"preview": "@import '@fontsource/fira-mono';\n\n:root {\n font-family: Arial, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, O"
},
{
"path": "src/app.d.ts",
"chars": 408,
"preview": "// See https://kit.svelte.dev/docs#typescript\n// for information about these interfaces\ndeclare global {\n\tnamespace App "
},
{
"path": "src/app.html",
"chars": 363,
"preview": "<!DOCTYPE html>\n<html lang=\"en\">\n\t<head>\n\t\t<meta charset=\"utf-8\" />\n\t\t<link rel=\"icon\" href=\"%sveltekit.assets%/favicon."
},
{
"path": "src/hooks/laravel-sanctum-fake-logged-in.ts",
"chars": 1039,
"preview": "import cookie, { parse } from 'cookie';\nimport type { Handle } from '@sveltejs/kit';\n\n// inside laravel-sanctum.ts\n// ->"
},
{
"path": "src/hooks/laravel-sanctum-fake-logged-out.ts",
"chars": 253,
"preview": "import type { Handle } from '@sveltejs/kit';\n\n// since we want to simulate a FAKE log out\n// inside this hooks, we will "
},
{
"path": "src/hooks/laravel-sanctum.ts",
"chars": 888,
"preview": "import { api } from '$src/routes/api';\nimport cookie, { parse } from 'cookie';\nimport type { Handle } from '@sveltejs/ki"
},
{
"path": "src/hooks/sveltekit-default.ts",
"chars": 637,
"preview": "import type { Handle } from '@sveltejs/kit';\nimport * as cookie from 'cookie';\n\nexport const handle: Handle = async ({ e"
},
{
"path": "src/lib/Counter.svelte",
"chars": 2037,
"preview": "<script lang=\"ts\">\n\timport { spring } from 'svelte/motion'\n\n\tlet count = 0\n\n\tconst displayed_count = spring()\n\t$: displa"
},
{
"path": "src/lib/components/Accordion.svelte",
"chars": 98,
"preview": "<div class=\"border border-b-0 border-gray-500 dark:border-gray-600 rounded-md\">\n <slot />\n</div>\n"
},
{
"path": "src/lib/components/AccordionItem.svelte",
"chars": 901,
"preview": "<script lang=\"ts\">\n import { fly } from 'svelte/transition'\n import ChevronUp from '$icon/ChevronUp/ChevronUp.svelte'\n"
},
{
"path": "src/lib/components/Alert.svelte",
"chars": 983,
"preview": "<script lang=\"ts\">\n export let type = 'primary'\n export let body = null\n\n let color = ''\n\n // reactive\n\n $: switch "
},
{
"path": "src/lib/components/Badge.svelte",
"chars": 277,
"preview": "<script lang=\"ts\">\n\texport let type = 'primary'\n\texport let body: string | null = null\n\texport let roundedSize = 'sm'\n\n\t"
},
{
"path": "src/lib/components/Breadcrumb.svelte",
"chars": 0,
"preview": ""
},
{
"path": "src/lib/components/ButtonGroup.svelte",
"chars": 0,
"preview": ""
},
{
"path": "src/lib/components/Buttons.svelte",
"chars": 0,
"preview": ""
},
{
"path": "src/lib/components/Card.svelte",
"chars": 0,
"preview": ""
},
{
"path": "src/lib/components/Carousel.svelte",
"chars": 0,
"preview": ""
},
{
"path": "src/lib/components/CloseButton.svelte",
"chars": 0,
"preview": ""
},
{
"path": "src/lib/components/Code.svelte",
"chars": 583,
"preview": "<script lang=\"ts\">\n export let language = null\n export let data = []\n</script>\n\n<code\n class=\"block rounded-lg text-s"
},
{
"path": "src/lib/components/Collapse.svelte",
"chars": 0,
"preview": ""
},
{
"path": "src/lib/components/Docs/DocAccordion.svelte",
"chars": 1846,
"preview": "<script lang=\"ts\">\n import Accordion from '$lib/components/Accordion.svelte'\n import AccordionItem from '$lib/componen"
},
{
"path": "src/lib/components/Docs/DocAlert.svelte",
"chars": 829,
"preview": "<script lang=\"ts\">\n import Alert from '$lib/components/Alert.svelte'\n import Code from '$lib/components/Code.svelte'\n<"
},
{
"path": "src/lib/components/Docs/DocBadge.svelte",
"chars": 1185,
"preview": "<script lang=\"ts\">\n import Badge from '$lib/components/Badge.svelte'\n import Code from '$lib/components/Code.svelte'\n<"
},
{
"path": "src/lib/components/Dropdowns.svelte",
"chars": 0,
"preview": ""
},
{
"path": "src/lib/components/ListGroup.svelte",
"chars": 0,
"preview": ""
},
{
"path": "src/lib/components/Modal.svelte",
"chars": 0,
"preview": ""
},
{
"path": "src/lib/components/NavsAndTabs.svelte",
"chars": 0,
"preview": ""
},
{
"path": "src/lib/components/Pagination.svelte",
"chars": 0,
"preview": ""
},
{
"path": "src/lib/components/Popovers.svelte",
"chars": 0,
"preview": ""
},
{
"path": "src/lib/components/Spinners.svelte",
"chars": 0,
"preview": ""
},
{
"path": "src/lib/components/Toasts.svelte",
"chars": 0,
"preview": ""
},
{
"path": "src/lib/components/Tooltips.svelte",
"chars": 0,
"preview": ""
},
{
"path": "src/lib/form.ts",
"chars": 1614,
"preview": "import { invalidateAll } from '$app/navigation';\n\n// this action (https://svelte.dev/tutorial/actions) allows us to\n// p"
},
{
"path": "src/lib/header/Header.svelte",
"chars": 2187,
"preview": "<script lang=\"ts\">\n\timport { page } from '$app/stores'\n\timport logo from './svelte-logo.svg'\n</script>\n\n<header>\n\t<div c"
},
{
"path": "src/lib/ioevents/click.ts",
"chars": 653,
"preview": "/** Dispatch event on click outside of node */\nexport function clickOutside(node: any, except: any[] = []) {\n const han"
},
{
"path": "src/lib/ioevents/keydown.ts",
"chars": 391,
"preview": "/** Dispatch event on keydown Escape of node */\nexport function keydownEscape(node: any) {\n const handle = (event: any)"
},
{
"path": "src/lib/tailwind.css",
"chars": 484,
"preview": "@tailwind base;\n@tailwind components;\n@tailwind utilities;\n\n.bg-blog {\n\t@apply bg-blue-500;\n}\n\n.primary {\n\t@apply text-p"
},
{
"path": "src/lib/templates/Admin/API/form.ts",
"chars": 1032,
"preview": "export default function enhance(\n form: HTMLFormElement,\n {\n pending,\n error,\n result,\n }: {\n pending?: ("
},
{
"path": "src/lib/templates/Admin/Config/charts.ts",
"chars": 2848,
"preview": "/**\n * For usage, visit Chart.js docs https://www.chartjs.org/docs/latest/\n */\nexport const barConfig = {\n type: 'bar',"
},
{
"path": "src/lib/templates/Admin/Header.svelte",
"chars": 8892,
"preview": "<script lang=\"ts\">\n\timport {\n\t\tisDark,\n\t\tisNotificationsMenuOpen,\n\t\tisProfileMenuOpen,\n\t\ttoggleSideMenu,\n\t\ttoggleNotific"
},
{
"path": "src/lib/templates/Admin/SideBar.svelte",
"chars": 5454,
"preview": "<script lang=\"ts\">\n\timport { closeSideMenu, pageMenus, togglePageMenu, toggleSideMenu } from '$stores/menus'\n\timport { p"
},
{
"path": "src/lib/templates/Admin/ToggleTheme.svelte",
"chars": 1142,
"preview": "<script lang=\"ts\">\n import {\n isDark,\n toggleTheme,\n } from '$stores/menus'\n</script>\n\n<button\n class=\"rounded-"
},
{
"path": "src/lib/templates/Blog/Config/links.json",
"chars": 99,
"preview": "[\n {\n \"name\": \"Home\",\n \"url\": \"/\"\n },\n {\n \"name\": \"Resumé\",\n \"url\": \"/resume\"\n }\n]\n"
},
{
"path": "src/lib/templates/Blog/Config/particle.json",
"chars": 1976,
"preview": "{\n \"particles\": {\n \"number\": {\n \"value\": 24,\n \"density\": {\n \"enable\": true,\n \"value_area\": 8"
},
{
"path": "src/lib/templates/Blog/Header.svelte",
"chars": 1029,
"preview": "<script lang=\"ts\">\n import { isSideMenuOpen, toggleSideMenu } from '$stores/menus'\n import List from '$icon/List/List."
},
{
"path": "src/lib/templates/Blog/Particles/Particles.svelte",
"chars": 1272,
"preview": "<svelte:options accessors={true} />\n\n<script lang=\"ts\">\n\timport { afterUpdate, createEventDispatcher } from 'svelte'\n\tim"
},
{
"path": "src/lib/templates/Blog/Particles/global.d.ts",
"chars": 32,
"preview": "/// <reference types=\"svelte\" />"
},
{
"path": "src/lib/templates/Blog/Particles/index.d.ts",
"chars": 651,
"preview": "import type { SvelteComponentTyped } from \"svelte\";\nimport type { ISourceOptions, Engine, Container } from \"tsparticles-"
},
{
"path": "src/lib/templates/Blog/Particles/index.ts",
"chars": 57,
"preview": "export { default as default } from './Particles.svelte';\n"
},
{
"path": "src/lib/templates/Blog/SideBar.svelte",
"chars": 1143,
"preview": "<script lang=\"ts\">\n import { closeSideMenu, pageMenus, togglePageMenu } from '$stores/menus'\n import { page } from '$a"
},
{
"path": "src/lib/translator.ts",
"chars": 1250,
"preview": "const getLang = (): string => {\n // well, maybe base the language from\n // -> where the guest coming from? via API to "
},
{
"path": "src/routes/admin/(authenticated)/+layout.svelte",
"chars": 1524,
"preview": "<script lang=\"ts\">\n\timport '$lib/tailwind.css'\n\timport { isDark, isSideMenuOpen, closeSideMenu } from '$stores/menus'\n\ti"
},
{
"path": "src/routes/admin/(authenticated)/+page.svelte",
"chars": 23443,
"preview": "<svelte:head>\n <title>Dashboard</title>\n</svelte:head>\n\n<main class=\"h-full overflow-y-auto\">\n <div class=\"container p"
},
{
"path": "src/routes/admin/(authenticated)/buttons/+page.svelte",
"chars": 7242,
"preview": "<svelte:head>\n <title>Buttons</title>\n</svelte:head>\n\n<main class=\"h-full overflow-y-auto\">\n <div class=\"container gri"
},
{
"path": "src/routes/admin/(authenticated)/cards/+page.svelte",
"chars": 6130,
"preview": "<svelte:head>\n <title>Cards</title>\n</svelte:head>\n\n<main class=\"h-full pb-16 overflow-y-auto\">\n <div class=\"container"
},
{
"path": "src/routes/admin/(authenticated)/charts/+page.svelte",
"chars": 4408,
"preview": "<script lang=\"ts\">\n // import { barConfig, lineConfig, pieConfig } from '$lib/templates/Admin/Config/charts'\n // impor"
},
{
"path": "src/routes/admin/(authenticated)/components/+page.svelte",
"chars": 2086,
"preview": "<script lang=\"ts\">\n import DocAccordion from '$lib/components/Docs/DocAccordion.svelte'\n import DocAlert from '$lib/co"
},
{
"path": "src/routes/admin/(authenticated)/forms/+page.svelte",
"chars": 11146,
"preview": "<svelte:head>\n <title>Forms</title>\n</svelte:head>\n\n<main class=\"h-full pb-16 overflow-y-auto\">\n <div class=\"container"
},
{
"path": "src/routes/admin/(authenticated)/modals/+page.svelte",
"chars": 5297,
"preview": "<script lang=\"ts\">\n import { clickOutside } from '$lib/ioevents/click'\n import { keydownEscape } from '$lib/ioevents/k"
},
{
"path": "src/routes/admin/(authenticated)/tables/+page.svelte",
"chars": 49855,
"preview": "<svelte:head>\n <title>Tables</title>\n</svelte:head>\n\n<main class=\"h-full pb-16 overflow-y-auto\">\n <div class=\"containe"
},
{
"path": "src/routes/admin/(guest)/+layout.svelte",
"chars": 340,
"preview": "<script lang=\"ts\">\n\timport '$lib/tailwind.css'\n\timport { isDark } from '$stores/menus'\n\timport { browser } from '$app/en"
},
{
"path": "src/routes/admin/(guest)/auth/login/+page.server.ts",
"chars": 717,
"preview": "import { api } from '$src/routes/api';\nimport { redirect, type RequestEvent } from '@sveltejs/kit';\nimport type { Action"
},
{
"path": "src/routes/admin/(guest)/auth/login/+page.svelte",
"chars": 5639,
"preview": "<script lang=\"ts\">\n\timport loginOffice from '$lib/templates/Admin/Images/login-office.jpeg'\n\timport loginOfficeDark from"
},
{
"path": "src/routes/admin/(guest)/auth/logout/+page.server.ts",
"chars": 910,
"preview": "import { api } from '$src/routes/api';\nimport { redirect, type RequestEvent } from '@sveltejs/kit';\nimport type { Action"
},
{
"path": "src/routes/admin/(guest)/forgot-password/+page.svelte",
"chars": 2175,
"preview": "<script lang=\"ts\">\n import forgotPasswordOffice from '$lib/templates/Admin/Images/forgot-password-office.jpeg'\n import"
},
{
"path": "src/routes/admin/(guest)/register/+page.svelte",
"chars": 6565,
"preview": "<script lang=\"ts\">\n import createAccountOffice from '$lib/templates/Admin/Images/create-account-office.jpeg'\n import c"
},
{
"path": "src/routes/admin/+error.svelte",
"chars": 1014,
"preview": "<script lang=\"ts\">\n\timport '$lib/tailwind.css'\n\timport { isDark } from '$stores/menus'\n\timport { browser } from '$app/en"
},
{
"path": "src/routes/admin/+layout.server.ts",
"chars": 542,
"preview": "import { redirect } from '@sveltejs/kit';\nimport type { PageServerLoad } from './$types';\n\nexport const load: PageServer"
},
{
"path": "src/routes/admin/html_head.svelte",
"chars": 584,
"preview": "<script lang=\"ts\">\n\texport let isDark\n</script>\n\n<svelte:head>\n\t<meta name=\"theme-color\" content={$isDark ? '#1a1c23' : "
},
{
"path": "src/routes/api.ts",
"chars": 662,
"preview": "import type { RequestEvent } from \"@sveltejs/kit\";\n\ninterface ApiParams {\n\tmethod: string;\n\tevent?: RequestEvent;\n\tresou"
},
{
"path": "src/routes/blog/+layout.svelte",
"chars": 2016,
"preview": "<script lang=\"ts\">\n\timport '$lib/tailwind.css'\n\timport { fly } from 'svelte/transition'\n\timport { isSideMenuOpen, closeS"
},
{
"path": "src/routes/blog/+page.svelte",
"chars": 3898,
"preview": "<script lang=\"ts\">\n\timport Github from '$icon/Github/Github.svelte'\n\timport Building from '$icon/Building/Building.svelt"
},
{
"path": "src/routes/blog/resume/+page.svelte",
"chars": 6303,
"preview": "<script lang=\"ts\">\n\timport Badge from '$lib/components/Badge.svelte'\n\timport Info from '$icon/Info/Info.svelte'\n</script"
},
{
"path": "src/routes/demo/+layout.svelte",
"chars": 741,
"preview": "<script>\n\timport Header from './Header.svelte';\n\timport './styles.css';\n</script>\n\n<div class=\"app\">\n\t<Header />\n\n\t<main"
},
{
"path": "src/routes/demo/+page.svelte",
"chars": 989,
"preview": "<script>\n\timport Counter from './Counter.svelte';\n\timport welcome from '$lib/images/svelte-welcome.webp';\n\timport welcom"
},
{
"path": "src/routes/demo/+page.ts",
"chars": 148,
"preview": "// since there's no dynamic data here, we can prerender\n// it so that it gets served as a static asset in production\nexp"
},
{
"path": "src/routes/demo/Counter.svelte",
"chars": 1998,
"preview": "<script lang=\"ts\">\n\timport { spring } from 'svelte/motion';\n\n\tlet count = 0;\n\n\tconst displayed_count = spring();\n\t$: dis"
},
{
"path": "src/routes/demo/Header.svelte",
"chars": 2339,
"preview": "<script>\n\timport { page } from '$app/stores';\n\timport logo from '$lib/images/svelte-logo.svg';\n\timport github from '$lib"
},
{
"path": "src/routes/demo/about/+page.svelte",
"chars": 776,
"preview": "<svelte:head>\n\t<title>About</title>\n\t<meta name=\"description\" content=\"About this app\" />\n</svelte:head>\n\n<div class=\"te"
},
{
"path": "src/routes/demo/about/+page.ts",
"chars": 321,
"preview": "import { dev } from '$app/environment';\n\n// we don't need any JS on this page, though we'll load\n// it in dev so that we"
},
{
"path": "src/routes/demo/styles.css",
"chars": 1856,
"preview": "@import '@fontsource/fira-mono';\n\n:root {\n\t--font-body: Arial, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Ox"
},
{
"path": "src/routes/demo/sverdle/+page.server.ts",
"chars": 1760,
"preview": "import { fail } from '@sveltejs/kit';\nimport { Game } from './game';\nimport type { PageServerLoad, Actions } from './$ty"
},
{
"path": "src/routes/demo/sverdle/+page.svelte",
"chars": 8765,
"preview": "<script lang=\"ts\">\n\timport { confetti } from '@neoconfetti/svelte';\n\timport { enhance } from '$app/forms';\n\timport type "
},
{
"path": "src/routes/demo/sverdle/game.test.ts",
"chars": 254,
"preview": "import { describe, it, expect } from 'vitest';\nimport { Game } from './game';\n\ndescribe('game test', () => {\n\tit('return"
},
{
"path": "src/routes/demo/sverdle/game.ts",
"chars": 1784,
"preview": "import { words, allowed } from './words.server';\n\nexport class Game {\n\tindex: number;\n\tguesses: string[];\n\tanswers: stri"
},
{
"path": "src/routes/demo/sverdle/how-to-play/+page.svelte",
"chars": 2157,
"preview": "<svelte:head>\n\t<title>How to play Sverdle</title>\n\t<meta name=\"description\" content=\"How to play Sverdle\" />\n</svelte:he"
},
{
"path": "src/routes/demo/sverdle/how-to-play/+page.ts",
"chars": 321,
"preview": "import { dev } from '$app/environment';\n\n// we don't need any JS on this page, though we'll load\n// it in dev so that we"
},
{
"path": "src/routes/demo/sverdle/reduced-motion.ts",
"chars": 714,
"preview": "import { readable } from 'svelte/store';\nimport { browser } from '$app/environment';\n\nconst reduced_motion_query = '(pre"
},
{
"path": "src/routes/demo/sverdle/words.server.ts",
"chars": 129909,
"preview": "/** The list of possible words */\nexport const words = [\n\t'aback',\n\t'abase',\n\t'abate',\n\t'abbey',\n\t'abbot',\n\t'abhor',\n\t'a"
},
{
"path": "src/service-worker.ts",
"chars": 3776,
"preview": "/// <reference lib=\"webworker\" />\n\nimport { build, files, version } from \"$service-worker\";\n\nconst worker = self as unkn"
},
{
"path": "src/stores/menus.ts",
"chars": 1160,
"preview": "import { writable } from 'svelte/store'\n\nexport const isDark = writable(false)\nexport const isSideMenuOpen = writable(fa"
},
{
"path": "start/route.js",
"chars": 918,
"preview": "// ---------------------------------------------------------\n// SvelteKit Starter: here we determine based on the ./run\n"
},
{
"path": "start/tailwind/admin.cjs",
"chars": 3339,
"preview": "const defaultTheme = require('tailwindcss/defaultTheme')\n\nmodule.exports = {\n\tmode: 'jit',\n\tpurge: ['src/app.html', 'src"
},
{
"path": "start/tailwind/daisy-ui.cjs",
"chars": 351,
"preview": "// const defaultTheme = require('tailwindcss/defaultTheme')\n\nmodule.exports = {\n\t// darkMode: false,\n\tcontent: ['./src/*"
},
{
"path": "start/tailwind/index.cjs",
"chars": 446,
"preview": "// ---------------------------------------------------------\n// SvelteKit Starter: here we determine based on the ./run\n"
},
{
"path": "start/vite/default.vite.config.js",
"chars": 382,
"preview": "import { sveltekit } from '@sveltejs/kit/vite'\nimport { resolve } from 'path'\n\n/** @type {import('vite').UserConfig} */\n"
},
{
"path": "start/vite/index.js",
"chars": 406,
"preview": "// ---------------------------------------------------------\n// SvelteKit Starter: here we determine based on the ./run\n"
},
{
"path": "static/manifest.json",
"chars": 1178,
"preview": "{\n\t\"$schema\": \"http://json.schemastore.org/web-manifest\",\n\t\"short_name\": \"SvelteKit Starter\",\n\t\"name\": \"SvelteKit Starte"
},
{
"path": "static/robots.txt",
"chars": 67,
"preview": "# https://www.robotstxt.org/robotstxt.html\nUser-agent: *\nDisallow:\n"
},
{
"path": "svelte.config.js",
"chars": 761,
"preview": "import adapter from '@sveltejs/adapter-auto'\nimport { vitePreprocess } from '@sveltejs/kit/vite'\nimport route from './st"
},
{
"path": "tailwind.config.cjs",
"chars": 77,
"preview": "const config = require('./start/tailwind/index.cjs')\nmodule.exports = config\n"
},
{
"path": "tests/demo.ts",
"chars": 207,
"preview": "import { expect, test } from '@playwright/test';\n\ntest('demo: about page has expected h1', async ({ page }) => {\n\tawait "
},
{
"path": "tsconfig.json",
"chars": 625,
"preview": "{\n\t\"extends\": \"./.svelte-kit/tsconfig.json\",\n\t\"compilerOptions\": {\n\t\t\"allowJs\": true,\n\t\t\"checkJs\": true,\n\t\t\"esModuleInte"
},
{
"path": "vite.config.js",
"chars": 474,
"preview": "import base from './start/vite/default.vite.config.js'\nimport folder from './start/vite'\n\n/** @type {import('vite').User"
}
]
About this extraction
This page contains the full source code of the daison12006013/sveltekit-starter GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 118 files (357.1 KB), approximately 134.5k tokens, and a symbol index with 18 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.