From ffa6b84da3a4053ab4ec90b7b8652b4325578b0b Mon Sep 17 00:00:00 2001 From: liyunze <50455574+liyunze-coding@users.noreply.github.com> Date: Sun, 30 Aug 2026 18:50:25 +0800 Subject: [PATCH] added formatter --- .github/workflows/deploy.yml | 46 +- .oxfmtrc.json | 8 + .vscode/extensions.json | 5 +- README.md | 20 +- docker-compose.yml | 18 +- package-lock.json | 416 +++++++++++++++++- package.json | 7 +- src/app.d.ts | 10 +- src/lib/api.ts | 24 +- src/lib/components/FeedRow.svelte | 14 +- src/lib/components/Navbar.svelte | 148 ++++--- src/lib/components/VoteStack.svelte | 40 +- src/lib/server/api.ts | 558 ++++++++++++++----------- src/lib/server/db.ts | 202 +++++---- src/lib/stores/auth.spec.ts | 10 +- src/lib/stores/auth.ts | 74 ++-- src/lib/time.ts | 2 +- src/lib/types.ts | 78 ++-- src/routes/+layout.svelte | 55 +-- src/routes/+page.svelte | 87 ++-- src/routes/api/+server.ts | 40 +- src/routes/auth/login/+page.svelte | 125 +++--- src/routes/layout.css | 22 +- src/routes/notes/+page.svelte | 180 ++++---- src/routes/notes/[id]/+page.svelte | 322 +++++++------- src/routes/post/note/+page.svelte | 312 +++++++------- src/routes/post/question/+page.svelte | 310 +++++++------- src/routes/questions/+page.svelte | 188 +++++---- src/routes/questions/[id]/+page.svelte | 318 +++++++------- src/routes/search/+page.svelte | 106 ++--- src/routes/topics/[slug]/+page.svelte | 150 +++---- src/routes/units/[code]/+page.svelte | 156 +++---- vite.config.ts | 47 ++- 33 files changed, 2398 insertions(+), 1700 deletions(-) create mode 100644 .oxfmtrc.json diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index a7ded66..4d2790a 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -1,31 +1,31 @@ name: Deploy to VPS on: - push: - branches: [main] - workflow_dispatch: + push: + branches: [main] + workflow_dispatch: jobs: - deploy: - runs-on: self-hosted - steps: - - name: Checkout - uses: actions/checkout@v4 + deploy: + runs-on: self-hosted + steps: + - name: Checkout + uses: actions/checkout@v4 - - name: Build and start containers - run: docker compose up -d --build --remove-orphans + - name: Build and start containers + run: docker compose up -d --build --remove-orphans - - name: Prune dangling images - run: docker image prune -f + - name: Prune dangling images + run: docker image prune -f - - name: Health check - run: | - for i in $(seq 1 30); do - if curl -fsS http://localhost:4073 > /dev/null; then - echo "App is up" - exit 0 - fi - sleep 2 - done - echo "App did not become healthy" >&2 - exit 1 + - name: Health check + run: | + for i in $(seq 1 30); do + if curl -fsS http://localhost:4073 > /dev/null; then + echo "App is up" + exit 0 + fi + sleep 2 + done + echo "App did not become healthy" >&2 + exit 1 diff --git a/.oxfmtrc.json b/.oxfmtrc.json new file mode 100644 index 0000000..cbdaffd --- /dev/null +++ b/.oxfmtrc.json @@ -0,0 +1,8 @@ +{ + "$schema": "./node_modules/oxfmt/configuration_schema.json", + "ignorePatterns": [], + "sortTailwindcss": true, + "useTabs": true, + "tabWidth": 4, + "svelte": true +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 5449017..42ca69c 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -1,6 +1,3 @@ { - "recommendations": [ - "svelte.svelte-vscode", - "bradlc.vscode-tailwindcss" - ] + "recommendations": ["svelte.svelte-vscode", "bradlc.vscode-tailwindcss"] } diff --git a/README.md b/README.md index 554c24f..d108682 100644 --- a/README.md +++ b/README.md @@ -33,23 +33,23 @@ A centralised resource hub for Deakin University students studying **SIT** (IT, 1. Clone the repository and install dependencies: - ```sh - npm install - ``` + ```sh + npm install + ``` 2. Configure environment variables (optional): - ```sh - cp .env .env.local - ``` + ```sh + cp .env .env.local + ``` - The only variable is `DATABASE_PATH`, which defaults to `data/dsec.db`. + The only variable is `DATABASE_PATH`, which defaults to `data/dsec.db`. 3. Start the development server: - ```sh - npm run dev - ``` + ```sh + npm run dev + ``` 4. Open the URL printed in the terminal (usually `http://localhost:5173`). diff --git a/docker-compose.yml b/docker-compose.yml index a47f8c4..f559f79 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,12 +1,12 @@ services: - app: - build: . - ports: - - "4073:3000" - environment: - DATABASE_PATH: data/dsec.db - volumes: - - dsec-data:/app/data + app: + build: . + ports: + - "4073:3000" + environment: + DATABASE_PATH: data/dsec.db + volumes: + - dsec-data:/app/data volumes: - dsec-data: + dsec-data: diff --git a/package-lock.json b/package-lock.json index fa7f710..9a5a952 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@tailwindcss/vite": "^4.3.0", "@types/node": "^26.3.0", "@vitest/browser-playwright": "^4.1.8", + "oxfmt": "^0.65.0", "playwright": "^1.60.0", "svelte": "^5.56.1", "svelte-check": "^4.6.0", @@ -111,6 +112,353 @@ "url": "https://github.com/sponsors/Boshen" } }, + "node_modules/@oxfmt/binding-android-arm-eabi": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm-eabi/-/binding-android-arm-eabi-0.65.0.tgz", + "integrity": "sha512-M10Gs1SSpTNI6ahGx3M/OlIdUF4hkaP6OgUb+MS79t/Pgflk3r1nW5gPFqsZGUAXg0H1AfANT9AvLdBSTIhZKg==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-android-arm64": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-android-arm64/-/binding-android-arm64-0.65.0.tgz", + "integrity": "sha512-6DXH5sftNlaHpWJG50hFMF+Qxtq5D2TmahvcDPxWNcGIf8qrC9Y0YgHYcYZ2hlWzaccKXh/f3GcssH8vtkl4JA==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "android" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-darwin-arm64": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-arm64/-/binding-darwin-arm64-0.65.0.tgz", + "integrity": "sha512-K9m7lr53pcOLETNsC88sWes/GWHUGjZyHx95UhYcSXy0r30haLdeXlSufSenEAtoLaW753WN8/l4M7GYcRt6cg==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-darwin-x64": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-darwin-x64/-/binding-darwin-x64-0.65.0.tgz", + "integrity": "sha512-sTNwIx1gre3MyiHOPLu7IGW4UyMScYL4DTmJT01p4vzB0En+OJUQz6KuH8t0PpsClRSaMuY3b0QmtoPItfO8Lg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-freebsd-x64": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-freebsd-x64/-/binding-freebsd-x64-0.65.0.tgz", + "integrity": "sha512-lYZMVIiIpnjGu5hJb2jxA8NYQ/e0OTGuaiAf4dqlGPNnPmUTu23FZRMltmjro/KkQm1uE4NT4n5yJ2zWmKcpfA==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "freebsd" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-linux-arm-gnueabihf": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-gnueabihf/-/binding-linux-arm-gnueabihf-0.65.0.tgz", + "integrity": "sha512-gIdXFAt/bURnjxuoedDEWdZ0PEWEmdDcm8qdpoFYYvW3QMk/5D4vUaH4mlMeRpeTdST4izUgHVO6RawQ4QulJw==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-linux-arm-musleabihf": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm-musleabihf/-/binding-linux-arm-musleabihf-0.65.0.tgz", + "integrity": "sha512-jJVyADto7gA2AaX5qAjAexrxx9PJQaKWOe8PICE7yKMbjBRyOHcmj9TtVJ+MZYDUQ3hodU0AcoTj0jFQ1W4C6Q==", + "cpu": [ + "arm" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-linux-arm64-gnu": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-gnu/-/binding-linux-arm64-gnu-0.65.0.tgz", + "integrity": "sha512-p3RFkB+u7u+8up99b/NEcI1hdpLDiGgJYNwDorB60n7eH+eKposAKuMBxx+NqB3b+sJP4CZmYDh9G7X62tUsKg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-linux-arm64-musl": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-arm64-musl/-/binding-linux-arm64-musl-0.65.0.tgz", + "integrity": "sha512-5Prb0uFzJHr+OUD/qS/TmU526wD+PaHDsm3KoRiUXbMIDpTSErjeQYkK3OQeshAvD/PuLa9WGEi9WPajjdOZJg==", + "cpu": [ + "arm64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-linux-ppc64-gnu": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-ppc64-gnu/-/binding-linux-ppc64-gnu-0.65.0.tgz", + "integrity": "sha512-S8svxTp81obnF3admN9yd+u2rOYXtyzThLGBTg1PY6TPtGcC09BaaXLQD+TBSMa7yvqhCDZ8DFri+S/yG60qCg==", + "cpu": [ + "ppc64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-linux-riscv64-gnu": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-gnu/-/binding-linux-riscv64-gnu-0.65.0.tgz", + "integrity": "sha512-WtXBr75G/h2qOHy8SiGtC1R6aS3jt4mE52v1D8AtwMXIgoOmSNP9lKvbSaTRoL0e5wsMPoi6T72QWDYPu+S+nA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-linux-riscv64-musl": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-riscv64-musl/-/binding-linux-riscv64-musl-0.65.0.tgz", + "integrity": "sha512-YwSLVvpaz4o/nv/miiPEBJz+eJ+VmbgNIrao6RccK9ce+L5EA8wP+ZD0uFeq6wKOza6zoWv/dR0sj6lip6R3EA==", + "cpu": [ + "riscv64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-linux-s390x-gnu": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-s390x-gnu/-/binding-linux-s390x-gnu-0.65.0.tgz", + "integrity": "sha512-XQTPqgvyrgkKcFq+Tp2eK6JS7sqqJ+nRmy2Fav4j3I+i4dJoPJm7YwEdoeSDX9xkqj9jZ/lWfF3bXUWztIrn6A==", + "cpu": [ + "s390x" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-linux-x64-gnu": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-gnu/-/binding-linux-x64-gnu-0.65.0.tgz", + "integrity": "sha512-cjZlx6S/VkeCNWCbwZriTnLnZeTcV3DEyeRGSw/2wwLP9viq+C0bJ4bC1k/ZLkFxDcB1lUgSasPkYGP1bdraOg==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "glibc" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-linux-x64-musl": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-linux-x64-musl/-/binding-linux-x64-musl-0.65.0.tgz", + "integrity": "sha512-2azCjxdLtK4zCcIOU1dlXlU0xxfbPi6EjwWx7Ac7teWPidIIDOcIhudup83xNCKYhtqeVd/gaVDOxbUq4syXWA==", + "cpu": [ + "x64" + ], + "dev": true, + "libc": [ + "musl" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-openharmony-arm64": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-openharmony-arm64/-/binding-openharmony-arm64-0.65.0.tgz", + "integrity": "sha512-KXQ7xi1e/voP0IQaw6fG6XY4Z5+Llf1XmRSZS1t7pVFCecFJ0iXaboKmVwjFtp5MLlT5iWQrJ2U1C3GJdZ2u+Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "openharmony" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-win32-arm64-msvc": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-arm64-msvc/-/binding-win32-arm64-msvc-0.65.0.tgz", + "integrity": "sha512-2FbbjG5jEqLSLKVJwBap84uJfpn5Y5A53KEO0aUNr+zeiRB9nyPUIFMcSbZVMFLitfBytFWRNngozXYjb6Rsbw==", + "cpu": [ + "arm64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-win32-ia32-msvc": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-ia32-msvc/-/binding-win32-ia32-msvc-0.65.0.tgz", + "integrity": "sha512-LJ+ZacAPSjegDOnSLyA1TMWAhdDrsK4el3REdr1oL2UtVBCMhO2II/Sb3cEW6mF2MfLhl8hDNCSvc7KSbgk3LQ==", + "cpu": [ + "ia32" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, + "node_modules/@oxfmt/binding-win32-x64-msvc": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/@oxfmt/binding-win32-x64-msvc/-/binding-win32-x64-msvc-0.65.0.tgz", + "integrity": "sha512-higu9cWEO6XXFzATD1jf0mCK34rNfN2H9JrJie7QB1IhleVpTh0QlLH9Ip2C1H/Nd5n0v5pvRtC+5R0uE4HpVg==", + "cpu": [ + "x64" + ], + "dev": true, + "license": "MIT", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^20.19.0 || >=22.12.0" + } + }, "node_modules/@polka/url": { "version": "1.0.0-next.29", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", @@ -929,9 +1277,9 @@ } }, "node_modules/@sveltejs/kit": { - "version": "2.70.2", - "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.70.2.tgz", - "integrity": "sha512-RzRoRpuR2KXqc5yMO0akQHDZeT4AslOlznGITURsqHaVbtyYP4Wn3eE3gxj9JcDyNYO0crkxhdwFHc+2vkVm6w==", + "version": "2.70.3", + "resolved": "https://registry.npmjs.org/@sveltejs/kit/-/kit-2.70.3.tgz", + "integrity": "sha512-UDvEYuZqAMbfB/oXIoqKvbKcb7YczK5zYrzmsGV1zRJk03jntwp8dXiYoIJotxAndsKvcPFtx9H1GRSKFdSHgg==", "dev": true, "license": "MIT", "dependencies": { @@ -2164,6 +2512,58 @@ "node": ">=12.20.0" } }, + "node_modules/oxfmt": { + "version": "0.65.0", + "resolved": "https://registry.npmjs.org/oxfmt/-/oxfmt-0.65.0.tgz", + "integrity": "sha512-SgS5VgnP42T0zl3zWD+xoH8FCqg1SAFnSRoOT/qeoa6gxcYIqrDMOmcXIg/EWSN92Du4ogB4riuKhKd6Y4CGhw==", + "dev": true, + "license": "MIT", + "dependencies": { + "tinypool": "2.1.0" + }, + "bin": { + "oxfmt": "bin/oxfmt" + }, + "engines": { + "node": "^20.19.0 || >=22.12.0" + }, + "funding": { + "url": "https://github.com/sponsors/Boshen" + }, + "optionalDependencies": { + "@oxfmt/binding-android-arm-eabi": "0.65.0", + "@oxfmt/binding-android-arm64": "0.65.0", + "@oxfmt/binding-darwin-arm64": "0.65.0", + "@oxfmt/binding-darwin-x64": "0.65.0", + "@oxfmt/binding-freebsd-x64": "0.65.0", + "@oxfmt/binding-linux-arm-gnueabihf": "0.65.0", + "@oxfmt/binding-linux-arm-musleabihf": "0.65.0", + "@oxfmt/binding-linux-arm64-gnu": "0.65.0", + "@oxfmt/binding-linux-arm64-musl": "0.65.0", + "@oxfmt/binding-linux-ppc64-gnu": "0.65.0", + "@oxfmt/binding-linux-riscv64-gnu": "0.65.0", + "@oxfmt/binding-linux-riscv64-musl": "0.65.0", + "@oxfmt/binding-linux-s390x-gnu": "0.65.0", + "@oxfmt/binding-linux-x64-gnu": "0.65.0", + "@oxfmt/binding-linux-x64-musl": "0.65.0", + "@oxfmt/binding-openharmony-arm64": "0.65.0", + "@oxfmt/binding-win32-arm64-msvc": "0.65.0", + "@oxfmt/binding-win32-ia32-msvc": "0.65.0", + "@oxfmt/binding-win32-x64-msvc": "0.65.0" + }, + "peerDependencies": { + "svelte": "^5.0.0", + "vite-plus": "*" + }, + "peerDependenciesMeta": { + "svelte": { + "optional": true + }, + "vite-plus": { + "optional": true + } + } + }, "node_modules/path-parse": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", @@ -2571,6 +2971,16 @@ "url": "https://github.com/sponsors/SuperchupuDev" } }, + "node_modules/tinypool": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-2.1.0.tgz", + "integrity": "sha512-Pugqs6M0m7Lv1I7FtxN4aoyToKg1C4tu+/381vH35y8oENM/Ai7f7C4StcoK4/+BSw9ebcS8jRiVrORFKCALLw==", + "dev": true, + "license": "MIT", + "engines": { + "node": "^20.0.0 || >=22.0.0" + } + }, "node_modules/tinyrainbow": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-3.1.1.tgz", diff --git a/package.json b/package.json index 252ff3d..e7ddf12 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "dsec-notebook", - "private": true, "version": "0.0.1", + "private": true, "type": "module", "scripts": { "dev": "vite dev", @@ -11,7 +11,9 @@ "check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json", "check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch", "test:unit": "vitest", - "test": "npm run test:unit -- --run" + "test": "npm run test:unit -- --run", + "fmt": "oxfmt", + "fmt:check": "oxfmt --check" }, "devDependencies": { "@sveltejs/adapter-node": "^5.5.7", @@ -20,6 +22,7 @@ "@tailwindcss/vite": "^4.3.0", "@types/node": "^26.3.0", "@vitest/browser-playwright": "^4.1.8", + "oxfmt": "^0.65.0", "playwright": "^1.60.0", "svelte": "^5.56.1", "svelte-check": "^4.6.0", diff --git a/src/app.d.ts b/src/app.d.ts index fb9cb50..d905397 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -1,9 +1,9 @@ export {}; declare global { - namespace App { - interface PageData {} - interface PageState {} - interface Platform {} - } + namespace App { + interface PageData {} + interface PageState {} + interface Platform {} + } } diff --git a/src/lib/api.ts b/src/lib/api.ts index 0c8d8dc..d66803d 100644 --- a/src/lib/api.ts +++ b/src/lib/api.ts @@ -1,21 +1,21 @@ async function call(name: string, args: Record = {}): Promise { - const res = await fetch('/api', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ fn: name, args }) - }); + const res = await fetch("/api", { + method: "POST", + headers: { "Content-Type": "application/json" }, + body: JSON.stringify({ fn: name, args }), + }); - const data = await res.json(); - if (!data.ok) { - throw new Error(data.error ?? 'Request failed'); - } - return data.result; + const data = await res.json(); + if (!data.ok) { + throw new Error(data.error ?? "Request failed"); + } + return data.result; } export function query(name: string, args: Record = {}): Promise { - return call(name, args); + return call(name, args); } export function mutation(name: string, args: Record = {}): Promise { - return call(name, args); + return call(name, args); } diff --git a/src/lib/components/FeedRow.svelte b/src/lib/components/FeedRow.svelte index fb45d15..eae022e 100644 --- a/src/lib/components/FeedRow.svelte +++ b/src/lib/components/FeedRow.svelte @@ -1,5 +1,5 @@ -
+
- + {#if unitCode}

{unitCode}

{/if} -

+

{title}

{meta}

diff --git a/src/lib/components/Navbar.svelte b/src/lib/components/Navbar.svelte index aa29e4a..6c88f0f 100644 --- a/src/lib/components/Navbar.svelte +++ b/src/lib/components/Navbar.svelte @@ -1,76 +1,92 @@ -
-
- Notebook +
+
+ Notebook - + - -
+ +
- {#if mobileMenuOpen} - - {/if} + {#if mobileMenuOpen} + + {/if}
diff --git a/src/lib/components/VoteStack.svelte b/src/lib/components/VoteStack.svelte index 8c16084..c221e59 100644 --- a/src/lib/components/VoteStack.svelte +++ b/src/lib/components/VoteStack.svelte @@ -1,15 +1,15 @@ - - - + + +
- -
- {@render children()} -
-
-
-
-

Notebook — written by students, for students.

-

- DSEC Notebook is a community resource for Deakin University students. Not affiliated with Deakin University. -

-
- Search -
-
+ +
+ {@render children()} +
+
+
+
+

Notebook — written by students, for students.

+

+ DSEC Notebook is a community resource for Deakin University students. Not + affiliated with Deakin University. +

+
+ Search +
+
diff --git a/src/routes/+page.svelte b/src/routes/+page.svelte index b35bd7b..cace8bd 100644 --- a/src/routes/+page.svelte +++ b/src/routes/+page.svelte @@ -1,52 +1,57 @@ - Notebook — written by students + Notebook — written by students
-
-

Written by students

-

- One notebook for every unit, every topic. -

-

- Post notes in markdown, ask questions, and browse by unit. A shared notebook for Deakin students studying IT, computer science, and cybersecurity. -

- -
+
+

Written by students

+

+ One notebook for every unit, every topic. +

+

+ Post notes in markdown, ask questions, and browse by unit. A shared notebook for Deakin + students studying IT, computer science, and cybersecurity. +

+ +
-
-

Units

- {#if loading} -

Loading

- {:else} -
- {#each units as unit} - - {unit.code} - {unit.name} - - {/each} -
- {/if} -
+
+

Units

+ {#if loading} +

Loading

+ {:else} +
+ {#each units as unit} + + {unit.code} + {unit.name} + + {/each} +
+ {/if} +
diff --git a/src/routes/api/+server.ts b/src/routes/api/+server.ts index 565dc0a..16ed0e2 100644 --- a/src/routes/api/+server.ts +++ b/src/routes/api/+server.ts @@ -1,25 +1,25 @@ -import { json } from '@sveltejs/kit'; -import type { RequestHandler } from './$types'; -import { call } from '$lib/server/api'; +import { json } from "@sveltejs/kit"; +import type { RequestHandler } from "./$types"; +import { call } from "$lib/server/api"; export const POST: RequestHandler = async ({ request }) => { - let fn: string; - let args: Record; + let fn: string; + let args: Record; - try { - const body = await request.json(); - fn = String(body?.fn ?? ''); - args = (body?.args ?? {}) as Record; - } catch { - return json({ ok: false, error: 'Invalid request body' }, { status: 400 }); - } + try { + const body = await request.json(); + fn = String(body?.fn ?? ""); + args = (body?.args ?? {}) as Record; + } catch { + return json({ ok: false, error: "Invalid request body" }, { status: 400 }); + } - try { - const result = call(fn, args as Record); - return json({ ok: true, result }); - } catch (err: any) { - const message = err?.message ?? 'Internal error'; - const status = message === 'Not authenticated' || message === 'Not authorized' ? 401 : 400; - return json({ ok: false, error: message }, { status }); - } + try { + const result = call(fn, args as Record); + return json({ ok: true, result }); + } catch (err: any) { + const message = err?.message ?? "Internal error"; + const status = message === "Not authenticated" || message === "Not authorized" ? 401 : 400; + return json({ ok: false, error: message }, { status }); + } }; diff --git a/src/routes/auth/login/+page.svelte b/src/routes/auth/login/+page.svelte index a657b18..caa0462 100644 --- a/src/routes/auth/login/+page.svelte +++ b/src/routes/auth/login/+page.svelte @@ -1,76 +1,85 @@ - Sign in — Notebook + Sign in — Notebook
-
-

Account

-

Sign in

-

Use your Deakin email to contribute.

+
+

Account

+

Sign in

+

Use your Deakin email to contribute.

-
-
- - -
+ +
+ + +
-
- - -

Must be an @deakin.edu.au address

-
+
+ + +

Must be an @deakin.edu.au address

+
- {#if error} -

{error}

- {/if} + {#if error} +

{error}

+ {/if} - + -

By signing in, you agree that your contributions are public.

-
-
+

+ By signing in, you agree that your contributions are public. +

+ +
diff --git a/src/routes/layout.css b/src/routes/layout.css index 2acb1bb..ea4d0b8 100644 --- a/src/routes/layout.css +++ b/src/routes/layout.css @@ -1,8 +1,8 @@ -@import 'tailwindcss'; +@import "tailwindcss"; @theme { - --font-sans: 'Inter', ui-sans-serif, system-ui, sans-serif; - --font-serif: 'EB Garamond', 'Iowan Old Style', Palatino, Georgia, serif; + --font-sans: "Inter", ui-sans-serif, system-ui, sans-serif; + --font-serif: "EB Garamond", "Iowan Old Style", Palatino, Georgia, serif; --color-primary: #ea4c65; --color-primary-dark: #d43d56; --color-secondary: #00bcd4; @@ -25,35 +25,35 @@ html { } .kicker { - @apply font-sans text-[11px] font-medium uppercase tracking-[0.18em] text-faint; + @apply text-faint font-sans text-[11px] font-medium tracking-[0.18em] uppercase; } .btn-primary { - @apply inline-flex items-center justify-center rounded-none border border-primary bg-primary px-5 py-2.5 text-[11px] font-medium uppercase tracking-[0.14em] text-white transition-colors hover:bg-primary-dark hover:border-primary-dark disabled:cursor-not-allowed disabled:opacity-50; + @apply border-primary bg-primary hover:bg-primary-dark hover:border-primary-dark inline-flex items-center justify-center rounded-none border px-5 py-2.5 text-[11px] font-medium tracking-[0.14em] text-white uppercase transition-colors disabled:cursor-not-allowed disabled:opacity-50; } .btn-secondary { - @apply inline-flex items-center justify-center rounded-none border border-secondary bg-transparent px-5 py-2.5 text-[11px] font-medium uppercase tracking-[0.14em] text-secondary transition-colors hover:bg-secondary hover:text-white disabled:cursor-not-allowed disabled:opacity-50; + @apply border-secondary text-secondary hover:bg-secondary inline-flex items-center justify-center rounded-none border bg-transparent px-5 py-2.5 text-[11px] font-medium tracking-[0.14em] uppercase transition-colors hover:text-white disabled:cursor-not-allowed disabled:opacity-50; } .btn-ghost { - @apply inline-flex items-center justify-center rounded-none border border-ink bg-transparent px-5 py-2.5 text-[11px] font-medium uppercase tracking-[0.14em] text-ink transition-colors hover:border-primary hover:text-primary; + @apply border-ink text-ink hover:border-primary hover:text-primary inline-flex items-center justify-center rounded-none border bg-transparent px-5 py-2.5 text-[11px] font-medium tracking-[0.14em] uppercase transition-colors; } .field { - @apply block w-full rounded-none border border-rule bg-white px-3 py-2.5 text-sm text-ink outline-none transition-colors placeholder:text-faint focus:border-primary; + @apply border-rule text-ink placeholder:text-faint focus:border-primary block w-full rounded-none border bg-white px-3 py-2.5 text-sm transition-colors outline-none; } .chip { - @apply inline-flex items-center rounded-none border border-rule bg-white px-3 py-1.5 font-sans text-[11px] font-medium uppercase tracking-[0.12em] text-ink transition-colors hover:border-ink; + @apply border-rule text-ink hover:border-ink inline-flex items-center rounded-none border bg-white px-3 py-1.5 font-sans text-[11px] font-medium tracking-[0.12em] uppercase transition-colors; } .chip-active { - @apply border-primary bg-primary text-white hover:border-primary-dark hover:bg-primary-dark; + @apply border-primary bg-primary hover:border-primary-dark hover:bg-primary-dark text-white; } .nav-link { - @apply text-[11px] font-medium uppercase tracking-[0.2em] text-muted transition-colors hover:text-primary; + @apply text-muted hover:text-primary text-[11px] font-medium tracking-[0.2em] uppercase transition-colors; } .nav-link-active { diff --git a/src/routes/notes/+page.svelte b/src/routes/notes/+page.svelte index a18e811..50b7d39 100644 --- a/src/routes/notes/+page.svelte +++ b/src/routes/notes/+page.svelte @@ -1,101 +1,107 @@ - Notes — Notebook + Notes — Notebook
-
-

Notes

- Post a note -
+
+

Notes

+ Post a note +
-
-
- - {#each usedUnits as unit} - - {/each} -
-
- - -
-
+
+
+ + {#each usedUnits as unit} + + {/each} +
+
+ + +
+
- {#if loading} -

Loading

- {:else} - {#each visible as note} - - {:else} -
-

No notes yet.

- Post a note -
- {/each} - {/if} + {#if loading} +

Loading

+ {:else} + {#each visible as note} + + {:else} +
+

No notes yet.

+ Post a note +
+ {/each} + {/if}
diff --git a/src/routes/notes/[id]/+page.svelte b/src/routes/notes/[id]/+page.svelte index 0dba62f..90dafc6 100644 --- a/src/routes/notes/[id]/+page.svelte +++ b/src/routes/notes/[id]/+page.svelte @@ -1,169 +1,191 @@ - {note?.title ?? 'Loading...'} — Notebook + {note?.title ?? "Loading..."} — Notebook
- {#if loading} -

Loading

- {:else if note} -
- -
-

- {#if unit}{unit.code}{/if}{#if unit && topic} · {/if}{#if topic}{topic.name}{/if} -

-

{note.title}

-

- {note.authorName} · {timeAgo(note.createdAt)} - {#if isAuthor} - · - - {/if} -

-
-
+ {#if loading} +

Loading

+ {:else if note} +
+ +
+

+ {#if unit}{unit.code}{/if}{#if unit && topic} + · + {/if}{#if topic}{topic.name}{/if} +

+

+ {note.title} +

+

+ {note.authorName} · {timeAgo(note.createdAt)} + {#if isAuthor} + · + + {/if} +

+
+
-
- {note.content} -
+
+ {note.content} +
-
-

Comments ({comments.length})

+
+

Comments ({comments.length})

- {#if get(isAuthenticated)} -
- -
- {commentError} - -
-
- {:else} -

- Sign in to leave a comment. -

- {/if} + {#if get(isAuthenticated)} +
+ +
+ {commentError} + +
+
+ {:else} +

+ Sign in to leave a comment. +

+ {/if} -
- {#each comments as comment} -
-

{comment.authorName} · {timeAgo(comment.createdAt)}

-

{comment.content}

- {#if get(currentUser)?._id === comment.authorId} - - {/if} -
- {:else} -

No comments yet.

- {/each} -
-
- {:else} -

Note not found

-

This note may have been deleted or doesn't exist.

- Back to notes - {/if} +
+ {#each comments as comment} +
+

{comment.authorName} · {timeAgo(comment.createdAt)}

+

+ {comment.content} +

+ {#if get(currentUser)?._id === comment.authorId} + + {/if} +
+ {:else} +

No comments yet.

+ {/each} +
+
+ {:else} +

Note not found

+

This note may have been deleted or doesn't exist.

+ Back to notes + {/if}
diff --git a/src/routes/post/note/+page.svelte b/src/routes/post/note/+page.svelte index 6812613..b704ad6 100644 --- a/src/routes/post/note/+page.svelte +++ b/src/routes/post/note/+page.svelte @@ -1,179 +1,185 @@ - Post a note — Notebook + Post a note — Notebook
-

Post a note

-

- Share study notes with the Deakin community. Focus on a specific topic, not an entire unit. -

+

Post a note

+

+ Share study notes with the Deakin community. Focus on a specific topic, not an entire unit. +

- {#if success} -

{success}

- {/if} + {#if success} +

{success}

+ {/if} -
-
- - -
+ +
+ + +
-
- - -
+
+ + +
-
-
- - -
+
+
+ + +
-
- - {#if !useCustomUnit} - - {/if} +
+ + {#if !useCustomUnit} + + {/if} - + - {#if useCustomUnit} - - {/if} -
-
+ {#if useCustomUnit} + + {/if} +
+
- {#if error} -

{error}

- {/if} + {#if error} +

{error}

+ {/if} - -
+ +
diff --git a/src/routes/post/question/+page.svelte b/src/routes/post/question/+page.svelte index 2480705..54dd500 100644 --- a/src/routes/post/question/+page.svelte +++ b/src/routes/post/question/+page.svelte @@ -1,177 +1,185 @@ - Ask a question — Notebook + Ask a question — Notebook
-

Ask a question

-

Stuck on something? Ask the Deakin community for help.

+

Ask a question

+

+ Stuck on something? Ask the Deakin community for help. +

- {#if success} -

{success}

- {/if} + {#if success} +

{success}

+ {/if} -
-
- - -
+ +
+ + +
-
- - -
+
+ + +
-
-
- - -
+
+
+ + +
-
- - {#if !useCustomUnit} - - {/if} +
+ + {#if !useCustomUnit} + + {/if} - + - {#if useCustomUnit} - - {/if} -
-
+ {#if useCustomUnit} + + {/if} +
+
- {#if error} -

{error}

- {/if} + {#if error} +

{error}

+ {/if} - -
+ +
diff --git a/src/routes/questions/+page.svelte b/src/routes/questions/+page.svelte index 23e05cd..e01bc27 100644 --- a/src/routes/questions/+page.svelte +++ b/src/routes/questions/+page.svelte @@ -1,104 +1,112 @@ - Questions — Notebook + Questions — Notebook
-
-

Questions

- Ask a question -
+
+

Questions

+ Ask a question +
-
-
- - {#each usedUnits as unit} - - {/each} -
-
- - -
-
+
+
+ + {#each usedUnits as unit} + + {/each} +
+
+ + +
+
- {#if loading} -

Loading

- {:else} - {#each visible as question} - - {:else} -
-

No questions yet.

- Ask a question -
- {/each} - {/if} + {#if loading} +

Loading

+ {:else} + {#each visible as question} + + {:else} +
+

No questions yet.

+ Ask a question +
+ {/each} + {/if}
diff --git a/src/routes/questions/[id]/+page.svelte b/src/routes/questions/[id]/+page.svelte index 847207f..6d59bcd 100644 --- a/src/routes/questions/[id]/+page.svelte +++ b/src/routes/questions/[id]/+page.svelte @@ -1,162 +1,192 @@ - {question?.title ?? 'Loading...'} — Notebook + {question?.title ?? "Loading..."} — Notebook
- {#if loading} -

Loading

- {:else if question} -
- -
-

- {#if unit}{unit.code}{/if}{#if unit && topic} · {/if}{#if topic}{topic.name}{/if} - {#if question.solved} · Solved{/if} -

-

{question.title}

-

- {question.authorName} · {timeAgo(question.createdAt)} - {#if isAuthor && !question.solved} - · - - {/if} -

-
-
+ {#if loading} +

Loading

+ {:else if question} +
+ +
+

+ {#if unit}{unit.code}{/if}{#if unit && topic} + · + {/if}{#if topic}{topic.name}{/if} + {#if question.solved} + · Solved{/if} +

+

+ {question.title} +

+

+ {question.authorName} · {timeAgo(question.createdAt)} + {#if isAuthor && !question.solved} + · + + {/if} +

+
+
-
- {question.content} -
+
+ {question.content} +
-
-

Answers ({answers.length})

+
+

Answers ({answers.length})

- {#if get(isAuthenticated)} -
- -
- {answerError} - -
-
- {:else} -

- Sign in to answer. -

- {/if} + {#if get(isAuthenticated)} +
+ +
+ {answerError} + +
+
+ {:else} +

+ Sign in to answer. +

+ {/if} -
- {#each answers as answer} -
-

{answer.authorName} · {timeAgo(answer.createdAt)}

-

{answer.content}

- {#if get(currentUser)?._id === answer.authorId} - - {/if} -
- {:else} -

No answers yet.

- {/each} -
-
- {:else} -

Question not found

-

This question may have been deleted or doesn't exist.

- Back to questions - {/if} +
+ {#each answers as answer} +
+

{answer.authorName} · {timeAgo(answer.createdAt)}

+

+ {answer.content} +

+ {#if get(currentUser)?._id === answer.authorId} + + {/if} +
+ {:else} +

No answers yet.

+ {/each} +
+
+ {:else} +

Question not found

+

This question may have been deleted or doesn't exist.

+ Back to questions + {/if}
diff --git a/src/routes/search/+page.svelte b/src/routes/search/+page.svelte index eabce80..3bb6ee5 100644 --- a/src/routes/search/+page.svelte +++ b/src/routes/search/+page.svelte @@ -1,59 +1,69 @@ - {searchQuery ? `Search: ${searchQuery}` : 'Search'} — Notebook + {searchQuery ? `Search: ${searchQuery}` : "Search"} — Notebook
-

Search

-
{ - e.preventDefault(); - const q = searchQuery.trim(); - if (!q) return; - window.location.href = `/search?q=${encodeURIComponent(q)}`; - }} - > - - -
+

Search

+
{ + e.preventDefault(); + const q = searchQuery.trim(); + if (!q) return; + window.location.href = `/search?q=${encodeURIComponent(q)}`; + }} + > + + +
- {#if loading} -

Loading

- {:else if ranQuery} - {#each results as note} - - {:else} -

No results found for “{searchQuery}”.

- Browse notes - {/each} - {/if} + {#if loading} +

Loading

+ {:else if ranQuery} + {#each results as note} + + {:else} +

No results found for “{searchQuery}”.

+ Browse notes + {/each} + {/if}
diff --git a/src/routes/topics/[slug]/+page.svelte b/src/routes/topics/[slug]/+page.svelte index 56d3369..0917817 100644 --- a/src/routes/topics/[slug]/+page.svelte +++ b/src/routes/topics/[slug]/+page.svelte @@ -1,83 +1,93 @@ - {topic?.name ?? 'Topic'} — Notebook + {topic?.name ?? "Topic"} — Notebook
- {#if loading} -

Loading

- {:else if topic} -

Home · Topic

-

{topic.name}

- {#if topic.description} -

{topic.description}

- {/if} + {#if loading} +

Loading

+ {:else if topic} +

Home · Topic

+

{topic.name}

+ {#if topic.description} +

{topic.description}

+ {/if} - {#if notes.length > 0} -

Notes

- {#each notes as note} - - {/each} - {/if} + {#if notes.length > 0} +

Notes

+ {#each notes as note} + + {/each} + {/if} - {#if questions.length > 0} -

Questions

- {#each questions as question} - - {/each} - {/if} + {#if questions.length > 0} +

Questions

+ {#each questions as question} + + {/each} + {/if} - {#if notes.length === 0 && questions.length === 0} -

No content in this topic yet.

- - {/if} - {:else} -

Topic not found

- Home - {/if} + {#if notes.length === 0 && questions.length === 0} +

No content in this topic yet.

+ + {/if} + {:else} +

Topic not found

+ Home + {/if}
diff --git a/src/routes/units/[code]/+page.svelte b/src/routes/units/[code]/+page.svelte index d2f1230..ac994fb 100644 --- a/src/routes/units/[code]/+page.svelte +++ b/src/routes/units/[code]/+page.svelte @@ -1,86 +1,96 @@ - {unit?.code ?? 'Unit'} — Notebook + {unit?.code ?? "Unit"} — Notebook
- {#if loading} -

Loading

- {:else if unit} -

Home · Unit

-

{unit.code}

-

{unit.name}

- {#if unit.description} -

{unit.description}

- {/if} + {#if loading} +

Loading

+ {:else if unit} +

Home · Unit

+

{unit.code}

+

{unit.name}

+ {#if unit.description} +

{unit.description}

+ {/if} - {#if notes.length > 0} -

Notes

- {#each notes as note} - - {/each} - {/if} + {#if notes.length > 0} +

Notes

+ {#each notes as note} + + {/each} + {/if} - {#if questions.length > 0} -

Questions

- {#each questions as question} - - {/each} - {/if} + {#if questions.length > 0} +

Questions

+ {#each questions as question} + + {/each} + {/if} - {#if notes.length === 0 && questions.length === 0} -

No content for this unit yet.

- - {/if} - {:else} -

Unit not found

- Home - {/if} + {#if notes.length === 0 && questions.length === 0} +

No content for this unit yet.

+ + {/if} + {:else} +

Unit not found

+ Home + {/if}
diff --git a/vite.config.ts b/vite.config.ts index 7cb48b2..a4421b1 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,8 +1,8 @@ -import tailwindcss from '@tailwindcss/vite'; -import { defineConfig } from 'vitest/config'; -import { playwright } from '@vitest/browser-playwright'; -import adapter from '@sveltejs/adapter-node'; -import { sveltekit } from '@sveltejs/kit/vite'; +import tailwindcss from "@tailwindcss/vite"; +import { defineConfig } from "vitest/config"; +import { playwright } from "@vitest/browser-playwright"; +import adapter from "@sveltejs/adapter-node"; +import { sveltekit } from "@sveltejs/kit/vite"; export default defineConfig({ plugins: [ @@ -10,39 +10,40 @@ export default defineConfig({ sveltekit({ compilerOptions: { // Force runes mode for the project, except for libraries. Can be removed in svelte 6. - runes: ({ filename }) => filename.split(/[/\\]/).includes('node_modules') ? undefined : true + runes: ({ filename }) => + filename.split(/[/\\]/).includes("node_modules") ? undefined : true, }, // adapter-node is used because the app persists data to a local SQLite file on the server. - adapter: adapter() - }) + adapter: adapter(), + }), ], test: { expect: { requireAssertions: true }, projects: [ { - extends: './vite.config.ts', + extends: "./vite.config.ts", test: { - name: 'client', + name: "client", browser: { enabled: true, provider: playwright(), - instances: [{ browser: 'chromium', headless: true }] + instances: [{ browser: "chromium", headless: true }], }, - include: ['src/**/*.svelte.{test,spec}.{js,ts}'], - exclude: ['src/lib/server/**'] - } + include: ["src/**/*.svelte.{test,spec}.{js,ts}"], + exclude: ["src/lib/server/**"], + }, }, { - extends: './vite.config.ts', + extends: "./vite.config.ts", test: { - name: 'server', - environment: 'node', - include: ['src/**/*.{test,spec}.{js,ts}'], - exclude: ['src/**/*.svelte.{test,spec}.{js,ts}'] - } - } - ] - } + name: "server", + environment: "node", + include: ["src/**/*.{test,spec}.{js,ts}"], + exclude: ["src/**/*.svelte.{test,spec}.{js,ts}"], + }, + }, + ], + }, });