diff --git a/.github/workflows/deploy-docker.yaml b/.github/workflows/deploy-docker.yaml index 20c9802b9..f5450d712 100644 --- a/.github/workflows/deploy-docker.yaml +++ b/.github/workflows/deploy-docker.yaml @@ -58,7 +58,7 @@ jobs: steps: - name: Checkout with tags - uses: actions/checkout@v3 + uses: actions/checkout@v4 with: fetch-depth: 0 ref: ${{ matrix.packages.ref }} diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml index 03f3f1079..c50f7dcae 100644 --- a/.github/workflows/e2e.yaml +++ b/.github/workflows/e2e.yaml @@ -11,7 +11,7 @@ jobs: name: Checkout - name: Install pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v4 id: pnpm-install with: run_install: false diff --git a/.github/workflows/release-without-versioning.yaml b/.github/workflows/release-without-versioning.yaml index b1ec94c1d..0909656c4 100644 --- a/.github/workflows/release-without-versioning.yaml +++ b/.github/workflows/release-without-versioning.yaml @@ -48,7 +48,7 @@ jobs: node-version-file: .nvmrc - name: Install pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v4 id: pnpm-install with: run_install: false diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 71088d3f9..7d54e2fc1 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -76,7 +76,7 @@ jobs: node-version-file: .nvmrc - name: Install pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v4 id: pnpm-install with: run_install: false diff --git a/.github/workflows/reusable-ci.yaml b/.github/workflows/reusable-ci.yaml index de88a080a..722f14c2c 100644 --- a/.github/workflows/reusable-ci.yaml +++ b/.github/workflows/reusable-ci.yaml @@ -22,7 +22,7 @@ jobs: fetch-depth: 0 - name: Install pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v4 id: pnpm-install with: run_install: false diff --git a/apps/analytics/package.json b/apps/analytics/package.json index 4de3e4599..e49faf260 100644 --- a/apps/analytics/package.json +++ b/apps/analytics/package.json @@ -9,8 +9,8 @@ "format": "eslint . --fix" }, "dependencies": { - "@cugetreg/database": "workspace:*", - "dotenv-cli": "^7.4.4", + "@repo/database": "workspace:*", + "dotenv-cli": "^8.0.0", "drizzle-orm": "^0.38.1", "postgres": "^3.4.5", "tsx": "^4.19.2" diff --git a/apps/analytics/src/index.ts b/apps/analytics/src/index.ts index f185b0e0b..43ff16cef 100644 --- a/apps/analytics/src/index.ts +++ b/apps/analytics/src/index.ts @@ -1,8 +1,9 @@ -import { user } from '@cugetreg/database' import { count, like } from 'drizzle-orm' import { drizzle } from 'drizzle-orm/postgres-js' import postgres from 'postgres' +import { user } from '@repo/database' + import { emailYear, faculty } from './constants.js' export const pgClient = postgres(process.env.DATABASE_URL as string) diff --git a/apps/storybook/package.json b/apps/storybook/package.json index d682a3b76..87e597135 100644 --- a/apps/storybook/package.json +++ b/apps/storybook/package.json @@ -4,7 +4,7 @@ "version": "0.0.0", "type": "module", "scripts": { - "dev": "storybook dev -p 6006", + "dev": "storybook dev -p 5342", "build": "storybook build", "check": "svelte-check --tsconfig ./tsconfig.json", "lint": "eslint . && prettier --check \"src/**/*.mdx\"", @@ -18,22 +18,22 @@ "@storybook/addon-essentials": "^8.4.7", "@storybook/addon-interactions": "^8.4.7", "@storybook/addon-links": "^8.4.7", - "@storybook/addon-svelte-csf": "^4.2.0", + "@storybook/addon-svelte-csf": "^5.0.0-next.21", "@storybook/addon-themes": "^8.4.7", "@storybook/blocks": "^8.4.7", "@storybook/svelte": "^8.4.7", "@storybook/svelte-vite": "^8.4.7", "@storybook/test": "^8.4.7", - "@sveltejs/vite-plugin-svelte": "^3.1.2", + "@sveltejs/vite-plugin-svelte": "^5.0.3", "@tsconfig/svelte": "^5.0.4", - "eslint": "^9.16.0", + "eslint": "^9.17.0", "sass-embedded": "^1.83.0", "storybook": "^8.4.7", - "svelte": "^4.2.18", + "svelte": "^5.15.0", "svelte-check": "^4.1.1", - "tailwindcss": "^3.4.16", + "tailwindcss": "^3.4.17", "tslib": "^2.8.1", "typescript": "^5.7.2", - "vite": "^6.0.3" + "vite": "^6.0.5" } } diff --git a/apps/web/package.json b/apps/web/package.json index eb83a8ee8..eb2a2ad26 100644 --- a/apps/web/package.json +++ b/apps/web/package.json @@ -4,7 +4,7 @@ "private": true, "type": "module", "scripts": { - "dev": "vite dev", + "dev": "vite dev --clearScreen false", "build": "vite build", "preview": "vite preview", "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", @@ -15,27 +15,30 @@ "test:unit": "vitest" }, "dependencies": { + "@repo/database": "workspace:*", "@repo/ui": "workspace:*" }, "devDependencies": { "@playwright/test": "^1.49.1", "@repo/config": "workspace:^", - "@sveltejs/adapter-auto": "^3.3.1", - "@sveltejs/kit": "^2.11.1", - "@sveltejs/vite-plugin-svelte": "^3.1.2", - "@typescript-eslint/eslint-plugin": "^8.18.0", - "@typescript-eslint/parser": "^8.18.0", + "@sveltejs/adapter-node": "^5.2.11", + "@sveltejs/kit": "^2.15.0", + "@sveltejs/vite-plugin-svelte": "^5.0.3", + "@typescript-eslint/eslint-plugin": "^8.18.2", + "@typescript-eslint/parser": "^8.18.2", "autoprefixer": "^10.4.20", - "eslint": "^9.16.0", + "drizzle-orm": "^0.38.1", + "eslint": "^9.17.0", "postcss": "^8.4.49", + "postgres": "^3.4.5", "prettier": "^3.4.2", "prettier-plugin-svelte": "^3.3.2", - "svelte": "^4.2.18", + "svelte": "^5.15.0", "svelte-check": "^4.1.1", - "tailwindcss": "^3.4.16", + "tailwindcss": "^3.4.17", "tslib": "^2.8.1", "typescript": "^5.7.2", - "vite": "^5.4.11", + "vite": "^6.0.5", "vitest": "^2.1.8" } } diff --git a/apps/web/src/lib/db.ts b/apps/web/src/lib/db.ts new file mode 100644 index 000000000..e34473208 --- /dev/null +++ b/apps/web/src/lib/db.ts @@ -0,0 +1,7 @@ +import { drizzle } from 'drizzle-orm/postgres-js' +import postgres from 'postgres' + +import { env } from '$env/dynamic/private' + +export const pgClient = postgres(env.DATABASE_URL as string) +export const db = drizzle(pgClient) diff --git a/apps/web/src/routes/+layout.svelte b/apps/web/src/routes/+layout.svelte index 0b65c34e5..cc4ad0bb7 100644 --- a/apps/web/src/routes/+layout.svelte +++ b/apps/web/src/routes/+layout.svelte @@ -1,5 +1,13 @@ - - +{@render children()} diff --git a/apps/web/src/routes/+page.server.ts b/apps/web/src/routes/+page.server.ts deleted file mode 100644 index 8a7129bf0..000000000 --- a/apps/web/src/routes/+page.server.ts +++ /dev/null @@ -1,7 +0,0 @@ -export const load = async () => { - return { - props: { - title: 'Page', - }, - } -} diff --git a/apps/web/src/routes/+page.svelte b/apps/web/src/routes/+page.svelte index cfc96deeb..b812f89db 100644 --- a/apps/web/src/routes/+page.svelte +++ b/apps/web/src/routes/+page.svelte @@ -8,7 +8,7 @@ import { Input } from '@repo/ui/input' import { RecommendedTag } from '@repo/ui/recommended-tag' - let counter = 0 + let counter = $state(0) const onButtonClick = () => { counter++ @@ -17,7 +17,7 @@

Web

- + {counter} @@ -30,9 +30,9 @@ รหัสผ่าน Closable @@ -40,7 +40,7 @@

Testtsetst

- +

RecommendedTag

@@ -53,3 +53,5 @@ + +Click to go to DB Demo diff --git a/apps/web/src/routes/dbdemo/+page.server.ts b/apps/web/src/routes/dbdemo/+page.server.ts new file mode 100644 index 000000000..3c6c2d277 --- /dev/null +++ b/apps/web/src/routes/dbdemo/+page.server.ts @@ -0,0 +1,17 @@ +import { eq } from 'drizzle-orm' + +import { course } from '@repo/database' + +import { db } from '$lib/db' + +import type { PageServerLoad } from './$types.js' + +export const load: PageServerLoad = async () => { + return { + course: await db + .select() + .from(course) + .where(eq(course.courseNo, '2110101')) + .orderBy(course.academicYear, course.semester), + } +} diff --git a/apps/web/src/routes/dbdemo/+page.svelte b/apps/web/src/routes/dbdemo/+page.svelte new file mode 100644 index 000000000..237ab3574 --- /dev/null +++ b/apps/web/src/routes/dbdemo/+page.svelte @@ -0,0 +1,11 @@ + + +

DB Demo

+ +

+ {JSON.stringify(data.course, null, 2)} +

diff --git a/apps/web/svelte.config.js b/apps/web/svelte.config.js index 98d7453fe..e45e65d0d 100644 --- a/apps/web/svelte.config.js +++ b/apps/web/svelte.config.js @@ -1,4 +1,4 @@ -import adapter from '@sveltejs/adapter-auto' +import adapter from '@sveltejs/adapter-node' import { vitePreprocess } from '@sveltejs/vite-plugin-svelte' /** @type {import('@sveltejs/kit').Config} */ @@ -7,8 +7,6 @@ const config = { // for more information about preprocessors preprocess: vitePreprocess(), kit: { - // adapter-auto only supports some environments, see https://kit.svelte.dev/docs/adapter-auto for a list. - // If your environment is not supported or you settled on a specific environment, switch out the adapter. // See https://kit.svelte.dev/docs/adapters for more information about adapters. adapter: adapter(), }, diff --git a/apps/web/vite.config.ts b/apps/web/vite.config.ts index ded32f167..f1cc3e27f 100644 --- a/apps/web/vite.config.ts +++ b/apps/web/vite.config.ts @@ -12,9 +12,12 @@ export default defineConfig({ }, }, server: { - port: 5173, + port: 5343, fs: { allow: ['../../packages/ui/src'], }, }, + preview: { + port: 4343, + }, }) diff --git a/package.json b/package.json index 7246ebab7..49af40ff2 100644 --- a/package.json +++ b/package.json @@ -6,16 +6,16 @@ "build": "turbo run build", "dev": "turbo run dev", "lint": "turbo run --continue lint", - "format": "turbo run --continue format" + "format": "turbo run --continue format", + "storybook:dev": "turbo run --filter=@app/storybook dev" }, "devDependencies": { "@changesets/changelog-github": "^0.5.0", - "@changesets/cli": "^2.27.10", + "@changesets/cli": "^2.27.11", "@repo/config": "workspace:^", - "@types/eslint": "^9.6.1", - "eslint": "^9.16.0", + "eslint": "^9.17.0", "prettier": "^3.4.2", "turbo": "^2.3.3" }, - "packageManager": "pnpm@9.15.0" + "packageManager": "pnpm@9.15.1" } diff --git a/packages/config/package.json b/packages/config/package.json index 2a18e25c1..e65a9724a 100644 --- a/packages/config/package.json +++ b/packages/config/package.json @@ -8,8 +8,8 @@ "format": "eslint . --fix" }, "dependencies": { - "@typescript-eslint/eslint-plugin": "^8.18.0", - "@typescript-eslint/parser": "^8.18.0", + "@typescript-eslint/eslint-plugin": "^8.18.2", + "@typescript-eslint/parser": "^8.18.2", "eslint-config-prettier": "^9.1.0", "eslint-config-turbo": "^2.3.3", "eslint-plugin-prettier": "^5.2.1", @@ -20,12 +20,10 @@ "prettier-plugin-svelte": "^3.3.2" }, "devDependencies": { - "@eslint/js": "^9.16.0", - "@types/eslint": "^9.6.1", - "@types/eslint__js": "^8.42.3", - "eslint": "^9.16.0", - "globals": "^15.13.0", + "@eslint/js": "^9.17.0", + "eslint": "^9.17.0", + "globals": "^15.14.0", "typescript": "^5.7.2", - "typescript-eslint": "^8.18.0" + "typescript-eslint": "^8.18.2" } } diff --git a/packages/database/package.json b/packages/database/package.json index b8c6448cb..83e757612 100644 --- a/packages/database/package.json +++ b/packages/database/package.json @@ -1,5 +1,5 @@ { - "name": "@cugetreg/database", + "name": "@repo/database", "version": "2.0.0", "private": true, "type": "module", @@ -21,7 +21,7 @@ "@types/cli-progress": "^3.11.6", "@types/node": "^22.10.2", "cli-progress": "^3.12.0", - "dotenv-cli": "^7.4.4", + "dotenv-cli": "^8.0.0", "drizzle-kit": "^0.30.0", "tsx": "^4.19.2", "typescript": "^5.7.2" diff --git a/packages/ui/package.json b/packages/ui/package.json index ca15644c5..23cefc519 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -14,24 +14,25 @@ }, "scripts": { "lint": "eslint .", - "format": "eslint . --fix" + "format": "eslint . --fix", + "postinstall": "node scripts/patch-sb-csf.js" }, "devDependencies": { "@repo/config": "workspace:^", - "@storybook/addon-svelte-csf": "^4.2.0", + "@storybook/addon-svelte-csf": "^5.0.0-next.21", "@storybook/svelte": "^8.4.7", - "@sveltejs/adapter-node": "^5.2.10", - "@sveltejs/kit": "^2.11.1", - "@sveltejs/vite-plugin-svelte": "^3.1.2", - "svelte": "^4.2.18", + "@sveltejs/adapter-node": "^5.2.11", + "@sveltejs/kit": "^2.15.0", + "@sveltejs/vite-plugin-svelte": "^5.0.3", + "svelte": "^5.15.0", "vitest": "^2.1.8" }, "dependencies": { "bits-ui": "^0.22.0", "clsx": "^2.1.1", - "lucide-svelte": "^0.468.0", - "tailwind-merge": "^2.5.5", + "lucide-svelte": "^0.469.0", + "tailwind-merge": "^2.6.0", "tailwind-variants": "^0.3.0", - "tailwindcss": "^3.4.16" + "tailwindcss": "^3.4.17" } } diff --git a/packages/ui/scripts/patch-sb-csf.js b/packages/ui/scripts/patch-sb-csf.js new file mode 100644 index 000000000..d6e3d3346 --- /dev/null +++ b/packages/ui/scripts/patch-sb-csf.js @@ -0,0 +1,94 @@ +/* eslint-disable no-undef */ + +import fs from 'node:fs/promises' + +const addonPath = './node_modules/@storybook/addon-svelte-csf' +const patchLocation = addonPath + '/package.json' + +const pkgJson = await fs.readFile(patchLocation, 'utf8') +const pkg = JSON.parse(pkgJson) + +if (!pkg.main || !pkg.types) { + console.log('Patching Storybook Svelte CSF package.json') + pkg.main = './dist/index.js' + pkg.types = './dist/index.d.ts' + await fs.writeFile(patchLocation, JSON.stringify(pkg, null, 2)) +} + +// ! Temporary Solution +// Patch broken import +// See: https://github.com/storybookjs/addon-svelte-csf/issues/252 + +const replacePatterns = { + "utils/identifier-utils'": "utils/identifier-utils.js'", + "from '@storybook/node-logger'": "from 'storybook/internal/node-logger'", + "/replace-argument'": "/replace-argument.js'", + "/define-meta'": "/define-meta.js'", + "/parser/ast'": "/parser/ast.js'", +} + +// Recursive all files in addonPath that match *.js +/** + * @param {string} file + */ +async function fixImport(file) { + let content = await fs.readFile(file, 'utf8') + let replaced = false + + for (const pattern in replacePatterns) { + if (content.includes(pattern)) { + replaced = true + + const lengthLimit = 70 - pattern.length + + console.log( + `Fixing pattern "${pattern}" in ${file.length > lengthLimit ? '...' + file.slice(-lengthLimit) : file}`, + ) + + content = content.replaceAll(pattern, replacePatterns[pattern]) + } + } + + if (replaced) { + await fs.writeFile(file, content) + } + + for (const line of content.split('\n')) { + if (line.startsWith('import')) { + const match = line.match(/from '(.*)'/) + + if (!match) { + continue + } + + const importPath = match[1] + if ( + importPath.startsWith('.') && + !(importPath.endsWith('.js') || importPath.endsWith('.svelte')) + ) { + console.log(`Warn: ${file}`) + console.log(`Invalid Import: ${importPath}`) + } + } + } +} + +/** + * @param {string} dir + */ +async function walkDir(dir) { + const files = await fs.readdir(dir) + + for (const file of files) { + // If is directory recursive + if ((await fs.stat(dir + '/' + file)).isDirectory()) { + await walkDir(dir + '/' + file) + } else { + if (file.endsWith('.js')) { + await fixImport(dir + '/' + file) + } + } + } +} + +await walkDir(addonPath) diff --git a/packages/ui/src/components/accordion/accordion-content.svelte b/packages/ui/src/components/accordion/accordion-content.svelte index 73ae7eb18..ee54b2c3c 100644 --- a/packages/ui/src/components/accordion/accordion-content.svelte +++ b/packages/ui/src/components/accordion/accordion-content.svelte @@ -1,26 +1,38 @@
- + {@render children?.()}
diff --git a/packages/ui/src/components/accordion/accordion-item.svelte b/packages/ui/src/components/accordion/accordion-item.svelte index 9babe2511..07131739e 100644 --- a/packages/ui/src/components/accordion/accordion-item.svelte +++ b/packages/ui/src/components/accordion/accordion-item.svelte @@ -1,15 +1,26 @@ - - + + {@render children?.()} diff --git a/packages/ui/src/components/accordion/accordion-trigger.svelte b/packages/ui/src/components/accordion/accordion-trigger.svelte index fdfada8df..8d5cec5e6 100644 --- a/packages/ui/src/components/accordion/accordion-trigger.svelte +++ b/packages/ui/src/components/accordion/accordion-trigger.svelte @@ -1,27 +1,38 @@ - + {@render children?.()} diff --git a/packages/ui/src/components/accordion/accordion.stories.svelte b/packages/ui/src/components/accordion/accordion.stories.svelte index 7b0cfcd4a..2d5f225bf 100644 --- a/packages/ui/src/components/accordion/accordion.stories.svelte +++ b/packages/ui/src/components/accordion/accordion.stories.svelte @@ -1,9 +1,9 @@ - - - diff --git a/packages/ui/src/components/accordion/index.ts b/packages/ui/src/components/accordion/index.ts index b098bfe1a..ed12f3835 100644 --- a/packages/ui/src/components/accordion/index.ts +++ b/packages/ui/src/components/accordion/index.ts @@ -3,6 +3,7 @@ import { Accordion as AccordionPrimitive } from 'bits-ui' import Content from './accordion-content.svelte' import Item from './accordion-item.svelte' import Trigger from './accordion-trigger.svelte' + const Root = AccordionPrimitive.Root export { diff --git a/packages/ui/src/components/button/button.stories.svelte b/packages/ui/src/components/button/button.stories.svelte index bfb652849..c40d34ba1 100644 --- a/packages/ui/src/components/button/button.stories.svelte +++ b/packages/ui/src/components/button/button.stories.svelte @@ -1,9 +1,9 @@ - - - - - - - + args={{ variant: 'solid', size: 'default', color: 'primary' }} +> + {#snippet children(args)} + + {/snippet} + + args={{ variant: 'outlined', size: 'default', color: 'primary' }} +> + {#snippet children(args)} + + {/snippet} + + args={{ variant: 'solid', size: 'default', color: 'neutral' }} +> + {#snippet children(args)} + + {/snippet} + + args={{ variant: 'outlined', size: 'default', color: 'neutral' }} +> + {#snippet children(args)} + + {/snippet} + + args={{ variant: 'solid', size: 'default', color: 'error' }} +> + {#snippet children(args)} + + {/snippet} + + args={{ variant: 'outlined', size: 'default', color: 'error' }} +> + {#snippet children(args)} + + {/snippet} + + args={{ variant: 'solid', size: 'default', color: 'secondary' }} +> + {#snippet children(args)} + + {/snippet} + + args={{ variant: 'outlined', size: 'default', color: 'secondary' }} +> + {#snippet children(args)} + + {/snippet} + diff --git a/packages/ui/src/components/button/button.svelte b/packages/ui/src/components/button/button.svelte index a3cc991ea..06a8afe2d 100644 --- a/packages/ui/src/components/button/button.svelte +++ b/packages/ui/src/components/button/button.svelte @@ -1,5 +1,6 @@ - + {@render children?.()} diff --git a/packages/ui/src/components/checkbox/checkbox.stories.svelte b/packages/ui/src/components/checkbox/checkbox.stories.svelte index c5a8df143..aae0f7c65 100644 --- a/packages/ui/src/components/checkbox/checkbox.stories.svelte +++ b/packages/ui/src/components/checkbox/checkbox.stories.svelte @@ -1,9 +1,9 @@ - - - - - - - + diff --git a/packages/ui/src/components/checkbox/checkbox.svelte b/packages/ui/src/components/checkbox/checkbox.svelte index 425acb0be..5cdb2d1fb 100644 --- a/packages/ui/src/components/checkbox/checkbox.svelte +++ b/packages/ui/src/components/checkbox/checkbox.svelte @@ -1,6 +1,6 @@
- {#if isChecked} - - {/if} + {#snippet children({ isChecked })} + {#if isChecked} + + {/if} + {/snippet} {#if label} diff --git a/packages/ui/src/components/chip/chip.stories.svelte b/packages/ui/src/components/chip/chip.stories.svelte index 4a242cc5b..2598a5324 100644 --- a/packages/ui/src/components/chip/chip.stories.svelte +++ b/packages/ui/src/components/chip/chip.stories.svelte @@ -1,9 +1,9 @@ - - - - - - - - - - + + {#snippet children(args)} + Chip + {/snippet} + + + + {#snippet children(args)} + Chip + {/snippet} + diff --git a/packages/ui/src/components/chip/chip.svelte b/packages/ui/src/components/chip/chip.svelte index a6bb65b71..58b5f98c7 100644 --- a/packages/ui/src/components/chip/chip.svelte +++ b/packages/ui/src/components/chip/chip.svelte @@ -1,20 +1,32 @@ - - + + {@render children?.()} {#if closable} - {/if} diff --git a/packages/ui/src/components/course-card/course-card.stories.svelte b/packages/ui/src/components/course-card/course-card.stories.svelte index e4e90766d..bb98df617 100644 --- a/packages/ui/src/components/course-card/course-card.stories.svelte +++ b/packages/ui/src/components/course-card/course-card.stories.svelte @@ -1,9 +1,9 @@ - - - - - - + - + diff --git a/packages/ui/src/components/course-card/course-card.svelte b/packages/ui/src/components/course-card/course-card.svelte index 534f8ecac..746a94773 100644 --- a/packages/ui/src/components/course-card/course-card.svelte +++ b/packages/ui/src/components/course-card/course-card.svelte @@ -8,22 +8,30 @@ import { RecommendedTag } from '../recommended-tag' import type { Course } from './index' - let className: string | undefined | null = undefined - export { className as class } - - export let course: Course = { - code: '0123101', - name: 'PARAGRAPH WRITING', - credit: 3, - gened: ['HU'], - seat: 24, - maxseat: 305, - review: 14, - days: ['MO', 'TU', 'WE'], + interface Props { + class?: string | undefined | null + course?: Course + selected?: boolean + recommended?: boolean + [key: string]: unknown } - export let selected: boolean = false - export let recommended: boolean = false + let { + class: className = undefined, + course = { + code: '0123101', + name: 'PARAGRAPH WRITING', + credit: 3, + gened: ['HU'], + seat: 24, + maxseat: 305, + review: 14, + days: ['MO', 'TU', 'WE'], + }, + selected = $bindable(false), + recommended = false, + ...rest + }: Props = $props() export const onButtonClick = () => { selected = !selected @@ -31,11 +39,11 @@
{#if recommended} @@ -49,7 +57,7 @@
{#each course.gened as gened} - + {/each}
@@ -74,13 +82,14 @@ variant="outlined" color="neutral" class="w-36 h-7 md:w-48 md:h-9 text-caption md:text-body2" - >เลือกเซคชัน + เลือกเซคชัน + {#if !selected}