-
-
-
- Get started by editing{" "}
-
- src/app/page.tsx -
- . -
- - Save and see your changes instantly. -
diff --git a/frontend/.prettierrc b/frontend/.prettierrc new file mode 100644 index 0000000..b4bfed3 --- /dev/null +++ b/frontend/.prettierrc @@ -0,0 +1,3 @@ +{ + "plugins": ["prettier-plugin-tailwindcss"] +} diff --git a/frontend/package.json b/frontend/package.json index b226e31..722ae0b 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -10,19 +10,26 @@ "lint": "next lint" }, "dependencies": { + "@fortawesome/fontawesome-svg-core": "^6.7.2", + "@fortawesome/free-brands-svg-icons": "^6.7.2", + "@fortawesome/free-regular-svg-icons": "^6.7.2", + "@fortawesome/free-solid-svg-icons": "^6.7.2", + "@fortawesome/react-fontawesome": "^0.2.2", + "next": "15.1.4", "react": "^19.0.0", - "react-dom": "^19.0.0", - "next": "15.1.4" + "react-dom": "^19.0.0" }, "devDependencies": { - "typescript": "^5", - "@types/node": "^20", - "@types/react": "^19", - "@types/react-dom": "^19", - "postcss": "^8", - "tailwindcss": "^3.4.1", - "eslint": "^9", + "@eslint/eslintrc": "^3.2.0", + "@types/node": "^20.17.14", + "@types/react": "^19.0.7", + "@types/react-dom": "^19.0.3", + "eslint": "^9.18.0", "eslint-config-next": "15.1.4", - "@eslint/eslintrc": "^3" + "postcss": "^8.5.1", + "prettier": "^3.4.2", + "prettier-plugin-tailwindcss": "^0.6.10", + "tailwindcss": "^3.4.17", + "typescript": "^5.7.3" } } diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml index 209ea05..7a17382 100644 --- a/frontend/pnpm-lock.yaml +++ b/frontend/pnpm-lock.yaml @@ -8,6 +8,21 @@ importers: .: dependencies: + '@fortawesome/fontawesome-svg-core': + specifier: ^6.7.2 + version: 6.7.2 + '@fortawesome/free-brands-svg-icons': + specifier: ^6.7.2 + version: 6.7.2 + '@fortawesome/free-regular-svg-icons': + specifier: ^6.7.2 + version: 6.7.2 + '@fortawesome/free-solid-svg-icons': + specifier: ^6.7.2 + version: 6.7.2 + '@fortawesome/react-fontawesome': + specifier: ^0.2.2 + version: 0.2.2(@fortawesome/fontawesome-svg-core@6.7.2)(react@19.0.0) next: specifier: 15.1.4 version: 15.1.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) @@ -19,31 +34,37 @@ importers: version: 19.0.0(react@19.0.0) devDependencies: '@eslint/eslintrc': - specifier: ^3 + specifier: ^3.2.0 version: 3.2.0 '@types/node': - specifier: ^20 + specifier: ^20.17.14 version: 20.17.14 '@types/react': - specifier: ^19 + specifier: ^19.0.7 version: 19.0.7 '@types/react-dom': - specifier: ^19 + specifier: ^19.0.3 version: 19.0.3(@types/react@19.0.7) eslint: - specifier: ^9 + specifier: ^9.18.0 version: 9.18.0(jiti@1.21.7) eslint-config-next: specifier: 15.1.4 version: 15.1.4(eslint@9.18.0(jiti@1.21.7))(typescript@5.7.3) postcss: - specifier: ^8 + specifier: ^8.5.1 version: 8.5.1 + prettier: + specifier: ^3.4.2 + version: 3.4.2 + prettier-plugin-tailwindcss: + specifier: ^0.6.10 + version: 0.6.10(prettier@3.4.2) tailwindcss: - specifier: ^3.4.1 + specifier: ^3.4.17 version: 3.4.17 typescript: - specifier: ^5 + specifier: ^5.7.3 version: 5.7.3 packages: @@ -89,6 +110,32 @@ packages: resolution: {integrity: sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==} engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} + '@fortawesome/fontawesome-common-types@6.7.2': + resolution: {integrity: sha512-Zs+YeHUC5fkt7Mg1l6XTniei3k4bwG/yo3iFUtZWd/pMx9g3fdvkSK9E0FOC+++phXOka78uJcYb8JaFkW52Xg==} + engines: {node: '>=6'} + + '@fortawesome/fontawesome-svg-core@6.7.2': + resolution: {integrity: sha512-yxtOBWDrdi5DD5o1pmVdq3WMCvnobT0LU6R8RyyVXPvFRd2o79/0NCuQoCjNTeZz9EzA9xS3JxNWfv54RIHFEA==} + engines: {node: '>=6'} + + '@fortawesome/free-brands-svg-icons@6.7.2': + resolution: {integrity: sha512-zu0evbcRTgjKfrr77/2XX+bU+kuGfjm0LbajJHVIgBWNIDzrhpRxiCPNT8DW5AdmSsq7Mcf9D1bH0aSeSUSM+Q==} + engines: {node: '>=6'} + + '@fortawesome/free-regular-svg-icons@6.7.2': + resolution: {integrity: sha512-7Z/ur0gvCMW8G93dXIQOkQqHo2M5HLhYrRVC0//fakJXxcF1VmMPsxnG6Ee8qEylA8b8Q3peQXWMNZ62lYF28g==} + engines: {node: '>=6'} + + '@fortawesome/free-solid-svg-icons@6.7.2': + resolution: {integrity: sha512-GsBrnOzU8uj0LECDfD5zomZJIjrPhIlWU82AHwa2s40FKH+kcxQaBvBo3Z4TxyZHIyX8XTDxsyA33/Vx9eFuQA==} + engines: {node: '>=6'} + + '@fortawesome/react-fontawesome@0.2.2': + resolution: {integrity: sha512-EnkrprPNqI6SXJl//m29hpaNzOp1bruISWaOiRtkMi/xSvHJlzc2j2JAYS7egxt/EbjSNV/k6Xy0AQI6vB2+1g==} + peerDependencies: + '@fortawesome/fontawesome-svg-core': ~1 || ~6 + react: '>=16.3' + '@humanfs/core@0.19.1': resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} engines: {node: '>=18.18.0'} @@ -1337,6 +1384,66 @@ packages: resolution: {integrity: sha512-vkcDPrRZo1QZLbn5RLGPpg/WmIQ65qoWWhcGKf/b5eplkkarX0m9z8ppCat4mlOqUsWpyNuYgO3VRyrYHSzX5g==} engines: {node: '>= 0.8.0'} + prettier-plugin-tailwindcss@0.6.10: + resolution: {integrity: sha512-ndj2WLDaMzACnr1gAYZiZZLs5ZdOeBYgOsbBmHj3nvW/6q8h8PymsXiEnKvj/9qgCCAoHyvLOisoQdIcsDvIgw==} + engines: {node: '>=14.21.3'} + peerDependencies: + '@ianvs/prettier-plugin-sort-imports': '*' + '@prettier/plugin-pug': '*' + '@shopify/prettier-plugin-liquid': '*' + '@trivago/prettier-plugin-sort-imports': '*' + '@zackad/prettier-plugin-twig': '*' + prettier: ^3.0 + prettier-plugin-astro: '*' + prettier-plugin-css-order: '*' + prettier-plugin-import-sort: '*' + prettier-plugin-jsdoc: '*' + prettier-plugin-marko: '*' + prettier-plugin-multiline-arrays: '*' + prettier-plugin-organize-attributes: '*' + prettier-plugin-organize-imports: '*' + prettier-plugin-sort-imports: '*' + prettier-plugin-style-order: '*' + prettier-plugin-svelte: '*' + peerDependenciesMeta: + '@ianvs/prettier-plugin-sort-imports': + optional: true + '@prettier/plugin-pug': + optional: true + '@shopify/prettier-plugin-liquid': + optional: true + '@trivago/prettier-plugin-sort-imports': + optional: true + '@zackad/prettier-plugin-twig': + optional: true + prettier-plugin-astro: + optional: true + prettier-plugin-css-order: + optional: true + prettier-plugin-import-sort: + optional: true + prettier-plugin-jsdoc: + optional: true + prettier-plugin-marko: + optional: true + prettier-plugin-multiline-arrays: + optional: true + prettier-plugin-organize-attributes: + optional: true + prettier-plugin-organize-imports: + optional: true + prettier-plugin-sort-imports: + optional: true + prettier-plugin-style-order: + optional: true + prettier-plugin-svelte: + optional: true + + prettier@3.4.2: + resolution: {integrity: sha512-e9MewbtFo+Fevyuxn/4rrcDAaq0IYxPGLvObpQjiZBMAzB9IGmzlnG9RZy3FFas+eBMu2vA0CszMeduow5dIuQ==} + engines: {node: '>=14'} + hasBin: true + prop-types@15.8.1: resolution: {integrity: sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==} @@ -1718,6 +1825,30 @@ snapshots: '@eslint/core': 0.10.0 levn: 0.4.1 + '@fortawesome/fontawesome-common-types@6.7.2': {} + + '@fortawesome/fontawesome-svg-core@6.7.2': + dependencies: + '@fortawesome/fontawesome-common-types': 6.7.2 + + '@fortawesome/free-brands-svg-icons@6.7.2': + dependencies: + '@fortawesome/fontawesome-common-types': 6.7.2 + + '@fortawesome/free-regular-svg-icons@6.7.2': + dependencies: + '@fortawesome/fontawesome-common-types': 6.7.2 + + '@fortawesome/free-solid-svg-icons@6.7.2': + dependencies: + '@fortawesome/fontawesome-common-types': 6.7.2 + + '@fortawesome/react-fontawesome@0.2.2(@fortawesome/fontawesome-svg-core@6.7.2)(react@19.0.0)': + dependencies: + '@fortawesome/fontawesome-svg-core': 6.7.2 + prop-types: 15.8.1 + react: 19.0.0 + '@humanfs/core@0.19.1': {} '@humanfs/node@0.16.6': @@ -3112,6 +3243,12 @@ snapshots: prelude-ls@1.2.1: {} + prettier-plugin-tailwindcss@0.6.10(prettier@3.4.2): + dependencies: + prettier: 3.4.2 + + prettier@3.4.2: {} + prop-types@15.8.1: dependencies: loose-envify: 1.4.0 diff --git a/frontend/src/app/globals.css b/frontend/src/app/globals.css index 6b717ad..7502d79 100644 --- a/frontend/src/app/globals.css +++ b/frontend/src/app/globals.css @@ -2,20 +2,6 @@ @tailwind components; @tailwind utilities; -:root { - --background: #ffffff; - --foreground: #171717; -} - -@media (prefers-color-scheme: dark) { - :root { - --background: #0a0a0a; - --foreground: #ededed; - } -} - body { - color: var(--foreground); - background: var(--background); - font-family: Arial, Helvetica, sans-serif; + @apply bg-white text-gray-600; } diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx index f7fa87e..e0721fe 100644 --- a/frontend/src/app/layout.tsx +++ b/frontend/src/app/layout.tsx @@ -1,20 +1,16 @@ import type { Metadata } from "next"; -import { Geist, Geist_Mono } from "next/font/google"; +import { Inter } from "next/font/google"; import "./globals.css"; +import Navbar from "@/ui/layout/navbar"; +import Footer from "@/ui/layout/footer"; -const geistSans = Geist({ - variable: "--font-geist-sans", - subsets: ["latin"], -}); - -const geistMono = Geist_Mono({ - variable: "--font-geist-mono", +const inter = Inter({ subsets: ["latin"], }); export const metadata: Metadata = { - title: "Create Next App", - description: "Generated by create next app", + title: "魚之魷魂 SquidSpirit", + description: "程式、科技、教學、分享", }; export default function RootLayout({ @@ -23,11 +19,13 @@ export default function RootLayout({ children: React.ReactNode; }>) { return ( - -
- {children} + + +
- src/app/page.tsx
-
- .
-