diff --git a/frontend/next.config.ts b/frontend/next.config.ts
index 6ed685e..7883785 100644
--- a/frontend/next.config.ts
+++ b/frontend/next.config.ts
@@ -8,6 +8,15 @@ const nextConfig: NextConfig = {
env: {
APP_VERSION: process.env.npm_package_version,
},
+
+ images: {
+ remotePatterns: [
+ {
+ protocol: "https",
+ hostname: "*",
+ },
+ ],
+ },
};
export default nextConfig;
diff --git a/frontend/src/app/post/page.tsx b/frontend/src/app/post/page.tsx
new file mode 100644
index 0000000..5dae52a
--- /dev/null
+++ b/frontend/src/app/post/page.tsx
@@ -0,0 +1,11 @@
+import PostOverallTitle from "@/lib/post/framework/ui/PostOverallTitle";
+import PostPreviewCardList from "@/lib/post/framework/ui/PostPreviewCardList";
+
+export default function PostOverallPage() {
+ return (
+
+ );
+}
diff --git a/frontend/src/lib/label/domain/labelEntity.ts b/frontend/src/lib/label/domain/labelEntity.ts
new file mode 100644
index 0000000..4afff25
--- /dev/null
+++ b/frontend/src/lib/label/domain/labelEntity.ts
@@ -0,0 +1,7 @@
+export default class LabelEntity {
+ constructor(
+ public readonly id: number,
+ public readonly name: string,
+ public readonly color: string,
+ ) {}
+}
diff --git a/frontend/src/lib/label/framework/ui/CompactLabel.tsx b/frontend/src/lib/label/framework/ui/CompactLabel.tsx
new file mode 100644
index 0000000..c83bb8d
--- /dev/null
+++ b/frontend/src/lib/label/framework/ui/CompactLabel.tsx
@@ -0,0 +1,16 @@
+import LabelEntity from "@/lib/label/domain/labelEntity";
+
+export default function CompactLabel({ labels }: { labels: LabelEntity[] }) {
+ function generateTitle(labels: LabelEntity[]): string {
+ return labels.map((e) => e.name).join("\n");
+ }
+
+ return (
+
+ {`${labels.length}+`}
+
+ );
+}
diff --git a/frontend/src/lib/label/framework/ui/Label.tsx b/frontend/src/lib/label/framework/ui/Label.tsx
new file mode 100644
index 0000000..6946e52
--- /dev/null
+++ b/frontend/src/lib/label/framework/ui/Label.tsx
@@ -0,0 +1,13 @@
+import LabelEntity from "@/lib/label/domain/labelEntity";
+
+export default function Label({ label }: { label: LabelEntity }) {
+ return (
+
+ );
+}
diff --git a/frontend/src/lib/post/domain/postEntity.ts b/frontend/src/lib/post/domain/postEntity.ts
new file mode 100644
index 0000000..f0c4d75
--- /dev/null
+++ b/frontend/src/lib/post/domain/postEntity.ts
@@ -0,0 +1,13 @@
+import LabelEntity from "@/lib/label/domain/labelEntity";
+
+export default class PostEntity {
+ constructor(
+ public id: number,
+ public title: string,
+ public content: string,
+ public description: string,
+ public previewImageUrl: string,
+ public labels: LabelEntity[],
+ public publishedTime: Date,
+ ) {}
+}
diff --git a/frontend/src/lib/post/framework/ui/PostOverallTitle.tsx b/frontend/src/lib/post/framework/ui/PostOverallTitle.tsx
new file mode 100644
index 0000000..f9b0d69
--- /dev/null
+++ b/frontend/src/lib/post/framework/ui/PostOverallTitle.tsx
@@ -0,0 +1,7 @@
+export default function PostOverallTitle() {
+ return (
+
+
文章
+
+ );
+}
diff --git a/frontend/src/lib/post/framework/ui/PostPreviewCard.tsx b/frontend/src/lib/post/framework/ui/PostPreviewCard.tsx
new file mode 100644
index 0000000..e86a51e
--- /dev/null
+++ b/frontend/src/lib/post/framework/ui/PostPreviewCard.tsx
@@ -0,0 +1,23 @@
+import Image from "next/image";
+
+import CompactLabel from "@/lib/label/framework/ui/CompactLabel";
+import Label from "@/lib/label/framework/ui/Label";
+
+import PostEntity from "../../domain/postEntity";
+
+export default function PostPreviewCard({ post }: { post: PostEntity }) {
+ return (
+
+
+
+
+ {post.labels.length > 0 && }
+ {post.labels.length > 1 && }
+
+
{post.title}
+
{post.description}
+
查看更多 →
+
+
+ );
+}
diff --git a/frontend/src/lib/post/framework/ui/PostPreviewCardList.tsx b/frontend/src/lib/post/framework/ui/PostPreviewCardList.tsx
new file mode 100644
index 0000000..171235e
--- /dev/null
+++ b/frontend/src/lib/post/framework/ui/PostPreviewCardList.tsx
@@ -0,0 +1,73 @@
+import PostEntity from "../../domain/postEntity";
+import PostPreviewCard from "./PostPreviewCard";
+
+export default function PostPreviewCardList() {
+ return (
+
+ {postList.map((post) => (
+
+ ))}
+
+ );
+}
+
+const postList: PostEntity[] = [
+ {
+ id: 1,
+ title: "SquidLIVE | 自己的網站自己寫 | 深夜開發台",
+ content: "SquidLIVE 是一個自己的網站自己寫的深夜開發台,這裡會分享一些技術文章、開發心得、以及一些生活感想。",
+ description:
+ "Git Repository: https://git.squidspirit.com/squid/blog 如果喜歡的話就按個大大的喜歡,順便分享出去;如果不喜歡的話也別吝嗇按個不喜歡,也要告訴我原因喔!如有任何問題歡迎在下方留言或寄 E-mail 至:squid@squidspirit.com",
+ previewImageUrl: "https://www.alleycat.org/wp-content/uploads/2019/03/FELV-cat.jpg",
+ labels: [
+ {
+ id: 1,
+ name: "Software Engineering",
+ color: "#D9D9D9",
+ },
+ {
+ id: 2,
+ name: "Algorithm",
+ color: "#D9D9D9",
+ },
+ {
+ id: 3,
+ name: "Frontend",
+ color: "#D9D9D9",
+ },
+ ],
+ publishedTime: new Date(),
+ },
+ {
+ id: 2,
+ title: "SquidLIVE | 自己的網站自己寫 | 深夜開發台",
+ content: "SquidLIVE 是一個自己的網站自己寫的深夜開發台,這裡會分享一些技術文章、開發心得、以及一些生活感想。",
+ description:
+ "Git Repository: https://git.squidspirit.com/squid/blog 如果喜歡的話就按個大大的喜歡,順便分享出去;如果不喜歡的話也別吝嗇按個不喜歡,也要告訴我原因喔!如有任何問題歡迎在下方留言或寄 E-mail 至:squid@squidspirit.com",
+ previewImageUrl: "https://www.alleycat.org/wp-content/uploads/2019/03/FELV-cat.jpg",
+ labels: [
+ {
+ id: 1,
+ name: "Software Engineering",
+ color: "#D9D9D9",
+ },
+ ],
+ publishedTime: new Date(),
+ },
+ {
+ id: 3,
+ title: "SquidLIVE | 自己的網站自己寫 | 深夜開發台",
+ content: "SquidLIVE 是一個自己的網站自己寫的深夜開發台,這裡會分享一些技術文章、開發心得、以及一些生活感想。",
+ description:
+ "Git Repository: https://git.squidspirit.com/squid/blog 如果喜歡的話就按個大大的喜歡,順便分享出去;如果不喜歡的話也別吝嗇按個不喜歡,也要告訴我原因喔!如有任何問題歡迎在下方留言或寄 E-mail 至:squid@squidspirit.com",
+ previewImageUrl: "https://www.alleycat.org/wp-content/uploads/2019/03/FELV-cat.jpg",
+ labels: [
+ {
+ id: 1,
+ name: "Software Engineering",
+ color: "#D9D9D9",
+ },
+ ],
+ publishedTime: new Date(),
+ },
+];