BLOG-3 feat: footer ui

This commit is contained in:
SquidSpirit 2025-01-17 01:31:19 +08:00
parent df814c9e3f
commit c833df2d7e
4 changed files with 123 additions and 19 deletions

View File

@ -10,21 +10,26 @@
"lint": "next lint" "lint": "next lint"
}, },
"dependencies": { "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", "next": "15.1.4",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0" "react-dom": "^19.0.0"
}, },
"devDependencies": { "devDependencies": {
"@eslint/eslintrc": "^3", "@eslint/eslintrc": "^3.2.0",
"@types/node": "^20", "@types/node": "^20.17.14",
"@types/react": "^19", "@types/react": "^19.0.7",
"@types/react-dom": "^19", "@types/react-dom": "^19.0.3",
"eslint": "^9", "eslint": "^9.18.0",
"eslint-config-next": "15.1.4", "eslint-config-next": "15.1.4",
"postcss": "^8", "postcss": "^8.5.1",
"prettier": "^3.4.2", "prettier": "^3.4.2",
"prettier-plugin-tailwindcss": "^0.6.10", "prettier-plugin-tailwindcss": "^0.6.10",
"tailwindcss": "^3.4.1", "tailwindcss": "^3.4.17",
"typescript": "^5" "typescript": "^5.7.3"
} }
} }

View File

@ -8,6 +8,21 @@ importers:
.: .:
dependencies: 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: next:
specifier: 15.1.4 specifier: 15.1.4
version: 15.1.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0) version: 15.1.4(react-dom@19.0.0(react@19.0.0))(react@19.0.0)
@ -19,25 +34,25 @@ importers:
version: 19.0.0(react@19.0.0) version: 19.0.0(react@19.0.0)
devDependencies: devDependencies:
'@eslint/eslintrc': '@eslint/eslintrc':
specifier: ^3 specifier: ^3.2.0
version: 3.2.0 version: 3.2.0
'@types/node': '@types/node':
specifier: ^20 specifier: ^20.17.14
version: 20.17.14 version: 20.17.14
'@types/react': '@types/react':
specifier: ^19 specifier: ^19.0.7
version: 19.0.7 version: 19.0.7
'@types/react-dom': '@types/react-dom':
specifier: ^19 specifier: ^19.0.3
version: 19.0.3(@types/react@19.0.7) version: 19.0.3(@types/react@19.0.7)
eslint: eslint:
specifier: ^9 specifier: ^9.18.0
version: 9.18.0(jiti@1.21.7) version: 9.18.0(jiti@1.21.7)
eslint-config-next: eslint-config-next:
specifier: 15.1.4 specifier: 15.1.4
version: 15.1.4(eslint@9.18.0(jiti@1.21.7))(typescript@5.7.3) version: 15.1.4(eslint@9.18.0(jiti@1.21.7))(typescript@5.7.3)
postcss: postcss:
specifier: ^8 specifier: ^8.5.1
version: 8.5.1 version: 8.5.1
prettier: prettier:
specifier: ^3.4.2 specifier: ^3.4.2
@ -46,10 +61,10 @@ importers:
specifier: ^0.6.10 specifier: ^0.6.10
version: 0.6.10(prettier@3.4.2) version: 0.6.10(prettier@3.4.2)
tailwindcss: tailwindcss:
specifier: ^3.4.1 specifier: ^3.4.17
version: 3.4.17 version: 3.4.17
typescript: typescript:
specifier: ^5 specifier: ^5.7.3
version: 5.7.3 version: 5.7.3
packages: packages:
@ -95,6 +110,32 @@ packages:
resolution: {integrity: sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==} resolution: {integrity: sha512-lB05FkqEdUg2AA0xEbUz0SnkXT1LcCTa438W4IWTUh4hdOnVbQyOJ81OrDXsJk/LSiJHubgGEFoR5EHq1NsH1A==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0} 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': '@humanfs/core@0.19.1':
resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==} resolution: {integrity: sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA==}
engines: {node: '>=18.18.0'} engines: {node: '>=18.18.0'}
@ -1784,6 +1825,30 @@ snapshots:
'@eslint/core': 0.10.0 '@eslint/core': 0.10.0
levn: 0.4.1 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/core@0.19.1': {}
'@humanfs/node@0.16.6': '@humanfs/node@0.16.6':

View File

@ -2,6 +2,7 @@ import type { Metadata } from "next";
import { Inter } from "next/font/google"; import { Inter } from "next/font/google";
import "./globals.css"; import "./globals.css";
import Navbar from "@/ui/layout/navbar"; import Navbar from "@/ui/layout/navbar";
import Footer from "@/ui/layout/footer";
const inter = Inter({ const inter = Inter({
subsets: ["latin"], subsets: ["latin"],
@ -18,10 +19,13 @@ export default function RootLayout({
children: React.ReactNode; children: React.ReactNode;
}>) { }>) {
return ( return (
<html lang="en"> <html lang="zh-Hant">
<body className={`${inter.className} antialiased`}> <body className={`${inter.className} antialiased`}>
<Navbar /> <div className="min-h-screen">
{children} <Navbar />
{children}
</div>
<Footer />
</body> </body>
</html> </html>
); );

View File

@ -0,0 +1,30 @@
import { faGithub, faYoutube } from "@fortawesome/free-brands-svg-icons";
import { faEnvelope } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import React from "react";
type Props = {};
export default function Footer({}: Props) {
return (
<div className="border-t border-gray-300">
<div className="mx-auto flex max-w-screen-xl flex-col items-center justify-center gap-4 px-4 py-12 md:flex-row md:px-6">
<div className="flex flex-row items-center justify-center gap-x-4">
<FontAwesomeIcon className="size-4" icon={faYoutube} />
<FontAwesomeIcon className="size-4" icon={faEnvelope} />
<FontAwesomeIcon className="size-4" icon={faGithub} />
</div>
<Devider className="max-md:hidden" />
<span className="text-sm">Copyright © 2025 SquidSpirit</span>
</div>
</div>
);
}
function Devider(props: { className?: string }) {
return (
<div className={props.className}>
<div className="h-4 w-0.5 bg-gray-300" />
</div>
);
}