Skip to content
This repository was archived by the owner on Aug 17, 2026. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 0 additions & 30 deletions .storybook/main.js

This file was deleted.

15 changes: 0 additions & 15 deletions .storybook/preview.js

This file was deleted.

2 changes: 1 addition & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"html",
"markdown"
],
"eslint.experimental.useFlatConfig": true,
"eslint.useFlatConfig": true,
"[typescript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
Expand Down
2 changes: 1 addition & 1 deletion components/Navbar.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<template>
<header
class="whitespace-nowrap flex items-center px-10 z-50 w-screen shadow-sm
class="whitespace-nowrap flex items-center px-10 z-50 w-full shadow-sm
backdrop-blur-md backdrop-saturate-200 bg-white/70 dark:bg-gray-900/70
flex-col h-28 justify-evenly md:flex-row md:py-0 md:h-16 md:justify-between md:space-x-12"
>
Expand Down
22 changes: 14 additions & 8 deletions components/index/NewsWidget/NewsWidget.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
<ul class="space-y-2 list-none list-inside">
<IndexNewsWidgetItem
v-for="digest in digests"
:key="digest._path"
:digest="digest"
:key="digest.path"
:digest="digest as ArticleDigest"
/>
</ul>
<NuxtLink to="/news">
Expand All @@ -27,14 +27,20 @@
</template>

<script setup lang="ts">
import { type ArticleDigest } from '~/components/news/ArticleDigest'
import type { ArticleDigest } from '~/components/news/ArticleDigest'

const rawData = await useAsyncData(
'news',
() => queryContent('news')
.only(['title', '_path', 'description', 'date', 'tags'])
.sort({ date: -1 })
.find(),
() => queryCollection('news')
.select('title', 'path', 'description', 'date', 'tags')
.order('date', 'DESC')
.all(),
)
const digests = (rawData.data.value ?? []) as ArticleDigest[]
const digests = computed(() => {
const data = rawData.data?.value
if (!data) {
return []
}
return data
})
</script>
6 changes: 4 additions & 2 deletions components/index/NewsWidget/NewsWidgetItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<Icon name="icon-park-outline:align-text-left" />
</div>
<NuxtLink
:to="digest._path"
:to="digest.path"
class="truncate transition-colors relative inline-block z-10 decoration-dotted underline-offset-4 hocus:underline hover:cursor-pointer"
>
{{ digest.title }}
Expand All @@ -22,9 +22,11 @@
<script setup lang="ts">
import dayjs from 'dayjs'
import relativeTime from 'dayjs/plugin/relativeTime'
import { type ArticleDigest } from '~/components/news/ArticleDigest'
import utc from 'dayjs/plugin/utc'
import type { ArticleDigest } from '~/components/news/ArticleDigest'

dayjs.extend(relativeTime)
dayjs.extend(utc)
defineProps<{
digest: ArticleDigest
}>()
Expand Down
4 changes: 2 additions & 2 deletions components/news/ArticleDigest.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
export type ArticleDigest = {
_path: string
path: string
title: string
description: string
date: string
date: Date
tags: string[]
}
20 changes: 12 additions & 8 deletions components/news/NewsList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,25 @@
>
<NewsListItem
v-for="digest in digests"
:key="digest._path"
:key="digest.path"
:digest="digest"
/>
</ul>
</template>

<script setup lang="ts">
import { type ArticleDigest } from './ArticleDigest'

const rawData = await useAsyncData(
'news',
() => queryContent('news')
.only(['title', '_path', 'description', 'date', 'tags'])
.sort({ date: -1 })
.find(),
() => queryCollection('news')
.select('title', 'path', 'description', 'date', 'tags')
.order('date', 'DESC')
.all(),
)
const digests = (rawData.data.value ?? []) as ArticleDigest[]
const digests = computed(() => {
const data = rawData.data?.value
if (!data) {
return []
}
return data
})
</script>
4 changes: 2 additions & 2 deletions components/news/NewsListItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
class="flex flex-col space-y-2 p-4 w-full border-t-[0.1em] border-slate-300 dark:border-slate-600"
>
<NuxtLink
:to="digest._path"
:to="digest.path"
class="transition-colors max-w-min hocus:text-blue-400 dark:hocus:text-blue-300"
>
<h2
Expand Down Expand Up @@ -41,7 +41,7 @@
</template>

<script setup lang="ts">
import { type ArticleDigest } from './ArticleDigest'
import type { ArticleDigest } from './ArticleDigest'

const props = defineProps<{
digest: ArticleDigest
Expand Down
23 changes: 23 additions & 0 deletions content.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { defineCollection, defineContentConfig, z } from '@nuxt/content'

export default defineContentConfig({
collections: {
news: defineCollection({
source: 'news/*.md',
type: 'page',
schema: z.object({
title: z.string(),
tags: z.array(z.string()),
date: z.date(),
description: z.string(),
}),
}),
fallback: defineCollection({
source: '*.md',
type: 'page',
schema: z.object({
title: z.string(),
}),
}),
},
})
4 changes: 2 additions & 2 deletions layouts/default.vue
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<template>
<div class="flex flex-col text-slate-800 dark:text-slate-200 w-screen">
<div class="flex flex-col text-slate-800 dark:text-slate-200 w-screen max-w-full">
<Navbar
title-name="HITSZ OSA Mirrors"
class="fixed top-0 left-0"
class="fixed top-0 left-0 right-0"
>
<template #logo>
<img
Expand Down
23 changes: 17 additions & 6 deletions nuxt.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,20 +4,29 @@ export default defineNuxtConfig({
'@pinia/nuxt',
'@nuxtjs/color-mode',
'@nuxt/content',
'nuxt-icon',
'@nuxt/icon',
'dayjs-nuxt',
'@nuxt/ui',
'@nuxt/eslint',
'@nuxtjs/mdc',
],

ssr: true,

devtools: { enabled: true },
css: ['@/assets/css/main.css'],

colorMode: {
classSuffix: '',
},

devtools: { enabled: true },
css: ['@/assets/css/main.css'],
mdc: {
highlight: false,
},

ui: {},

compatibilityDate: '2024-11-01',

postcss: {
plugins: {
Expand All @@ -26,7 +35,9 @@ export default defineNuxtConfig({
},
},

ui: {},

compatibilityDate: '2024-11-01',
icon: {
serverBundle: {
collections: ['icon-park'],
},
},
})
45 changes: 25 additions & 20 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,41 +10,46 @@
"format": "eslint --fix ."
},
"devDependencies": {
"@nuxt/content": "^2.8.1",
"@nuxt/devtools": "^1.6.0",
"@nuxt/eslint": "^0.3.7",
"@nuxtjs/color-mode": "^3.4.0",
"@nuxtjs/eslint-config-typescript": "^12.1.0",
"@nuxtjs/eslint-module": "^4.1.0",
"@tailwindcss/typography": "^0.5.15",
"@typescript-eslint/parser": "^6.5.0",
"@typescript-eslint/parser": "^8.29",
"autoprefixer": "^10.4.15",
"browserslist": "^4.24.4",
"dayjs-nuxt": "^1.1.2",
"eslint": "^9.0.0",
"eslint-config-prettier": "^9.0.0",
"eslint-plugin-prettier": "^5.0.0",
"eslint-plugin-vue": "^9.17.0",
"nuxt": "~3.14",
"nuxt-eslint-auto-explicit-import": "^0.0.2",
"nuxt-icon": "^0.5.0",
"nuxt-purgecss": "^2.0.0",
"nuxt-eslint-auto-explicit-import": "^0.1.1",
"postcss": "^8.4.29",
"prettier-eslint": "^15.0.1",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"prettier": "^3.5",
"prettier-eslint": "^16.0.1",
"sass": "^1.66.1",
"tailwindcss": "^3.3.3",
"typescript": "^5.2.2",
"vue-eslint-parser": "^9.3.1",
"update-browserslist-db": "^1.1.3"
"typescript": "^5.6.3",
"update-browserslist-db": "^1.1.3",
"vue-eslint-parser": "^9.3.1"
},
"dependencies": {
"@iconify/json": "^2.2.126",
"@nuxt/ui": "^2.13.0",
"@pinia/nuxt": "^0.4.11",
"@nuxt/content": "^3.4.0",
"@nuxt/eslint": "^1.3.0",
"@nuxt/fonts": "^0.11.0",
"@nuxt/icon": "^1.11.0",
"@nuxt/image": "1.10.0",
"@nuxt/scripts": "^0.11.5",
"@nuxt/test-utils": "^3.17.2",
"@nuxt/ui": "^2",
"@nuxtjs/mdc": "0.16.1",
"@pinia/nuxt": "^0.10.1",
"@unhead/vue": "^2.0.2",
"dayjs": "^1.11.9",
"pinia": "^2.1.6",
"nuxt": "^3.16.1",
"pinia": "^3",
"vue": "^3.5.13",
"vue-router": "^4.5.0",
"vue3-keypress": "^4.0.1"
},
"type": "module",
"packageManager": "yarn@1.22.21+sha1.1959a18351b811cdeedbd484a8f86c3cc3bbaf72"
"packageManager": "yarn@1.22.22+sha1.ac34549e6aa8e7ead463a7407e1c7390f61a6610"
}
12 changes: 0 additions & 12 deletions pages/[...slug].vue

This file was deleted.

18 changes: 18 additions & 0 deletions pages/[id].vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<template>
<article class="flex flex-col w-full max-w-screen-lg prose dark:prose-invert prose-slate">
<ContentRenderer
v-if="page"
:value="page"
/>
<NotFound v-else />
</article>
</template>

<script setup lang="ts">
const route = useRoute()
const { data: page } = await useAsyncData(route.path, () => {
return queryCollection('fallback')
.path(route.path)
.first()
})
</script>
12 changes: 0 additions & 12 deletions pages/news/[...slug].vue

This file was deleted.

18 changes: 18 additions & 0 deletions pages/news/[id].vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<template>
<article class="flex flex-col w-full max-w-screen-lg prose dark:prose-invert prose-slate">
<ContentRenderer
v-if="page"
:value="page"
/>
<NotFound v-else />
</article>
</template>

<script setup lang="ts">
const route = useRoute()
const { data: page } = await useAsyncData(route.path, () => {
return queryCollection('news')
.path(route.path)
.first()
})
</script>
Loading