feat: preliminary completion of index page and post page

Signed-off-by: Ryan Wang <i@ryanc.cc>
This commit is contained in:
Ryan Wang
2022-10-06 00:38:24 +08:00
parent d8769ce58c
commit d39c95bbce
17 changed files with 999 additions and 28 deletions

1
.gitignore vendored
View File

@@ -9,7 +9,6 @@ lerna-debug.log*
node_modules
.DS_Store
dist
*.local
# Editor directories and files

View File

@@ -13,6 +13,9 @@
"author": "",
"license": "ISC",
"devDependencies": {
"@iconify/json": "^2.1.118",
"@tailwindcss/aspect-ratio": "^0.4.2",
"@tailwindcss/typography": "^0.5.7",
"@types/node": "16",
"@typescript-eslint/eslint-plugin": "^5.39.0",
"@typescript-eslint/parser": "^5.39.0",
@@ -25,6 +28,10 @@
"prettier-plugin-tailwindcss": "^0.1.13",
"tailwindcss": "^3.1.8",
"typescript": "^4.6.4",
"vite": "^3.1.4"
"vite": "^3.1.4",
"vite-plugin-purge-icons": "^0.9.1"
},
"dependencies": {
"@iconify/iconify": "^3.0.0"
}
}

193
pnpm-lock.yaml generated
View File

@@ -1,6 +1,10 @@
lockfileVersion: 5.4
specifiers:
'@iconify/iconify': ^3.0.0
'@iconify/json': ^2.1.118
'@tailwindcss/aspect-ratio': ^0.4.2
'@tailwindcss/typography': ^0.5.7
'@types/node': '16'
'@typescript-eslint/eslint-plugin': ^5.39.0
'@typescript-eslint/parser': ^5.39.0
@@ -14,8 +18,15 @@ specifiers:
tailwindcss: ^3.1.8
typescript: ^4.6.4
vite: ^3.1.4
vite-plugin-purge-icons: ^0.9.1
dependencies:
'@iconify/iconify': 3.0.0
devDependencies:
'@iconify/json': 2.1.118
'@tailwindcss/aspect-ratio': 0.4.2_tailwindcss@3.1.8
'@tailwindcss/typography': 0.5.7_tailwindcss@3.1.8
'@types/node': 16.11.64
'@typescript-eslint/eslint-plugin': 5.39.0_c7dhob3nbh3wwlahpgade2jupi
'@typescript-eslint/parser': 5.39.0_4at4lsfnhb3djm6qjts2gmiglm
@@ -29,6 +40,7 @@ devDependencies:
tailwindcss: 3.1.8_postcss@8.4.17
typescript: 4.6.4
vite: 3.1.4
vite-plugin-purge-icons: 0.9.1_vite@3.1.4
packages:
@@ -91,6 +103,29 @@ packages:
resolution: {integrity: sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==}
dev: true
/@iconify/iconify/2.1.2:
resolution: {integrity: sha512-QcUzFeEWkE/mW+BVtEGmcWATClcCOIJFiYUD/PiCWuTcdEA297o8D4oN6Ra44WrNOHu1wqNW4J0ioaDIiqaFOQ==}
dependencies:
cross-fetch: 3.1.5
transitivePeerDependencies:
- encoding
dev: true
/@iconify/iconify/3.0.0:
resolution: {integrity: sha512-wgCSv4GwVLzwGqfUkYEDT9XOfetGZV67D5CmMYp74IdaPMnyOWb/3XxUPvGmuTt8Yw9xekMqzvdQp/p+a/abNw==}
dependencies:
'@iconify/types': 2.0.0
/@iconify/json/2.1.118:
resolution: {integrity: sha512-mvCocCcWIIoF/IiBQS0hIMqpmXYVbZsmNM8CyQCn6jEPEEKWpW5/vK+W+qOWO7+F7Hrs3//8OyLMh131by7zSQ==}
dependencies:
'@iconify/types': 2.0.0
pathe: 0.3.8
dev: true
/@iconify/types/2.0.0:
resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==}
/@nodelib/fs.scandir/2.1.5:
resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
engines: {node: '>= 8'}
@@ -112,6 +147,45 @@ packages:
fastq: 1.13.0
dev: true
/@purge-icons/core/0.9.1:
resolution: {integrity: sha512-sx8/a30MbbqQVEqhuMPE1wJpdVRRbEmwEPZpFzVkcDixzX4p+R2A0WVxqkb0xfHUBAVQwrSE2SeAyniIQLqbLw==}
dependencies:
'@iconify/iconify': 2.1.2
axios: 0.26.1_debug@4.3.4
debug: 4.3.4
fast-glob: 3.2.12
fs-extra: 10.1.0
transitivePeerDependencies:
- encoding
- supports-color
dev: true
/@purge-icons/generated/0.9.0:
resolution: {integrity: sha512-s2t+1oVtGDV6KtqfCXtUOhxfeYvOdDF90IVm+nMs/6bUP0HeGZLslguuL/AibpwtfL4FA/oCsIu/RhwapgAdJw==}
dependencies:
'@iconify/iconify': 3.0.0
dev: true
/@tailwindcss/aspect-ratio/0.4.2_tailwindcss@3.1.8:
resolution: {integrity: sha512-8QPrypskfBa7QIMuKHg2TA7BqES6vhBrDLOv8Unb6FcFyd3TjKbc6lcmb9UPQHxfl24sXoJ41ux/H7qQQvfaSQ==}
peerDependencies:
tailwindcss: '>=2.0.0 || >=3.0.0 || >=3.0.0-alpha.1'
dependencies:
tailwindcss: 3.1.8_postcss@8.4.17
dev: true
/@tailwindcss/typography/0.5.7_tailwindcss@3.1.8:
resolution: {integrity: sha512-JTTSTrgZfp6Ki4svhPA4mkd9nmQ/j9EfE7SbHJ1cLtthKkpW2OxsFXzSmxbhYbEkfNIyAyhle5p4SYyKRbz/jg==}
peerDependencies:
tailwindcss: '>=3.0.0 || insiders'
dependencies:
lodash.castarray: 4.4.0
lodash.isplainobject: 4.0.6
lodash.merge: 4.6.2
postcss-selector-parser: 6.0.10
tailwindcss: 3.1.8_postcss@8.4.17
dev: true
/@types/json-schema/7.0.11:
resolution: {integrity: sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==}
dev: true
@@ -337,6 +411,14 @@ packages:
postcss-value-parser: 4.2.0
dev: true
/axios/0.26.1_debug@4.3.4:
resolution: {integrity: sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA==}
dependencies:
follow-redirects: 1.15.2_debug@4.3.4
transitivePeerDependencies:
- debug
dev: true
/balanced-match/1.0.2:
resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==}
dev: true
@@ -423,6 +505,14 @@ packages:
resolution: {integrity: sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==}
dev: true
/cross-fetch/3.1.5:
resolution: {integrity: sha512-lvb1SBsI0Z7GDwmuid+mU3kWVBwTVUbe7S0H52yaaAdQOXq2YktTCZdlAcNKFzE6QtRz0snpw9bNiPeOIkkQvw==}
dependencies:
node-fetch: 2.6.7
transitivePeerDependencies:
- encoding
dev: true
/cross-spawn/7.0.3:
resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==}
engines: {node: '>= 8'}
@@ -929,10 +1019,31 @@ packages:
resolution: {integrity: sha512-5nqDSxl8nn5BSNxyR3n4I6eDmbolI6WT+QqR547RwxQapgjQBmtktdP+HTBb/a/zLsbzERTONyUB5pefh5TtjQ==}
dev: true
/follow-redirects/1.15.2_debug@4.3.4:
resolution: {integrity: sha512-VQLG33o04KaQ8uYi2tVNbdrWp1QWxNNea+nmIB4EVM28v0hmP17z7aG1+wAkNzVq4KeXTq3221ye5qTJP91JwA==}
engines: {node: '>=4.0'}
peerDependencies:
debug: '*'
peerDependenciesMeta:
debug:
optional: true
dependencies:
debug: 4.3.4
dev: true
/fraction.js/4.2.0:
resolution: {integrity: sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==}
dev: true
/fs-extra/10.1.0:
resolution: {integrity: sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==}
engines: {node: '>=12'}
dependencies:
graceful-fs: 4.2.10
jsonfile: 6.1.0
universalify: 2.0.0
dev: true
/fs.realpath/1.0.0:
resolution: {integrity: sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==}
dev: true
@@ -993,6 +1104,10 @@ packages:
slash: 3.0.0
dev: true
/graceful-fs/4.2.10:
resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==}
dev: true
/grapheme-splitter/1.0.4:
resolution: {integrity: sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==}
dev: true
@@ -1091,6 +1206,14 @@ packages:
resolution: {integrity: sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==}
dev: true
/jsonfile/6.1.0:
resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==}
dependencies:
universalify: 2.0.0
optionalDependencies:
graceful-fs: 4.2.10
dev: true
/levn/0.4.1:
resolution: {integrity: sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ==}
engines: {node: '>= 0.8.0'}
@@ -1111,6 +1234,14 @@ packages:
p-locate: 5.0.0
dev: true
/lodash.castarray/4.4.0:
resolution: {integrity: sha512-aVx8ztPv7/2ULbArGJ2Y42bG1mEQ5mGjpdvrbJcJFU3TbYybe+QlLS4pst9zV52ymy2in1KpFPiZnAOATxD4+Q==}
dev: true
/lodash.isplainobject/4.0.6:
resolution: {integrity: sha512-oSXzaWypCMHkPC3NvBEaPHf0KsA5mvPrOPgQWDsbg8n7orZ290M0BmC/jgRZ4vcJ6DTAhjrsSYgdsW/F+MFOBA==}
dev: true
/lodash.merge/4.6.2:
resolution: {integrity: sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==}
dev: true
@@ -1159,6 +1290,18 @@ packages:
resolution: {integrity: sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw==}
dev: true
/node-fetch/2.6.7:
resolution: {integrity: sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==}
engines: {node: 4.x || >=6.0.0}
peerDependencies:
encoding: ^0.1.0
peerDependenciesMeta:
encoding:
optional: true
dependencies:
whatwg-url: 5.0.0
dev: true
/node-releases/2.0.6:
resolution: {integrity: sha512-PiVXnNuFm5+iYkLBNeq5211hvO38y63T0i2KKh2KnUs3RpzJ+JtODFjkD8yjLwnDkTYF1eKXheUwdssR+NRZdg==}
dev: true
@@ -1241,6 +1384,10 @@ packages:
engines: {node: '>=8'}
dev: true
/pathe/0.3.8:
resolution: {integrity: sha512-c71n61F1skhj/jzZe+fWE9XDoTYjWbUwIKVwFftZ5IOgiX44BVkTkD+/803YDgR50tqeO4eXWxLyVHBLWQAD1g==}
dev: true
/picocolors/1.0.0:
resolution: {integrity: sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==}
dev: true
@@ -1410,6 +1557,17 @@ packages:
glob: 7.2.3
dev: true
/rollup-plugin-purge-icons/0.9.1:
resolution: {integrity: sha512-hRDKBsPUz47UMdBufki2feTmBF2ClEJlYqL7N6vpVAHSLd7V2BJUaNKOF7YYbLMofVVF+9hm44YSkYO6k9hUgg==}
engines: {node: '>= 12'}
dependencies:
'@purge-icons/core': 0.9.1
'@purge-icons/generated': 0.9.0
transitivePeerDependencies:
- encoding
- supports-color
dev: true
/rollup/2.78.1:
resolution: {integrity: sha512-VeeCgtGi4P+o9hIg+xz4qQpRl6R401LWEXBmxYKOV4zlF82lyhgh2hTZnheFUbANE8l2A41F458iwj2vEYaXJg==}
engines: {node: '>=10.0.0'}
@@ -1522,6 +1680,10 @@ packages:
is-number: 7.0.0
dev: true
/tr46/0.0.3:
resolution: {integrity: sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==}
dev: true
/tslib/1.14.1:
resolution: {integrity: sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==}
dev: true
@@ -1554,6 +1716,11 @@ packages:
hasBin: true
dev: true
/universalify/2.0.0:
resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==}
engines: {node: '>= 10.0.0'}
dev: true
/update-browserslist-db/1.0.9_browserslist@4.21.4:
resolution: {integrity: sha512-/xsqn21EGVdXI3EXSum1Yckj3ZVZugqyOZQ/CxYPBD/R+ko9NSUScf8tFF4dOKY+2pvSSJA/S+5B8s4Zr4kyvg==}
hasBin: true
@@ -1575,6 +1742,21 @@ packages:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
dev: true
/vite-plugin-purge-icons/0.9.1_vite@3.1.4:
resolution: {integrity: sha512-oS0Y9Iq6vGnTDVRzB8xJNhA/gGlyR0lfCICU6+9FRKdrO5PnT34fRjvd8YWEsegCrk91+w3GVZc0HJDj/dPp5Q==}
engines: {node: '>= 12'}
peerDependencies:
vite: ^2.0.0-beta.3 || ^3.0.0
dependencies:
'@purge-icons/core': 0.9.1
'@purge-icons/generated': 0.9.0
rollup-plugin-purge-icons: 0.9.1
vite: 3.1.4
transitivePeerDependencies:
- encoding
- supports-color
dev: true
/vite/3.1.4:
resolution: {integrity: sha512-JoQI08aBjY9lycL7jcEq4p9o1xUjq5aRvdH4KWaXtkSx7e7RpAh9D3IjzDWRD4Fg44LS3oDAIOG/Kq1L+82psA==}
engines: {node: ^14.18.0 || >=16.0.0}
@@ -1602,6 +1784,17 @@ packages:
fsevents: 2.3.2
dev: true
/webidl-conversions/3.0.1:
resolution: {integrity: sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==}
dev: true
/whatwg-url/5.0.0:
resolution: {integrity: sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==}
dependencies:
tr46: 0.0.3
webidl-conversions: 3.0.1
dev: true
/which/2.0.2:
resolution: {integrity: sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==}
engines: {node: '>= 8'}

View File

@@ -1,3 +1,14 @@
import "./styles/tailwind.css";
import "./styles/main.css";
import "@purge-icons/generated";
console.log("dd");
const onScroll = () => {
const headerMenu = document.getElementById("header-menu");
if (window.scrollY > 0) {
headerMenu?.classList.add("menu-sticky");
} else {
headerMenu?.classList.remove("menu-sticky");
}
};
window.addEventListener("scroll", onScroll);

32
src/styles/main.css Normal file
View File

@@ -0,0 +1,32 @@
body {
overflow: overlay;
background: #f9f9f9;
}
*::-webkit-scrollbar-track-piece {
background-color: #f8f8f8;
-webkit-border-radius: 2em;
-moz-border-radius: 2em;
border-radius: 2em;
}
*::-webkit-scrollbar {
width: 8px;
height: 8px;
}
*::-webkit-scrollbar-thumb {
background-color: #ddd;
background-clip: padding-box;
-webkit-border-radius: 2em;
-moz-border-radius: 2em;
border-radius: 2em;
}
*::-webkit-scrollbar-thumb:hover {
background-color: #bbb;
}
.menu-sticky {
@apply fixed top-0 left-0 right-0 z-10 bg-black/80 drop-shadow-md backdrop-blur-lg;
}

20
tailwind.config.cjs Normal file
View File

@@ -0,0 +1,20 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./templates/**/*.html"],
theme: {
extend: {},
container: {
padding: {
DEFAULT: "1rem",
sm: "2rem",
lg: "4rem",
xl: "5rem",
"2xl": "6rem",
},
},
},
plugins: [
require("@tailwindcss/aspect-ratio"),
require("@tailwindcss/typography"),
],
}

View File

@@ -1,8 +0,0 @@
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./templates/**/*.html"],
theme: {
extend: {},
},
plugins: [],
}

11
templates/assets/dist/main.iife.js vendored Normal file

File diff suppressed because one or more lines are too long

1
templates/assets/dist/style.css vendored Normal file

File diff suppressed because one or more lines are too long

View File

@@ -1,19 +1,67 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Halo</title>
<link
rel="stylesheet"
th:href="@{/assets/dist/style.css}"
href="./assets/dist/style.css"
/>
</head>
<body>
<span class="flex items-center justify-center font-serif text-red-600">
Halo
</span>
</body>
<html
xmlns:th="https://www.thymeleaf.org"
th:replace="modules/layout :: html(~{::content})"
>
<th:block th:fragment="content">
<div
id="filters"
class="flex gap-x-2 overflow-x-auto overflow-y-hidden scroll-smooth"
>
<div
class="flex cursor-pointer items-center rounded bg-gray-100 px-2 py-1 font-semibold text-gray-900 transition-all hover:shadow-sm"
>
<div class="flex flex-1 items-center truncate">
<span class="truncate text-base"> 全部 </span>
</div>
</div>
<th:block th:with="categories = ${categoryFinder.listAll()}">
<div
th:each="category : ${categories}"
class="flex cursor-pointer items-center rounded px-2 py-1 font-semibold text-gray-500 transition-all hover:bg-gray-100 hover:text-gray-900 hover:shadow-sm"
>
<div class="flex flex-1 items-center truncate">
<span class="truncate text-base">
<a
th:href="${category.status.permalink}"
th:text="${category.spec.displayName}"
></a>
</span>
</div>
</div>
</th:block>
</div>
<div
id="post-list"
th:with="postItems=${posts.items}"
class="mt-6 grid grid-cols-1 gap-6 md:grid-cols-2 xl:grid-cols-3"
>
<th:block th:each="post : ${postItems}">
<th:block th:replace="modules/post-card :: post-card(${post},true)" />
</th:block>
</div>
<div class="mt-6 flex items-center justify-between">
<button
class="whitespace-no-wrap group inline-flex items-center justify-center gap-1 rounded-md border border-gray-200 bg-white px-4 py-1 text-sm font-medium leading-6 text-gray-600 shadow-sm hover:bg-gray-50 focus:shadow-none focus:outline-none"
>
<span
data-icon="tabler:arrow-left"
class="iconify text-lg transition-all group-hover:-translate-x-1"
></span>
<span>上一页</span>
</button>
<span class="text-sm text-gray-900">1 / 20</span>
<button
class="whitespace-no-wrap group inline-flex items-center justify-center gap-1 rounded-md border border-gray-200 bg-white px-4 py-1 text-sm font-medium leading-6 text-gray-600 shadow-sm hover:bg-gray-50 focus:shadow-none focus:outline-none"
>
<span>下一页</span>
<span
data-icon="tabler:arrow-right"
class="iconify text-lg transition-all group-hover:translate-x-1"
></span>
</button>
</div>
</th:block>
</html>

View File

@@ -0,0 +1,35 @@
<footer class="mt-10 bg-white py-8">
<div class="container mx-auto sm:flex sm:items-center sm:justify-between">
<a
href="https://halo.run/"
class="mb-4 flex items-center justify-center sm:mb-0 sm:justify-start"
>
<img src="https://halo.run/logo" class="mr-3 h-8" alt="Halo Logo" />
<span class="self-center whitespace-nowrap text-2xl font-semibold">
Halo
</span>
</a>
<ul
class="mb-6 flex flex-wrap items-center justify-center text-sm text-gray-500 sm:mb-0 sm:justify-start"
>
<li>
<a href="#" class="mr-4 hover:underline md:mr-6">首页</a>
</li>
<li>
<a href="#" class="mr-4 hover:underline md:mr-6">关于</a>
</li>
<li>
<a href="#" class="mr-4 hover:underline md:mr-6">订阅</a>
</li>
<li>
<a href="#" class="hover:underline">联系</a>
</li>
</ul>
</div>
<hr class="my-6 border-gray-100 sm:mx-auto lg:my-8" />
<span class="container mx-auto block text-center text-sm text-gray-500">
© 2022
<a href="https://halo.run" class="hover:underline">Halo</a>. All Rights
Reserved.
</span>
</footer>

View File

@@ -0,0 +1,59 @@
<header>
<div class="h-96 bg-gradient-to-r from-cyan-500 to-blue-500">
<div id="header-menu" class="flex h-14 py-3 transition-all">
<div class="container mx-auto flex justify-between">
<div class="flex items-center gap-6">
<div>
<img
src="https://halo.run/upload/2022/03/logo.svg"
class="h-14 w-14"
/>
</div>
<ul class="flex items-center gap-6 text-white">
<li
class="cursor-pointer opacity-100 transition-all hover:opacity-100"
>
<RouterLink :to="{ name: 'Home' }">首页</RouterLink>
</li>
<li
class="cursor-pointer opacity-80 transition-all hover:opacity-100"
>
默认分类
</li>
<li
class="cursor-pointer opacity-80 transition-all hover:opacity-100"
>
Halo
</li>
<li
class="cursor-pointer opacity-80 transition-all hover:opacity-100"
>
<RouterLink :to="{ name: 'Links' }">链接</RouterLink>
</li>
<li
class="cursor-pointer opacity-80 transition-all hover:opacity-100"
>
关于
</li>
</ul>
</div>
<div class="flex items-center">
<ul class="flex items-center gap-4">
<li>
<span
data-icon="tabler:brightness-2"
class="iconify text-lg text-white"
></span>
</li>
<li>
<span
data-icon="tabler:search"
class="iconify text-lg text-white"
></span>
</li>
</ul>
</div>
</div>
</div>
</div>
</header>

View File

@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en" th:fragment="html (content)">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no"
/>
<title th:text="${site.title}"></title>
<link
rel="stylesheet"
th:href="@{/assets/dist/style.css}"
href="./assets/dist/style.css"
/>
<script th:src="@{/assets/dist/main.iife.js}"></script>
</head>
<body>
<th:block th:replace="modules/header" />
<section class="container mx-auto"></section>
<section class="container mx-auto -mt-20 grid grid-cols-4 gap-6">
<div class="col-span-4 sm:col-span-3">
<th:block th:replace="${content}" />
</div>
<th:block th:replace="modules/sidebar" />
</section>
<th:block th:replace="modules/footer" />
</body>
</html>

View File

@@ -0,0 +1,49 @@
<div
th:fragment="post-card(post,cover)"
class="group flex cursor-pointer flex-col overflow-hidden rounded-xl bg-white shadow-md ring-black transition-all duration-500 hover:-translate-y-2 hover:shadow-lg hover:ring-2"
>
<div th:if="${cover}" class="aspect-w-16 aspect-h-9">
<img
th:src="${post.spec.cover}"
th:alt="${post.spec.title}"
class="h-full w-full object-cover transition-all duration-500 group-hover:scale-110"
/>
</div>
<div class="relative flex flex-col p-4">
<div class="flex flex-wrap items-center gap-2">
<a
th:if="${#lists.size(post.categories)} gt 0"
th:href="${post.categories[0].status.permalink}"
th:title="${post.categories[0].spec.displayName}"
th:text="${post.categories[0].spec.displayName}"
class="mr-1 text-sm font-medium text-gray-800 hover:text-gray-900"
>
</a>
<a
th:each="tag : ${post.tags}"
th:href="${tag.status.permalink}"
th:title="${tag.spec.displayName}"
th:text="'#'+${tag.spec.displayName}"
class="cursor-pointer text-sm italic text-gray-600 hover:text-gray-900"
>
</a>
</div>
<h1
class="mt-2 cursor-pointer text-2xl font-medium transition-all hover:text-gray-500 hover:underline"
>
<a th:href="${post.status.permalink}" th:text="${post.spec.title}"></a>
</h1>
<p class="font-sm mt-2 font-light" th:text="${post.status.excerpt}"></p>
<div class="mt-2 flex flex-1 items-center justify-start gap-2">
<img
src="https://ryanc.cc/avatar"
class="h-8 w-8 rounded-full border drop-shadow-sm"
/>
<span
class="text-sm tabular-nums text-gray-600"
th:text="${'发布于 '+#dates.format(post.spec.publishTime,'yyyy-MM-dd')}"
>
</span>
</div>
</div>
</div>

View File

@@ -0,0 +1,410 @@
<aside class="col-span-1 hidden h-full flex-col gap-6 sm:flex">
<div
class="w-full cursor-pointer overflow-hidden rounded-xl bg-white p-3 shadow transition-all duration-500 hover:shadow-md"
>
<div class="flex flex-col items-center justify-center gap-4">
<div class="relative h-24 w-24">
<img
src="https://halo.run/logo"
class="h-full w-full rounded-full"
/><span
class="absolute right-0 bottom-0 flex h-7 w-7 items-center justify-center rounded-full border bg-white p-0.5"
>
🌚
</span>
</div>
<div><h1 class="text-2xl font-medium">Halo</h1></div>
<div>
<p class="text-center text-sm text-gray-700">
Natus eveniet et cum eum.
</p>
</div>
<div class="grid grid-cols-4 gap-5">
<div class="inline-flex flex-col items-center">
<span class="text-xl font-medium tabular-nums text-gray-900">97</span
><span class="text-xs font-light text-gray-600">文章数</span>
</div>
<div class="inline-flex flex-col items-center">
<span class="text-xl font-medium tabular-nums text-gray-900">18</span
><span class="text-xs font-light text-gray-600">分类数</span>
</div>
<div class="inline-flex flex-col items-center">
<span class="text-xl font-medium tabular-nums text-gray-900">117</span
><span class="text-xs font-light text-gray-600">评论数</span>
</div>
<div class="inline-flex flex-col items-center">
<span class="text-xl font-medium tabular-nums text-gray-900"
>92392</span
><span class="text-xs font-light text-gray-600">访问量</span>
</div>
</div>
<div class="grid grid-cols-6 items-center gap-5">
<div
class="flex cursor-pointer items-center justify-center rounded p-1 hover:bg-gray-100"
>
<span
data-icon="simple-icons:wechat"
class="iconify text-[#07C160]"
></span>
</div>
<div
class="flex cursor-pointer items-center justify-center rounded p-1 hover:bg-gray-100"
>
<span
data-icon="simple-icons:bilibili"
class="iconify text-[#00A1D6]"
></span>
</div>
<div
class="flex cursor-pointer items-center justify-center rounded p-1 hover:bg-gray-100"
>
<span
data-icon="simple-icons:github"
class="iconify text-[#181717]"
></span>
</div>
<div
class="flex cursor-pointer items-center justify-center rounded p-1 hover:bg-gray-100"
>
<span
data-icon="simple-icons:twitter"
class="iconify text-[#1DA1F2]"
></span>
</div>
<div
class="flex cursor-pointer items-center justify-center rounded p-1 hover:bg-gray-100"
>
<span
data-icon="simple-icons:telegram"
class="iconify text-[#26A5E4]"
></span>
</div>
<div
class="flex cursor-pointer items-center justify-center rounded p-1 hover:bg-gray-100"
>
<span
data-icon="simple-icons:feedly"
class="iconify text-[#2BB24C]"
></span>
</div>
</div>
</div>
</div>
<div
class="w-full cursor-pointer overflow-hidden rounded-xl bg-white p-3 shadow transition-all duration-500 hover:shadow-md"
>
<h2 class="inline-flex items-center gap-2 text-base">
<span
data-icon="tabler:stairs-up"
class="iconify text-lg text-red-600"
></span>
热门文章
</h2>
<div>
<ul role="list" class="divide-y divide-gray-100">
<li class="py-3">
<div class="flex items-center justify-between">
<div class="flex flex-col gap-1">
<h3 class="text-sm font-medium">non omnis id</h3>
<p class="text-xs text-gray-500">2022-10-01 发布</p>
</div>
<div class="inline-flex items-center gap-1 text-xs text-gray-600">
<span data-icon="tabler:eye" class="iconify"></span>
<span>5243</span>
</div>
</div>
</li>
<li class="py-3">
<div class="flex items-center justify-between">
<div class="flex flex-col gap-1">
<h3 class="text-sm font-medium">unde velit necessitatibus</h3>
<p class="text-xs text-gray-500">2022-10-01 发布</p>
</div>
<div class="inline-flex items-center gap-1 text-xs text-gray-600">
<span data-icon="tabler:eye" class="iconify"></span>
<span>5243</span>
</div>
</div>
</li>
<li class="py-3">
<div class="flex items-center justify-between">
<div class="flex flex-col gap-1">
<h3 class="text-sm font-medium">eos voluptatum velit</h3>
<p class="text-xs text-gray-500">2022-10-01 发布</p>
</div>
<div class="inline-flex items-center gap-1 text-xs text-gray-600">
<span data-icon="tabler:eye" class="iconify"></span>
<span>5243</span>
</div>
</div>
</li>
<li class="py-3">
<div class="flex items-center justify-between">
<div class="flex flex-col gap-1">
<h3 class="text-sm font-medium">culpa nam exercitationem</h3>
<p class="text-xs text-gray-500">2022-10-01 发布</p>
</div>
<div class="inline-flex items-center gap-1 text-xs text-gray-600">
<span data-icon="tabler:eye" class="iconify"></span>
<span>5243</span>
</div>
</div>
</li>
<li class="py-3">
<div class="flex items-center justify-between">
<div class="flex flex-col gap-1">
<h3 class="text-sm font-medium">est optio facere</h3>
<p class="text-xs text-gray-500">2022-10-01 发布</p>
</div>
<div class="inline-flex items-center gap-1 text-xs text-gray-600">
<span data-icon="tabler:eye" class="iconify"></span>
<span>5243</span>
</div>
</div>
</li>
</ul>
</div>
</div>
<div
class="w-full cursor-pointer overflow-hidden rounded-xl bg-white p-3 shadow transition-all duration-500 hover:shadow-md"
>
<h2 class="inline-flex items-center gap-2 text-base">
<span data-icon="tabler:message-circle" class="iconify text-lg"></span>
最新评论
</h2>
<div>
<ul role="list" class="divide-y divide-gray-100">
<li class="py-3">
<div class="flex space-x-3">
<img
class="h-6 w-6 rounded-full"
src="https://loremflickr.com/640/480/cats"
alt=""
/>
<div class="flex-1 space-y-1">
<div class="flex items-center justify-between">
<h3 class="text-sm font-medium">Phyllis McKenzie</h3>
<p class="text-sm text-gray-500">1h</p>
</div>
<p class="text-sm text-gray-500">
Fugit quae nam dolores impedit quia fuga pariatur dignissimos
recusandae.
</p>
</div>
</div>
</li>
<li class="py-3">
<div class="flex space-x-3">
<img
class="h-6 w-6 rounded-full"
src="https://loremflickr.com/640/480/cats"
alt=""
/>
<div class="flex-1 space-y-1">
<div class="flex items-center justify-between">
<h3 class="text-sm font-medium">Willard Labadie I</h3>
<p class="text-sm text-gray-500">1h</p>
</div>
<p class="text-sm text-gray-500">
Officiis quis quos repudiandae quam delectus impedit quidem amet
ut.
</p>
</div>
</div>
</li>
<li class="py-3">
<div class="flex space-x-3">
<img
class="h-6 w-6 rounded-full"
src="https://loremflickr.com/640/480/cats"
alt=""
/>
<div class="flex-1 space-y-1">
<div class="flex items-center justify-between">
<h3 class="text-sm font-medium">Miss Leonard Sporer</h3>
<p class="text-sm text-gray-500">1h</p>
</div>
<p class="text-sm text-gray-500">Nesciunt dolores et debitis.</p>
</div>
</div>
</li>
<li class="py-3">
<div class="flex space-x-3">
<img
class="h-6 w-6 rounded-full"
src="https://loremflickr.com/640/480/cats"
alt=""
/>
<div class="flex-1 space-y-1">
<div class="flex items-center justify-between">
<h3 class="text-sm font-medium">Tyrone Fisher</h3>
<p class="text-sm text-gray-500">1h</p>
</div>
<p class="text-sm text-gray-500">
Et nesciunt dolorem eum ut corporis.
</p>
</div>
</div>
</li>
<li class="py-3">
<div class="flex space-x-3">
<img
class="h-6 w-6 rounded-full"
src="https://loremflickr.com/640/480/cats"
alt=""
/>
<div class="flex-1 space-y-1">
<div class="flex items-center justify-between">
<h3 class="text-sm font-medium">Angie Braun V</h3>
<p class="text-sm text-gray-500">1h</p>
</div>
<p class="text-sm text-gray-500">
Autem labore ipsam earum reiciendis eum omnis.
</p>
</div>
</div>
</li>
</ul>
</div>
</div>
<div
class="w-full cursor-pointer overflow-hidden rounded-xl bg-white p-3 shadow transition-all duration-500 hover:shadow-md"
>
<h2 class="inline-flex items-center gap-2 text-base">
<span data-icon="tabler:category" class="iconify text-lg"></span>
分类目录
</h2>
<div class="mt-2">
<ul class="space-y-1">
<li>
<a
href="#"
class="group flex items-center justify-between rounded py-1 px-1.5 transition-all hover:bg-gray-100"
><span class="text-sm opacity-80">Halo</span
><span
class="rounded bg-gray-100 py-0.5 px-1 text-xs opacity-70 group-hover:bg-white"
>
20
</span></a
>
</li>
<li>
<a
href="#"
class="group flex items-center justify-between rounded py-1 px-1.5 transition-all hover:bg-gray-100"
><span class="text-sm opacity-80">MeterSphere</span
><span
class="rounded bg-gray-100 py-0.5 px-1 text-xs opacity-70 group-hover:bg-white"
>
21
</span></a
>
</li>
<li>
<a
href="#"
class="group flex items-center justify-between rounded py-1 px-1.5 transition-all hover:bg-gray-100"
><span class="text-sm opacity-80">DataEase</span
><span
class="rounded bg-gray-100 py-0.5 px-1 text-xs opacity-70 group-hover:bg-white"
>
22
</span></a
>
</li>
<li>
<a
href="#"
class="group flex items-center justify-between rounded py-1 px-1.5 transition-all hover:bg-gray-100"
><span class="text-sm opacity-80">assumenda</span
><span
class="rounded bg-gray-100 py-0.5 px-1 text-xs opacity-70 group-hover:bg-white"
>
20
</span></a
>
<ul class="my-3 ml-3 space-y-1 border-l pl-2">
<li>
<a
href="#"
class="group flex items-center justify-between rounded py-1 px-1.5 transition-all hover:bg-gray-100"
><span class="text-sm opacity-80">minima</span
><span
class="rounded bg-gray-100 py-0.5 px-1 text-xs opacity-70 group-hover:bg-white"
>14</span
></a
>
</li>
<li>
<a
href="#"
class="group flex items-center justify-between rounded py-1 px-1.5 transition-all hover:bg-gray-100"
><span class="text-sm opacity-80">minima</span
><span
class="rounded bg-gray-100 py-0.5 px-1 text-xs opacity-70 group-hover:bg-white"
>18</span
></a
>
</li>
<li>
<a
href="#"
class="group flex items-center justify-between rounded py-1 px-1.5 transition-all hover:bg-gray-100"
><span class="text-sm opacity-80">hic</span
><span
class="rounded bg-gray-100 py-0.5 px-1 text-xs opacity-70 group-hover:bg-white"
>9</span
></a
>
</li>
<li>
<a
href="#"
class="group flex items-center justify-between rounded py-1 px-1.5 transition-all hover:bg-gray-100"
><span class="text-sm opacity-80">mollitia</span
><span
class="rounded bg-gray-100 py-0.5 px-1 text-xs opacity-70 group-hover:bg-white"
>14</span
></a
>
</li>
<li>
<a
href="#"
class="group flex items-center justify-between rounded py-1 px-1.5 transition-all hover:bg-gray-100"
><span class="text-sm opacity-80">facere</span
><span
class="rounded bg-gray-100 py-0.5 px-1 text-xs opacity-70 group-hover:bg-white"
>7</span
></a
>
</li>
</ul>
</li>
</ul>
</div>
</div>
<div
class="w-full cursor-pointer overflow-hidden rounded-xl bg-white p-3 shadow transition-all duration-500 hover:shadow-md"
>
<h2 class="inline-flex items-center gap-2 text-base">
<span data-icon="tabler:tags" class="iconify text-lg"></span>
标签
</h2>
<div
class="mt-2 flex flex-wrap gap-2"
th:with="tags = ${tagFinder.listAll()}"
>
<a
th:each="tag : ${tags}"
th:href="${tag.status.permalink}"
th:title="${tag.spec.displayName}"
class="rounded bg-gray-100 px-1 py-0.5 text-sm text-gray-900 hover:bg-gray-200"
href="#"
>
<th:block th:text="'#'+${tag.spec.displayName}" />
<sup th:text="${tag.status.postCount}"></sup>
</a>
</div>
</div>
</aside>

73
templates/post.html Normal file
View File

@@ -0,0 +1,73 @@
<!DOCTYPE html>
<html
xmlns:th="https://www.thymeleaf.org"
th:replace="modules/layout :: html(~{::content})"
>
<th:block th:fragment="content">
<div class="rounded-xl bg-white p-4">
<div class="flex items-center justify-between">
<div class="inline-flex items-center justify-start gap-2">
<img src="https://ryanc.cc/avatar" class="h-10 w-10 rounded-full" />
<div class="flex flex-col gap-0.5">
<span class="text-sm font-semibold text-gray-900">Ryan Wang</span>
<div
class="flex items-center gap-2 text-xs font-light text-gray-600"
>
<span
th:text="${'发布于 '+#dates.format(post.spec.publishTime,'yyyy-MM-dd')}"
></span>
<span class="text-gray-300">/</span>
<span th:text="${post.stats.visit}+' 阅读'"></span>
<span class="text-gray-300">/</span>
<span th:text="${post.stats.comment}+ ' 评论'"> </span>
<span class="text-gray-300">/</span>
<span th:text="${post.stats.upvote}+' 点赞'"> </span>
</div>
</div>
</div>
<div class="inline-flex flex-row gap-1">
<div class="cursor-pointer rounded-lg p-1 hover:bg-gray-100">
<span
data-icon="tabler:heart"
class="iconify text-lg text-gray-600 hover:text-red-600"
></span>
</div>
<div class="cursor-pointer rounded-lg p-1 hover:bg-gray-100">
<span
data-icon="tabler:message-circle"
class="iconify text-lg text-gray-600 hover:text-gray-900"
></span>
</div>
<div class="cursor-pointer rounded-lg p-1 hover:bg-gray-100">
<span
data-icon="tabler:share"
class="iconify text-lg text-gray-600 hover:text-blue-600"
></span>
</div>
</div>
</div>
<h1 class="my-3 text-2xl font-medium" th:text="${post.spec.title}"></h1>
<div>
<a
th:each="tag : ${post.tags}"
th:href="${tag.status.permalink}"
th:title="${tag.spec.displayName}"
th:text="'#'+${tag.spec.displayName}"
class="cursor-pointer text-sm italic text-gray-600 hover:text-gray-900"
>
</a>
</div>
<article
class="prose prose-base mt-4 !max-w-none"
th:utext="${post.content.content}"
></article>
<hr class="my-10" />
<h2 class="mb-2 text-base font-medium text-gray-900">评论</h2>
<halo:comment
group="content.halo.run"
kind="Post"
th:attr="name=${post.metadata.name}"
/>
</div>
</th:block>
</html>

View File

@@ -1,8 +1,10 @@
import { defineConfig } from "vite";
import { fileURLToPath } from "url";
import path from "path";
import PurgeIcons from "vite-plugin-purge-icons";
export default defineConfig({
plugins: [PurgeIcons()],
build: {
outDir: fileURLToPath(new URL("./templates/assets/dist", import.meta.url)),
emptyOutDir: true,