diff --git a/frontend/src/ui/layout/navbar.tsx b/frontend/src/ui/layout/navbar.tsx
index 040610c..145b4aa 100644
--- a/frontend/src/ui/layout/navbar.tsx
+++ b/frontend/src/ui/layout/navbar.tsx
@@ -1,8 +1,6 @@
import React from "react";
-type Props = {};
-
-export default function Navbar({}: Props) {
+export default function Navbar() {
return (
--
2.47.1
From 7f1a202cc7c6e4f44a3cf5678f8f83ceb425034e Mon Sep 17 00:00:00 2001
From: SquidSpirit
Date: Sat, 18 Jan 2025 03:01:11 +0800
Subject: [PATCH 4/6] BLOG-5 feat: self tags animation
---
frontend/next.config.ts | 2 +-
frontend/package.json | 4 +-
frontend/pnpm-lock.yaml | 86 +++++++++++++++++++
frontend/src/app/layout.tsx | 14 +--
frontend/src/app/page.tsx | 26 +-----
.../common/presenter/ui/Footer.tsx} | 1 -
.../common/presenter/ui/Navbar.tsx} | 2 -
.../src/lib/home/presenter/redux/tagHooks.ts | 6 ++
.../src/lib/home/presenter/redux/tagSlice.ts | 72 ++++++++++++++++
.../src/lib/home/presenter/redux/tagStore.ts | 10 +++
.../src/lib/home/presenter/ui/SelfTags.tsx | 55 ++++++++++++
frontend/src/lib/util/shuffleArray.ts | 8 ++
frontend/tailwind.config.ts | 2 +-
13 files changed, 251 insertions(+), 37 deletions(-)
rename frontend/src/{ui/layout/footer.tsx => lib/common/presenter/ui/Footer.tsx} (97%)
rename frontend/src/{ui/layout/navbar.tsx => lib/common/presenter/ui/Navbar.tsx} (96%)
create mode 100644 frontend/src/lib/home/presenter/redux/tagHooks.ts
create mode 100644 frontend/src/lib/home/presenter/redux/tagSlice.ts
create mode 100644 frontend/src/lib/home/presenter/redux/tagStore.ts
create mode 100644 frontend/src/lib/home/presenter/ui/SelfTags.tsx
create mode 100644 frontend/src/lib/util/shuffleArray.ts
diff --git a/frontend/next.config.ts b/frontend/next.config.ts
index e9ffa30..9ab38a3 100644
--- a/frontend/next.config.ts
+++ b/frontend/next.config.ts
@@ -1,7 +1,7 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
- /* config options here */
+ reactStrictMode: false,
};
export default nextConfig;
diff --git a/frontend/package.json b/frontend/package.json
index 722ae0b..060b633 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -15,9 +15,11 @@
"@fortawesome/free-regular-svg-icons": "^6.7.2",
"@fortawesome/free-solid-svg-icons": "^6.7.2",
"@fortawesome/react-fontawesome": "^0.2.2",
+ "@reduxjs/toolkit": "^2.5.0",
"next": "15.1.4",
"react": "^19.0.0",
- "react-dom": "^19.0.0"
+ "react-dom": "^19.0.0",
+ "react-redux": "^9.2.0"
},
"devDependencies": {
"@eslint/eslintrc": "^3.2.0",
diff --git a/frontend/pnpm-lock.yaml b/frontend/pnpm-lock.yaml
index 7a17382..d3648f3 100644
--- a/frontend/pnpm-lock.yaml
+++ b/frontend/pnpm-lock.yaml
@@ -23,6 +23,9 @@ importers:
'@fortawesome/react-fontawesome':
specifier: ^0.2.2
version: 0.2.2(@fortawesome/fontawesome-svg-core@6.7.2)(react@19.0.0)
+ '@reduxjs/toolkit':
+ specifier: ^2.5.0
+ version: 2.5.0(react-redux@9.2.0(@types/react@19.0.7)(react@19.0.0)(redux@5.0.1))(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)
@@ -32,6 +35,9 @@ importers:
react-dom:
specifier: ^19.0.0
version: 19.0.0(react@19.0.0)
+ react-redux:
+ specifier: ^9.2.0
+ version: 9.2.0(@types/react@19.0.7)(react@19.0.0)(redux@5.0.1)
devDependencies:
'@eslint/eslintrc':
specifier: ^3.2.0
@@ -357,6 +363,17 @@ packages:
resolution: {integrity: sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==}
engines: {node: '>=14'}
+ '@reduxjs/toolkit@2.5.0':
+ resolution: {integrity: sha512-awNe2oTodsZ6LmRqmkFhtb/KH03hUhxOamEQy411m3Njj3BbFvoBovxo4Q1cBWnV1ErprVj9MlF0UPXkng0eyg==}
+ peerDependencies:
+ react: ^16.9.0 || ^17.0.0 || ^18 || ^19
+ react-redux: ^7.2.1 || ^8.1.3 || ^9.0.0
+ peerDependenciesMeta:
+ react:
+ optional: true
+ react-redux:
+ optional: true
+
'@rtsao/scc@1.1.0':
resolution: {integrity: sha512-zt6OdqaDoOnJ1ZYsCYGt9YmWzDXl4vQdKTyJev62gFhRGKdx7mcT54V9KIjg+d2wi9EXsPvAPKe7i7WjfVWB8g==}
@@ -389,6 +406,9 @@ packages:
'@types/react@19.0.7':
resolution: {integrity: sha512-MoFsEJKkAtZCrC1r6CM8U22GzhG7u2Wir8ons/aCKH6MBdD1ibV24zOSSkdZVUKqN5i396zG5VKLYZ3yaUZdLA==}
+ '@types/use-sync-external-store@0.0.6':
+ resolution: {integrity: sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==}
+
'@typescript-eslint/eslint-plugin@8.20.0':
resolution: {integrity: sha512-naduuphVw5StFfqp4Gq4WhIBE2gN1GEmMUExpJYknZJdRnc+2gDzB8Z3+5+/Kv33hPQRDGzQO/0opHE72lZZ6A==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
@@ -979,6 +999,9 @@ packages:
resolution: {integrity: sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==}
engines: {node: '>= 4'}
+ immer@10.1.1:
+ resolution: {integrity: sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==}
+
import-fresh@3.3.0:
resolution: {integrity: sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==}
engines: {node: '>=6'}
@@ -1462,6 +1485,18 @@ packages:
react-is@16.13.1:
resolution: {integrity: sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==}
+ react-redux@9.2.0:
+ resolution: {integrity: sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==}
+ peerDependencies:
+ '@types/react': ^18.2.25 || ^19
+ react: ^18.0 || ^19
+ redux: ^5.0.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ redux:
+ optional: true
+
react@19.0.0:
resolution: {integrity: sha512-V8AVnmPIICiWpGfm6GLzCR/W5FXLchHop40W4nXBmdlEceh16rCN8O8LNWm5bh5XUX91fh7KpA+W0TgMKmgTpQ==}
engines: {node: '>=0.10.0'}
@@ -1473,6 +1508,14 @@ packages:
resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
engines: {node: '>=8.10.0'}
+ redux-thunk@3.1.0:
+ resolution: {integrity: sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==}
+ peerDependencies:
+ redux: ^5.0.0
+
+ redux@5.0.1:
+ resolution: {integrity: sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==}
+
reflect.getprototypeof@1.0.10:
resolution: {integrity: sha512-00o4I+DVrefhv+nX0ulyi3biSHCPDe+yLv5o/p6d/UVlirijB8E16FtfwSAi4g3tcqrQ4lRAqQSoFEZJehYEcw==}
engines: {node: '>= 0.4'}
@@ -1481,6 +1524,9 @@ packages:
resolution: {integrity: sha512-dYqgNSZbDwkaJ2ceRd9ojCGjBq+mOm9LmtXnAnEGyHhN/5R7iDW2TRw3h+o/jCFxus3P2LfWIIiwowAjANm7IA==}
engines: {node: '>= 0.4'}
+ reselect@5.1.1:
+ resolution: {integrity: sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==}
+
resolve-from@4.0.0:
resolution: {integrity: sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==}
engines: {node: '>=4'}
@@ -1729,6 +1775,11 @@ packages:
uri-js@4.4.1:
resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==}
+ use-sync-external-store@1.4.0:
+ resolution: {integrity: sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==}
+ peerDependencies:
+ react: ^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0
+
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
@@ -2010,6 +2061,16 @@ snapshots:
'@pkgjs/parseargs@0.11.0':
optional: true
+ '@reduxjs/toolkit@2.5.0(react-redux@9.2.0(@types/react@19.0.7)(react@19.0.0)(redux@5.0.1))(react@19.0.0)':
+ dependencies:
+ immer: 10.1.1
+ redux: 5.0.1
+ redux-thunk: 3.1.0(redux@5.0.1)
+ reselect: 5.1.1
+ optionalDependencies:
+ react: 19.0.0
+ react-redux: 9.2.0(@types/react@19.0.7)(react@19.0.0)(redux@5.0.1)
+
'@rtsao/scc@1.1.0': {}
'@rushstack/eslint-patch@1.10.5': {}
@@ -2038,6 +2099,8 @@ snapshots:
dependencies:
csstype: 3.1.3
+ '@types/use-sync-external-store@0.0.6': {}
+
'@typescript-eslint/eslint-plugin@8.20.0(@typescript-eslint/parser@8.20.0(eslint@9.18.0(jiti@1.21.7))(typescript@5.7.3))(eslint@9.18.0(jiti@1.21.7))(typescript@5.7.3)':
dependencies:
'@eslint-community/regexpp': 4.12.1
@@ -2840,6 +2903,8 @@ snapshots:
ignore@5.3.2: {}
+ immer@10.1.1: {}
+
import-fresh@3.3.0:
dependencies:
parent-module: 1.0.1
@@ -3266,6 +3331,15 @@ snapshots:
react-is@16.13.1: {}
+ react-redux@9.2.0(@types/react@19.0.7)(react@19.0.0)(redux@5.0.1):
+ dependencies:
+ '@types/use-sync-external-store': 0.0.6
+ react: 19.0.0
+ use-sync-external-store: 1.4.0(react@19.0.0)
+ optionalDependencies:
+ '@types/react': 19.0.7
+ redux: 5.0.1
+
react@19.0.0: {}
read-cache@1.0.0:
@@ -3276,6 +3350,12 @@ snapshots:
dependencies:
picomatch: 2.3.1
+ redux-thunk@3.1.0(redux@5.0.1):
+ dependencies:
+ redux: 5.0.1
+
+ redux@5.0.1: {}
+
reflect.getprototypeof@1.0.10:
dependencies:
call-bind: 1.0.8
@@ -3296,6 +3376,8 @@ snapshots:
gopd: 1.2.0
set-function-name: 2.0.2
+ reselect@5.1.1: {}
+
resolve-from@4.0.0: {}
resolve-pkg-maps@1.0.0: {}
@@ -3642,6 +3724,10 @@ snapshots:
dependencies:
punycode: 2.3.1
+ use-sync-external-store@1.4.0(react@19.0.0):
+ dependencies:
+ react: 19.0.0
+
util-deprecate@1.0.2: {}
which-boxed-primitive@1.1.1:
diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx
index e0721fe..d1c1cb2 100644
--- a/frontend/src/app/layout.tsx
+++ b/frontend/src/app/layout.tsx
@@ -1,8 +1,8 @@
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
-import Navbar from "@/ui/layout/navbar";
-import Footer from "@/ui/layout/footer";
+import Navbar from "@/lib/common/presenter/ui/Navbar";
+import Footer from "@/lib/common/presenter/ui/Footer";
const inter = Inter({
subsets: ["latin"],
@@ -21,11 +21,11 @@ export default function RootLayout({
return (
-
-
- {children}
-
-
+
+
+ {children}
+
+
);
diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx
index 81dae41..3c02804 100644
--- a/frontend/src/app/page.tsx
+++ b/frontend/src/app/page.tsx
@@ -1,4 +1,4 @@
-import React from "react";
+import SelfTags from "@/lib/home/presenter/ui/SelfTags";
export default function HomePage() {
return (
@@ -13,29 +13,7 @@ export default function HomePage() {
魷魚
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
);
}
-
-function Hashtag(props: { tag: string }) {
- return
# {props.tag};
-}
diff --git a/frontend/src/ui/layout/footer.tsx b/frontend/src/lib/common/presenter/ui/Footer.tsx
similarity index 97%
rename from frontend/src/ui/layout/footer.tsx
rename to frontend/src/lib/common/presenter/ui/Footer.tsx
index 7ed636f..8386ec7 100644
--- a/frontend/src/ui/layout/footer.tsx
+++ b/frontend/src/lib/common/presenter/ui/Footer.tsx
@@ -1,7 +1,6 @@
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";
export default function Footer() {
return (
diff --git a/frontend/src/ui/layout/navbar.tsx b/frontend/src/lib/common/presenter/ui/Navbar.tsx
similarity index 96%
rename from frontend/src/ui/layout/navbar.tsx
rename to frontend/src/lib/common/presenter/ui/Navbar.tsx
index 145b4aa..1270cac 100644
--- a/frontend/src/ui/layout/navbar.tsx
+++ b/frontend/src/lib/common/presenter/ui/Navbar.tsx
@@ -1,5 +1,3 @@
-import React from "react";
-
export default function Navbar() {
return (
diff --git a/frontend/src/lib/home/presenter/redux/tagHooks.ts b/frontend/src/lib/home/presenter/redux/tagHooks.ts
new file mode 100644
index 0000000..a4c799f
--- /dev/null
+++ b/frontend/src/lib/home/presenter/redux/tagHooks.ts
@@ -0,0 +1,6 @@
+import { useDispatch, useSelector } from "react-redux";
+import tagStore from "./tagStore";
+
+export const useTagDispatch = useDispatch.withTypes
();
+export const useTagSelector =
+ useSelector.withTypes>();
diff --git a/frontend/src/lib/home/presenter/redux/tagSlice.ts b/frontend/src/lib/home/presenter/redux/tagSlice.ts
new file mode 100644
index 0000000..67f05ac
--- /dev/null
+++ b/frontend/src/lib/home/presenter/redux/tagSlice.ts
@@ -0,0 +1,72 @@
+import { createSlice, PayloadAction } from "@reduxjs/toolkit";
+import tagStore from "./tagStore";
+import shuffleArray from "@/lib/util/shuffleArray";
+
+export interface TagState {
+ tags: string[];
+ timer?: NodeJS.Timeout;
+}
+
+export interface TagStartedActionPayload {
+ interval: number;
+}
+
+export const tagSlice = createSlice({
+ name: "tag",
+ initialState: {
+ tags: [],
+ timer: undefined,
+ } as TagState,
+ reducers: {
+ started: (state, action: PayloadAction) => {
+ state.tags = shuffleArray(tagsCollection);
+ state.timer = setInterval(() => {
+ tagStore.dispatch(tagSlice.actions.shuffled());
+ }, action.payload.interval);
+ },
+ shuffled: (state) => {
+ state.tags = shuffleArray(tagsCollection);
+ },
+ stopped: (state) => {
+ clearInterval(state.timer);
+ state.timer = undefined;
+ },
+ },
+});
+
+export const tagStartedAction = tagSlice.actions.started;
+export const tagStoppedAction = tagSlice.actions.stopped;
+
+const tagReducer = tagSlice.reducer;
+export default tagReducer;
+
+const tagsCollection = [
+ "APP",
+ "C++",
+ "Design Pattern",
+ "Docker",
+ "Flutter",
+ "Go",
+ "Java",
+ "LINER",
+ "Linux",
+ "Python",
+ "Squid",
+ "TypeScript",
+ "中央大學",
+ "全端",
+ "分享",
+ "前端",
+ "後端",
+ "教學",
+ "暴肝",
+ "知識",
+ "碼農",
+ "科技",
+ "科普",
+ "程式設計",
+ "資工系",
+ "軟體工程",
+ "遊戲",
+ "魷魚",
+];
diff --git a/frontend/src/lib/home/presenter/redux/tagStore.ts b/frontend/src/lib/home/presenter/redux/tagStore.ts
new file mode 100644
index 0000000..557fd1a
--- /dev/null
+++ b/frontend/src/lib/home/presenter/redux/tagStore.ts
@@ -0,0 +1,10 @@
+import { configureStore } from "@reduxjs/toolkit";
+import tagReducer from "./tagSlice";
+
+const tagStore = configureStore({
+ reducer: {
+ tag: tagReducer,
+ },
+});
+
+export default tagStore;
diff --git a/frontend/src/lib/home/presenter/ui/SelfTags.tsx b/frontend/src/lib/home/presenter/ui/SelfTags.tsx
new file mode 100644
index 0000000..1a9b44e
--- /dev/null
+++ b/frontend/src/lib/home/presenter/ui/SelfTags.tsx
@@ -0,0 +1,55 @@
+"use client";
+
+import { Provider } from "react-redux";
+import tagStore from "../redux/tagStore";
+import { useTagDispatch, useTagSelector } from "../redux/tagHooks";
+import { useEffect, useState } from "react";
+import { tagStartedAction, tagStoppedAction } from "../redux/tagSlice";
+
+export default function SelfTags() {
+ return (
+
+ <_SelfTags />
+
+ );
+}
+
+function _SelfTags() {
+ const tags = useTagSelector((state) => state.tag.tags);
+ const dispatch = useTagDispatch();
+
+ const [isTagsVisible, setIsTagsVisible] = useState(false);
+
+ useEffect(() => {
+ dispatch(tagStartedAction({ interval: 4000 }));
+ return () => {
+ dispatch(tagStoppedAction());
+ setIsTagsVisible(false);
+ };
+ }, []);
+
+ useEffect(() => {
+ if (tags.length === 0) return;
+ setIsTagsVisible(true);
+ setTimeout(() => {
+ setIsTagsVisible(false);
+ }, 3500);
+ }, [tags]);
+
+ return (
+
+
+
+ {tags.map((tag) => (
+
+ ))}
+
+
+ );
+}
+
+function Hashtag(props: { tag: string }) {
+ return # {props.tag};
+}
diff --git a/frontend/src/lib/util/shuffleArray.ts b/frontend/src/lib/util/shuffleArray.ts
new file mode 100644
index 0000000..851ed97
--- /dev/null
+++ b/frontend/src/lib/util/shuffleArray.ts
@@ -0,0 +1,8 @@
+export default function shuffleArray(array: T[]): T[] {
+ const newArray = [...array];
+ for (let i = newArray.length - 1; i > 0; i--) {
+ const j = Math.floor(Math.random() * (i + 1));
+ [newArray[i], newArray[j]] = [newArray[j], newArray[i]];
+ }
+ return newArray;
+}
diff --git a/frontend/tailwind.config.ts b/frontend/tailwind.config.ts
index 85afc41..11fcf7f 100644
--- a/frontend/tailwind.config.ts
+++ b/frontend/tailwind.config.ts
@@ -2,7 +2,7 @@ import type { Config } from "tailwindcss";
export default {
content: [
- "./src/ui/**/*.{js,ts,jsx,tsx,mdx}",
+ "./src/lib/**/*.{js,ts,jsx,tsx,mdx}",
"./src/app/**/*.{js,ts,jsx,tsx,mdx}",
],
theme: {
--
2.47.1
From c16e3f29a0eda664c0d812d5a3d2bd55b6cfbe3f Mon Sep 17 00:00:00 2001
From: SquidSpirit
Date: Sat, 18 Jan 2025 03:22:55 +0800
Subject: [PATCH 5/6] BLOG-5 refactor: apply clean architecture directory
structure
---
frontend/src/app/page.tsx | 2 +-
.../src/lib/home/{presenter => framework}/ui/SelfTags.tsx | 6 +++---
frontend/src/lib/home/presenter/{redux => }/tagHooks.ts | 0
frontend/src/lib/home/presenter/{redux => }/tagSlice.ts | 0
frontend/src/lib/home/presenter/{redux => }/tagStore.ts | 0
5 files changed, 4 insertions(+), 4 deletions(-)
rename frontend/src/lib/home/{presenter => framework}/ui/SelfTags.tsx (86%)
rename frontend/src/lib/home/presenter/{redux => }/tagHooks.ts (100%)
rename frontend/src/lib/home/presenter/{redux => }/tagSlice.ts (100%)
rename frontend/src/lib/home/presenter/{redux => }/tagStore.ts (100%)
diff --git a/frontend/src/app/page.tsx b/frontend/src/app/page.tsx
index 3c02804..bc9a6c2 100644
--- a/frontend/src/app/page.tsx
+++ b/frontend/src/app/page.tsx
@@ -1,4 +1,4 @@
-import SelfTags from "@/lib/home/presenter/ui/SelfTags";
+import SelfTags from "@/lib/home/framework/ui/SelfTags";
export default function HomePage() {
return (
diff --git a/frontend/src/lib/home/presenter/ui/SelfTags.tsx b/frontend/src/lib/home/framework/ui/SelfTags.tsx
similarity index 86%
rename from frontend/src/lib/home/presenter/ui/SelfTags.tsx
rename to frontend/src/lib/home/framework/ui/SelfTags.tsx
index 1a9b44e..00d2f3a 100644
--- a/frontend/src/lib/home/presenter/ui/SelfTags.tsx
+++ b/frontend/src/lib/home/framework/ui/SelfTags.tsx
@@ -1,10 +1,10 @@
"use client";
import { Provider } from "react-redux";
-import tagStore from "../redux/tagStore";
-import { useTagDispatch, useTagSelector } from "../redux/tagHooks";
+import tagStore from "../../presenter/tagStore";
+import { useTagDispatch, useTagSelector } from "../../presenter/tagHooks";
import { useEffect, useState } from "react";
-import { tagStartedAction, tagStoppedAction } from "../redux/tagSlice";
+import { tagStartedAction, tagStoppedAction } from "../../presenter/tagSlice";
export default function SelfTags() {
return (
diff --git a/frontend/src/lib/home/presenter/redux/tagHooks.ts b/frontend/src/lib/home/presenter/tagHooks.ts
similarity index 100%
rename from frontend/src/lib/home/presenter/redux/tagHooks.ts
rename to frontend/src/lib/home/presenter/tagHooks.ts
diff --git a/frontend/src/lib/home/presenter/redux/tagSlice.ts b/frontend/src/lib/home/presenter/tagSlice.ts
similarity index 100%
rename from frontend/src/lib/home/presenter/redux/tagSlice.ts
rename to frontend/src/lib/home/presenter/tagSlice.ts
diff --git a/frontend/src/lib/home/presenter/redux/tagStore.ts b/frontend/src/lib/home/presenter/tagStore.ts
similarity index 100%
rename from frontend/src/lib/home/presenter/redux/tagStore.ts
rename to frontend/src/lib/home/presenter/tagStore.ts
--
2.47.1
From 756112cb21e58d41d0da1dde76ef335a738c6c8e Mon Sep 17 00:00:00 2001
From: SquidSpirit
Date: Sat, 18 Jan 2025 03:33:25 +0800
Subject: [PATCH 6/6] BLOG-5 docs: add comment for next config
---
frontend/next.config.ts | 1 +
1 file changed, 1 insertion(+)
diff --git a/frontend/next.config.ts b/frontend/next.config.ts
index 9ab38a3..fb53d7a 100644
--- a/frontend/next.config.ts
+++ b/frontend/next.config.ts
@@ -1,6 +1,7 @@
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
+ // Avoid from rendering twice in development mode
reactStrictMode: false,
};
--
2.47.1