Daisy UI #14

Merged
BenjaminPalko merged 28 commits from daisy-ui into master 2024-12-19 21:20:21 -05:00
56 changed files with 192 additions and 182 deletions
Showing only changes of commit 783f0553f3 - Show all commits

View file

@ -1,8 +1,14 @@
{ {
"useTabs": true, "useTabs": true,
"singleQuote": true, "singleQuote": true,
"trailingComma": "none", "trailingComma": "es5",
"printWidth": 100, "printWidth": 100,
piopi commented 2024-12-19 21:02:26 -05:00 (Migrated from github.com)
Review

🙈

🙈
"endOfLine": "lf",
"arrowParens": "always",
"jsxSingleQuote": false,
"semi": true,
"quoteProps": "as-needed",
"tabWidth": 4,
"plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"], "plugins": ["prettier-plugin-svelte", "prettier-plugin-tailwindcss"],
"overrides": [ "overrides": [
{ {

View file

@ -7,11 +7,11 @@ const config = {
'@storybook/addon-interactions', '@storybook/addon-interactions',
'@storybook/addon-styling-webpack', '@storybook/addon-styling-webpack',
'@storybook/addon-svelte-csf', '@storybook/addon-svelte-csf',
'@storybook/addon-themes' '@storybook/addon-themes',
], ],
framework: { framework: {
name: '@storybook/sveltekit', name: '@storybook/sveltekit',
options: {} options: {},
} },
}; };
export default config; export default config;

View file

@ -8,21 +8,21 @@ const preview = {
controls: { controls: {
matchers: { matchers: {
color: /(background|color)$/i, color: /(background|color)$/i,
date: /Date$/i date: /Date$/i,
} },
} },
}, },
decorators: [ decorators: [
withThemeByDataAttribute({ withThemeByDataAttribute({
themes: { themes: {
light: 'light', light: 'light',
dark: 'dark', dark: 'dark',
night: 'night' night: 'night',
}, },
defaultTheme: 'dark', defaultTheme: 'dark',
attributeName: 'data-theme' attributeName: 'data-theme',
}) }),
] ],
}; };
export default preview; export default preview;

View file

@ -18,17 +18,17 @@ export default ts.config(
languageOptions: { languageOptions: {
globals: { globals: {
...globals.browser, ...globals.browser,
...globals.node ...globals.node,
} },
} },
}, },
{ {
files: ['**/*.svelte'], files: ['**/*.svelte'],
languageOptions: { languageOptions: {
parserOptions: { parserOptions: {
parser: ts.parser parser: ts.parser,
} },
} },
} }
); );

View file

@ -3,8 +3,8 @@ import { defineConfig } from '@playwright/test';
export default defineConfig({ export default defineConfig({
webServer: { webServer: {
command: 'npm run build && npm run preview', command: 'npm run build && npm run preview',
port: 4173 port: 4173,
}, },
testDir: 'e2e' testDir: 'e2e',
}); });

View file

@ -1,6 +1,6 @@
export default { export default {
plugins: { plugins: {
tailwindcss: {}, tailwindcss: {},
autoprefixer: {} autoprefixer: {},
} },
}; };

3
src/app.d.ts vendored
View file

@ -2,10 +2,9 @@
// for information about these interfaces // for information about these interfaces
declare global { declare global {
namespace App { namespace App {
// interface Error {} // interface Error {}
interface Locals { interface Locals {
user: import("lucia").User | null; user: import('lucia').User | null;
session: import('lucia').Session | null; session: import('lucia').Session | null;
} }
piopi commented 2024-12-19 21:03:51 -05:00 (Migrated from github.com)
Review

Will need to remove this when we switch to Clerk, maybe add a Todo to not forget it ?

Will need to remove this when we switch to Clerk, maybe add a Todo to not forget it ?
// interface PageData {} // interface PageData {}

View file

@ -4,7 +4,7 @@
const { Story } = defineMeta({ const { Story } = defineMeta({
title: 'Navigation/Navbar', title: 'Navigation/Navbar',
component: Navbar component: Navbar,
}); });
</script> </script>

View file

@ -10,13 +10,13 @@
argTypes: { argTypes: {
size: { size: {
control: 'select', control: 'select',
options: ['xs', 'sm', 'rg', 'lg'] options: ['xs', 'sm', 'rg', 'lg'],
}, },
variant: { variant: {
control: 'select', control: 'select',
options: ['none', 'bordered', 'lifted', 'boxed'] options: ['none', 'bordered', 'lifted', 'boxed'],
} },
} },
}); });
</script> </script>

View file

@ -7,7 +7,7 @@
title: 'Actions/Button', title: 'Actions/Button',
component: Button, component: Button,
args: { args: {
onClick: fn() onClick: fn(),
}, },
argTypes: { argTypes: {
color: { color: {
@ -22,22 +22,22 @@
'info', 'info',
'success', 'success',
'warning', 'warning',
'error' 'error',
] ],
}, },
outline: { outline: {
control: 'boolean' control: 'boolean',
}, },
size: { size: {
control: 'select', control: 'select',
options: ['Default', 'xs', 'sm', 'lg'], options: ['Default', 'xs', 'sm', 'lg'],
defaultValue: 'Default' defaultValue: 'Default',
}, },
type: { type: {
control: 'select', control: 'select',
options: ['button', 'reset', 'submit'] options: ['button', 'reset', 'submit'],
} },
} },
}); });
</script> </script>

View file

@ -25,7 +25,7 @@
responsive = false, responsive = false,
size, size,
type = 'button', type = 'button',
wide = false wide = false,
}: Props = $props(); }: Props = $props();
</script> </script>

View file

@ -4,7 +4,7 @@
const { Story } = defineMeta({ const { Story } = defineMeta({
title: 'Feedback/Loader', title: 'Feedback/Loader',
component: Loader component: Loader,
}); });
</script> </script>

View file

@ -17,22 +17,22 @@
'info', 'info',
'success', 'success',
'warning', 'warning',
'error' 'error',
] ],
}, },
bordered: { bordered: {
control: 'boolean' control: 'boolean',
}, },
size: { size: {
control: 'select', control: 'select',
options: ['Default', 'xs', 'sm', 'lg'], options: ['Default', 'xs', 'sm', 'lg'],
defaultValue: 'Default' defaultValue: 'Default',
}, },
type: { type: {
control: 'select', control: 'select',
options: ['email', 'password', 'search', 'tel', 'text', 'url'] options: ['email', 'password', 'search', 'tel', 'text', 'url'],
} },
} },
}); });
</script> </script>

View file

@ -30,7 +30,7 @@
name, name,
placeholder, placeholder,
size, size,
type = 'text' type = 'text',
}: Props = $props(); }: Props = $props();
</script> </script>

View file

@ -8,7 +8,7 @@ export interface Configuration {
export const LoadConfig = (): Configuration => { export const LoadConfig = (): Configuration => {
const { success, data, error } = z const { success, data, error } = z
.object({ .object({
VITE_APP_VERSION: z.string().default('development') VITE_APP_VERSION: z.string().default('development'),
}) })
.safeParse(import.meta.env); .safeParse(import.meta.env);
@ -17,7 +17,7 @@ export const LoadConfig = (): Configuration => {
} }
return { return {
app_version: data!.VITE_APP_VERSION app_version: data!.VITE_APP_VERSION,
}; };
}; };

View file

@ -19,5 +19,5 @@ export const yogaLogger: YogaLogger = {
error(...args) { error(...args) {
// @ts-expect-error types dont match // @ts-expect-error types dont match
logger.error(...args); logger.error(...args);
} },
}; };

View file

@ -7,14 +7,14 @@ const adapter = new PrismaAdapter(prisma.session, prisma.user);
export const auth = new Lucia(adapter, { export const auth = new Lucia(adapter, {
sessionCookie: { sessionCookie: {
attributes: { attributes: {
secure: process.env.NODE_ENV === 'production' secure: process.env.NODE_ENV === 'production',
} },
}, },
getUserAttributes: (attributes) => { getUserAttributes: (attributes) => {
return { return {
email: attributes.email email: attributes.email,
}; };
} },
}); });
declare module 'lucia' { declare module 'lucia' {

View file

@ -23,6 +23,6 @@ export const builder = new SchemaBuilder<PothosType>({
// use where clause from prismaRelatedConnection for totalCount (defaults to true) // use where clause from prismaRelatedConnection for totalCount (defaults to true)
filterConnectionTotalCount: true, filterConnectionTotalCount: true,
// warn when not using a query parameter correctly // warn when not using a query parameter correctly
onUnusedQuery: process.env.NODE_ENV === 'production' ? null : 'warn' onUnusedQuery: process.env.NODE_ENV === 'production' ? null : 'warn',
} },
}); });

View file

@ -10,5 +10,5 @@ export const DateScalar = builder.scalarType('Date', {
throw new Error('Cyka blyat'); throw new Error('Cyka blyat');
} }
return new Date(date); return new Date(date);
} },
}); });

View file

@ -5,7 +5,7 @@ builder.queryType({});
builder.queryField('version', (t) => builder.queryField('version', (t) =>
t.string({ t.string({
description: 'Application version', description: 'Application version',
resolve: (parent, args, context) => context.config.app_version resolve: (parent, args, context) => context.config.app_version,
}) })
); );

View file

@ -9,39 +9,39 @@ export const Post = builder.prismaObject('Post', {
published: t.exposeBoolean('published'), published: t.exposeBoolean('published'),
author: t.relation('author'), author: t.relation('author'),
createdAt: t.expose('createdAt', { createdAt: t.expose('createdAt', {
type: 'Date' type: 'Date',
}), }),
updatedAt: t.expose('updatedAt', { updatedAt: t.expose('updatedAt', {
type: 'Date' type: 'Date',
}) }),
}) }),
}); });
const CreatePost = builder.inputType('CreatePost', { const CreatePost = builder.inputType('CreatePost', {
fields: (t) => ({ fields: (t) => ({
title: t.string({ title: t.string({
required: true required: true,
}), }),
content: t.string({ content: t.string({
required: true required: true,
}), }),
published: t.boolean(), published: t.boolean(),
authorId: t.id({ authorId: t.id({
required: true required: true,
}) }),
}) }),
}); });
const UpdatePost = builder.inputType('UpdatePost', { const UpdatePost = builder.inputType('UpdatePost', {
fields: (t) => ({ fields: (t) => ({
id: t.id({ id: t.id({
required: true required: true,
}), }),
title: t.string(), title: t.string(),
content: t.string(), content: t.string(),
published: t.boolean(), published: t.boolean(),
authorId: t.id() authorId: t.id(),
}) }),
}); });
builder.queryFields((t) => ({ builder.queryFields((t) => ({
@ -49,19 +49,19 @@ builder.queryFields((t) => ({
type: [Post], type: [Post],
resolve: async () => { resolve: async () => {
return await prisma.post.findMany(); return await prisma.post.findMany();
} },
}) }),
})); }));
builder.mutationFields((t) => ({ builder.mutationFields((t) => ({
createPost: t.field({ createPost: t.field({
type: Post, type: Post,
args: { args: {
input: t.arg({ required: true, type: CreatePost }) input: t.arg({ required: true, type: CreatePost }),
}, },
resolve: async (parent, args) => { resolve: async (parent, args) => {
const author = await prisma.user.findUnique({ const author = await prisma.user.findUnique({
where: { id: Number(args.input.authorId) } where: { id: Number(args.input.authorId) },
}); });
if (!author) { if (!author) {
throw new Error('Author does not exist!'); throw new Error('Author does not exist!');
@ -73,23 +73,23 @@ builder.mutationFields((t) => ({
published: args.input.published, published: args.input.published,
author: { author: {
connect: { connect: {
id: author.id id: author.id,
} },
} },
} },
}); });
return post; return post;
} },
}), }),
updatePost: t.field({ updatePost: t.field({
type: Post, type: Post,
args: { args: {
input: t.arg({ required: true, type: UpdatePost }) input: t.arg({ required: true, type: UpdatePost }),
}, },
resolve: async (parent, args) => { resolve: async (parent, args) => {
const post = await prisma.post.update({ const post = await prisma.post.update({
where: { where: {
id: Number(args.input.id) id: Number(args.input.id),
}, },
data: { data: {
title: args.input.title ?? undefined, title: args.input.title ?? undefined,
@ -98,13 +98,13 @@ builder.mutationFields((t) => ({
...(args.input.authorId && { ...(args.input.authorId && {
author: { author: {
connect: { connect: {
id: Number(args.input.authorId) id: Number(args.input.authorId),
} },
} },
}) }),
} },
}); });
return post; return post;
} },
}) }),
})); }));

View file

@ -8,33 +8,33 @@ export const User = builder.prismaObject('User', {
name: t.exposeString('name'), name: t.exposeString('name'),
posts: t.relation('posts'), posts: t.relation('posts'),
createdAt: t.expose('createdAt', { createdAt: t.expose('createdAt', {
type: 'Date' type: 'Date',
}), }),
updatedAt: t.expose('updatedAt', { updatedAt: t.expose('updatedAt', {
type: 'Date' type: 'Date',
}) }),
}) }),
}); });
const CreateUser = builder.inputType('CreateUser', { const CreateUser = builder.inputType('CreateUser', {
fields: (t) => ({ fields: (t) => ({
email: t.string({ email: t.string({
required: true required: true,
}), }),
name: t.string({ name: t.string({
required: true required: true,
}) }),
}) }),
}); });
const UpdateUser = builder.inputType('UpdateUser', { const UpdateUser = builder.inputType('UpdateUser', {
fields: (t) => ({ fields: (t) => ({
id: t.id({ id: t.id({
required: true required: true,
}), }),
email: t.string(), email: t.string(),
name: t.string() name: t.string(),
}) }),
}); });
builder.queryFields((t) => ({ builder.queryFields((t) => ({
@ -42,42 +42,42 @@ builder.queryFields((t) => ({
type: [User], type: [User],
resolve: async () => { resolve: async () => {
return await prisma.user.findMany(); return await prisma.user.findMany();
} },
}) }),
})); }));
builder.mutationFields((t) => ({ builder.mutationFields((t) => ({
createUser: t.field({ createUser: t.field({
type: User, type: User,
args: { args: {
input: t.arg({ required: true, type: CreateUser }) input: t.arg({ required: true, type: CreateUser }),
}, },
resolve: async (parent, args) => { resolve: async (parent, args) => {
const post = await prisma.user.create({ const post = await prisma.user.create({
data: { data: {
email: args.input.email, email: args.input.email,
name: args.input.name name: args.input.name,
} },
}); });
return post; return post;
} },
}), }),
updateUser: t.field({ updateUser: t.field({
type: User, type: User,
args: { args: {
input: t.arg({ required: true, type: UpdateUser }) input: t.arg({ required: true, type: UpdateUser }),
}, },
resolve: async (parent, args) => { resolve: async (parent, args) => {
const post = await prisma.user.update({ const post = await prisma.user.update({
where: { where: {
id: Number(args.input.id) id: Number(args.input.id),
}, },
data: { data: {
email: args.input.email, email: args.input.email,
name: args.input.name ?? undefined name: args.input.name ?? undefined,
} },
}); });
return post; return post;
} },
}) }),
})); }));

View file

@ -3,5 +3,5 @@ import type { YogaInitialContext } from 'graphql-yoga';
export const Context = (initialContext: YogaInitialContext) => ({ export const Context = (initialContext: YogaInitialContext) => ({
...initialContext, ...initialContext,
config: Config config: Config,
}); });

View file

@ -10,5 +10,5 @@ export const Yoga = createYoga<RequestEvent>({
graphqlEndpoint: '/api/graphql', graphqlEndpoint: '/api/graphql',
// Let Yoga use sveltekit's Response object // Let Yoga use sveltekit's Response object
fetchAPI: { Response }, fetchAPI: { Response },
logging: yogaLogger logging: yogaLogger,
}); });

View file

@ -3,15 +3,15 @@ export async function load(event) {
const userId = event.cookies.get('user'); const userId = event.cookies.get('user');
if (!userId) { if (!userId) {
return { return {
authenticated: false authenticated: false,
}; };
} }
const user = await prisma.user.findUnique({ const user = await prisma.user.findUnique({
where: { where: {
id: userId id: userId,
} },
}); });
return { return {
authenticated: !!user authenticated: !!user,
}; };
} }

View file

@ -12,8 +12,8 @@ export const actions = {
} }
const user = await prisma.user.findUnique({ const user = await prisma.user.findUnique({
where: { where: {
email: form.get('email') as string email: form.get('email') as string,
} },
}); });
if (!user) { if (!user) {
logger.error('User not found! ${user}'); logger.error('User not found! ${user}');
@ -31,7 +31,7 @@ export const actions = {
const sessionCookie = auth.createSessionCookie(session.id); const sessionCookie = auth.createSessionCookie(session.id);
event.cookies.set(sessionCookie.name, sessionCookie.value, { event.cookies.set(sessionCookie.name, sessionCookie.value, {
path: '/', path: '/',
maxAge: 120 maxAge: 120,
}); });
redirect(302, '/'); redirect(302, '/');
}, },
@ -47,8 +47,8 @@ export const actions = {
data: { data: {
email: form.get('email') as string, email: form.get('email') as string,
name: form.get('name') as string, name: form.get('name') as string,
password: hashedPassword password: hashedPassword,
} },
}); });
const session = await auth.createSession(user.id.toString(), {}); const session = await auth.createSession(user.id.toString(), {});
const sessionCookie = auth.createSessionCookie(session.id); const sessionCookie = auth.createSessionCookie(session.id);
@ -57,8 +57,8 @@ export const actions = {
} }
event.cookies.set(sessionCookie.name, sessionCookie.value, { event.cookies.set(sessionCookie.name, sessionCookie.value, {
path: '/', path: '/',
maxAge: 120 maxAge: 120,
}); });
redirect(302, '/'); redirect(302, '/');
} },
} satisfies Actions; } satisfies Actions;

View file

@ -23,7 +23,12 @@
<form method="POST" action={`?/${variant}`}> <form method="POST" action={`?/${variant}`}>
<div class="card-body gap-4"> <div class="card-body gap-4">
<TextInput start={userIcon} placeholder="Email" name="email" type="email" /> <TextInput start={userIcon} placeholder="Email" name="email" type="email" />
<TextInput start={passwordIcon} placeholder="Password" name="password" type="password" /> <TextInput
start={passwordIcon}
placeholder="Password"
name="password"
type="password"
/>
{#if variant === 'register'} {#if variant === 'register'}
<TextInput start={nameIcon} placeholder="Name" name="name" fade /> <TextInput start={nameIcon} placeholder="Name" name="name" fade />
{/if} {/if}

View file

@ -11,8 +11,8 @@ const config = {
// adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list. // adapter-auto only supports some environments, see https://svelte.dev/docs/kit/adapter-auto for a list.
// If your environment is not supported, or you settled on a specific environment, switch out the adapter. // If your environment is not supported, or you settled on a specific environment, switch out the adapter.
// See https://svelte.dev/docs/kit/adapters for more information about adapters. // See https://svelte.dev/docs/kit/adapters for more information about adapters.
adapter: adapter() adapter: adapter(),
} },
}; };
export default config; export default config;

View file

@ -8,22 +8,22 @@ export default {
theme: { theme: {
extend: { extend: {
fontFamily: { fontFamily: {
display: ['Baskervville SC'] display: ['Baskervville SC'],
}, },
animation: { animation: {
fade: 'fadeIn .5s ease-in-out' fade: 'fadeIn .5s ease-in-out',
}, },
keyframes: { keyframes: {
fadeIn: { fadeIn: {
from: { opacity: '0' }, from: { opacity: '0' },
to: { opacity: '1' } to: { opacity: '1' },
} },
} },
} },
}, },
plugins: [typography, daisyui], plugins: [typography, daisyui],
daisyui: { daisyui: {
logs: false logs: false,
} },
} satisfies Config; } satisfies Config;

View file

@ -5,6 +5,6 @@ export default defineConfig({
plugins: [sveltekit()], plugins: [sveltekit()],
test: { test: {
include: ['src/**/*.{test,spec}.{js,ts}'] include: ['src/**/*.{test,spec}.{js,ts}'],
} },
}); });