Skip to content

Commit 4cf168f

Browse files
authored
Merge pull request #38 from dudkinox/button-light-dark-mode
Button light dark mode
2 parents 3b9f04c + e451d5c commit 4cf168f

File tree

5 files changed

+99
-54
lines changed

5 files changed

+99
-54
lines changed

src/common/Sidebar.tsx

Lines changed: 32 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,20 @@
1-
import { useContext, useState, useEffect } from "react";
1+
import { useContext } from "react";
22
import { AppContext } from "../contexts";
33
import { PathEnum } from "../enum/path.enum";
44
import { ThemesEnum } from "../enum/mode.enum";
5+
import ThemeToggle from "./Themes";
56

67
export default function SidebarCommon() {
7-
const { pathUrl, isLogin, majorUser } = useContext(AppContext);
8-
const [theme, setTheme] = useState<ThemesEnum>(ThemesEnum.DARK);
9-
10-
useEffect(() => {
11-
const savedTheme = localStorage.getItem("theme") as ThemesEnum | null;
12-
if (savedTheme) {
13-
setTheme(savedTheme);
14-
document.body.classList.toggle("dark-mode", savedTheme === ThemesEnum.DARK);
15-
document.body.classList.toggle("light-mode", savedTheme === ThemesEnum.LIGHT);
16-
}
17-
}, []);
18-
19-
const toggleTheme = () => {
20-
const newTheme = theme === ThemesEnum.DARK ? ThemesEnum.LIGHT : ThemesEnum.DARK;
21-
setTheme(newTheme);
22-
localStorage.setItem("theme", newTheme);
23-
document.body.classList.toggle("dark-mode", newTheme === ThemesEnum.DARK);
24-
document.body.classList.toggle("light-mode", newTheme === ThemesEnum.LIGHT);
25-
};
8+
const { pathUrl, isLogin, majorUser, theme } = useContext(AppContext);
269

2710
return (
28-
<aside className={`main-sidebar ${theme === "dark" ? "sidebar-dark-primary" : "sidebar-light-primary"} elevation-4`}>
11+
<aside
12+
className={`main-sidebar ${theme === ThemesEnum.DARK
13+
? "sidebar-dark-primary"
14+
: "sidebar-light-primary"
15+
} elevation-4`}
16+
>
2917
<div className="sidebar">
30-
3118
<div className="user-panel mt-3 pb-3 mb-3 d-flex">
3219
<div className="image">
3320
<img
@@ -52,7 +39,7 @@ export default function SidebarCommon() {
5239
role="menu"
5340
data-accordion="false"
5441
>
55-
{majorUser === "admin" ? (
42+
{majorUser === "admin" && (
5643
<li className="nav-item">
5744
<a
5845
href="/"
@@ -63,9 +50,9 @@ export default function SidebarCommon() {
6350
<p>หน้าเเรก</p>
6451
</a>
6552
</li>
66-
) : null}
53+
)}
6754

68-
{majorUser === "admin" ? (
55+
{majorUser === "admin" && (
6956
<li className="nav-item">
7057
<a
7158
href={PathEnum.DOCUMENT}
@@ -76,7 +63,7 @@ export default function SidebarCommon() {
7663
<p>นำเข้าข้อมูล</p>
7764
</a>
7865
</li>
79-
) : null}
66+
)}
8067

8168
<li className="nav-item menu-open">
8269
<a href="#" className="nav-link">
@@ -90,7 +77,8 @@ export default function SidebarCommon() {
9077
<li className="nav-item">
9178
<a
9279
href={PathEnum.STOCK_KAY}
93-
className={`nav-link ${pathUrl === PathEnum.STOCK_KAY ? "active" : ""}`}
80+
className={`nav-link ${pathUrl === PathEnum.STOCK_KAY ? "active" : ""
81+
}`}
9482
>
9583
<i className="far fa-circle nav-icon" />
9684
<p>ขาย</p>
@@ -99,7 +87,8 @@ export default function SidebarCommon() {
9987
<li className="nav-item">
10088
<a
10189
href={PathEnum.STOCK_BYE}
102-
className={`nav-link ${pathUrl === PathEnum.STOCK_BYE ? "active" : ""}`}
90+
className={`nav-link ${pathUrl === PathEnum.STOCK_BYE ? "active" : ""
91+
}`}
10392
>
10493
<i className="far fa-circle nav-icon" />
10594
<p>ซื้อ</p>
@@ -108,7 +97,8 @@ export default function SidebarCommon() {
10897
<li className="nav-item">
10998
<a
11099
href={PathEnum.STOCK_EQUIPMENT}
111-
className={`nav-link ${pathUrl === PathEnum.STOCK_EQUIPMENT ? "active" : ""}`}
100+
className={`nav-link ${pathUrl === PathEnum.STOCK_EQUIPMENT ? "active" : ""
101+
}`}
112102
>
113103
<i className="far fa-circle nav-icon" />
114104
<p>อุปกรณ์</p>
@@ -117,7 +107,10 @@ export default function SidebarCommon() {
117107
<li className="nav-item">
118108
<a
119109
href={PathEnum.STOCK_INSTALLMENT_PAYMENT}
120-
className={`nav-link ${pathUrl === PathEnum.STOCK_INSTALLMENT_PAYMENT ? "active" : ""}`}
110+
className={`nav-link ${pathUrl === PathEnum.STOCK_INSTALLMENT_PAYMENT
111+
? "active"
112+
: ""
113+
}`}
121114
>
122115
<i className="far fa-circle nav-icon" />
123116
<p>ผ่อน</p>
@@ -127,7 +120,10 @@ export default function SidebarCommon() {
127120
<li className="nav-item">
128121
<a
129122
href={PathEnum.STOCK_INSTALLMENT_SUMMARY}
130-
className={`nav-link ${pathUrl === PathEnum.STOCK_INSTALLMENT_SUMMARY ? "active" : ""}`}
123+
className={`nav-link ${pathUrl === PathEnum.STOCK_INSTALLMENT_SUMMARY
124+
? "active"
125+
: ""
126+
}`}
131127
>
132128
<i className="far fa-circle nav-icon" />
133129
<p>สรุป</p>
@@ -148,7 +144,7 @@ export default function SidebarCommon() {
148144
</a>
149145
</li>
150146

151-
{majorUser === "admin" ? (
147+
{majorUser === "admin" && (
152148
<li className="nav-item">
153149
<a
154150
href="/manage-user"
@@ -159,9 +155,9 @@ export default function SidebarCommon() {
159155
<p>จัดการผู้ใช้</p>
160156
</a>
161157
</li>
162-
) : null}
158+
)}
163159

164-
{majorUser === "admin" ? (
160+
{majorUser === "admin" && (
165161
<li className="nav-item">
166162
<a
167163
href="/income-list"
@@ -172,7 +168,7 @@ export default function SidebarCommon() {
172168
<p>รายรับ-รายจ่าย</p>
173169
</a>
174170
</li>
175-
) : null}
171+
)}
176172

177173
<li className="nav-item">
178174
<a href="/app/Stock.msi" className={`nav-link`}>
@@ -202,23 +198,11 @@ export default function SidebarCommon() {
202198
<p>ออกจากระบบ</p>
203199
</a>
204200
</li>
205-
206201
</ul>
207-
208202
</nav>
209203
)}
210-
211-
</div>
212-
213-
<div className="d-flex justify-content-around">
214-
<button
215-
onClick={toggleTheme}
216-
className={`btn btn-sm ${theme === ThemesEnum.DARK ? "btn-outline-light" : "btn-dark"}`}
217-
>
218-
{theme === ThemesEnum.DARK ? "🌞 Light" : "🌙 Dark"}
219-
</button>
220-
221204
</div>
205+
<ThemeToggle />
222206
</aside>
223207
);
224208
}

src/common/Themes.tsx

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { useContext } from "react";
2+
import { AppContext } from "../contexts";
3+
import { ThemesEnum } from "../enum/mode.enum";
4+
5+
export default function ThemeToggle() {
6+
const { theme, setTheme, isLogin } = useContext(AppContext);
7+
8+
if (!isLogin) return null;
9+
10+
const toggleTheme = () => {
11+
const newTheme = theme === ThemesEnum.DARK ? ThemesEnum.LIGHT : ThemesEnum.DARK;
12+
setTheme(newTheme);
13+
localStorage.setItem("theme", newTheme);
14+
document.body.classList.toggle("dark-mode", newTheme === ThemesEnum.DARK);
15+
document.body.classList.toggle("light-mode", newTheme === ThemesEnum.LIGHT);
16+
};
17+
18+
return (
19+
<div className="d-flex justify-content-around mb-3">
20+
<button
21+
onClick={toggleTheme}
22+
className={`btn btn-sm ${
23+
theme === ThemesEnum.DARK ? "btn-outline-light" : "btn-dark"
24+
}`}
25+
>
26+
{theme === ThemesEnum.DARK ? "🌞 Light" : "🌙 Dark"}
27+
</button>
28+
</div>
29+
);
30+
}

src/contexts/index.tsx

Lines changed: 29 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { createContext, ReactNode, useEffect, useMemo, useState } from "react";
22
import { AlertError, AlertSuccess } from "../common/ToastrCommon";
33
import AccountServices from "../services/AccountService";
44
import StockService from "../services/StockServices";
5+
import { ThemesEnum } from "../enum/mode.enum";
56

67
interface AppContextProps {
78
pathUrl: string;
@@ -15,20 +16,24 @@ interface AppContextProps {
1516
isLoading: boolean;
1617
setIsLoading: (isLoading: boolean) => void;
1718
deleteStock: (id: string, major: string) => () => void;
19+
theme: ThemesEnum;
20+
setTheme: (theme: ThemesEnum) => void;
1821
}
1922

2023
export const AppContext = createContext<AppContextProps>({
2124
pathUrl: "",
22-
setPathUrl: () => {},
25+
setPathUrl: () => { },
2326
isLogin: "",
2427
majorUser: "",
2528
isEdit: () => false,
2629
isDelete: () => false,
2730
editPermission: "",
2831
deletePermission: "",
2932
isLoading: false,
30-
setIsLoading: () => {},
31-
deleteStock: () => () => {},
33+
setIsLoading: () => { },
34+
deleteStock: () => () => { },
35+
theme: ThemesEnum.DARK,
36+
setTheme: () => { }
3237
});
3338

3439
interface ChildrenProps {
@@ -43,6 +48,11 @@ export function AppContextProvider({ children }: Readonly<ChildrenProps>) {
4348
const deletePermission = sessionStorage.getItem("can_delete") ?? "";
4449
const [isLoading, setIsLoading] = useState<boolean>(false);
4550

51+
const [theme, setTheme] = useState<ThemesEnum>(() => {
52+
const savedTheme = localStorage.getItem("theme") as ThemesEnum | null;
53+
return savedTheme ?? ThemesEnum.DARK;
54+
});
55+
4656
const isEdit = () => editPermission === "TRUE";
4757
const isDelete = () => deletePermission === "TRUE";
4858

@@ -67,6 +77,18 @@ export function AppContextProvider({ children }: Readonly<ChildrenProps>) {
6777
setIsLoading(false);
6878
});
6979
};
80+
useEffect(() => {
81+
document.body.classList.remove("dark-mode", "light-mode");
82+
document.body.classList.add(theme === ThemesEnum.DARK ? "dark-mode" : "light-mode");
83+
localStorage.setItem("theme", theme);
84+
}, [theme]);
85+
useEffect(() => {
86+
if (!isLogin) {
87+
setTheme(ThemesEnum.DARK);
88+
document.body.classList.remove("light-mode");
89+
document.body.classList.add("dark-mode");
90+
}
91+
}, [isLogin]);
7092

7193
useEffect(() => {
7294
setIsLoading(true);
@@ -123,6 +145,8 @@ export function AppContextProvider({ children }: Readonly<ChildrenProps>) {
123145
isLoading,
124146
setIsLoading,
125147
deleteStock,
148+
theme,
149+
setTheme,
126150
}),
127151
[
128152
pathUrl,
@@ -136,6 +160,8 @@ export function AppContextProvider({ children }: Readonly<ChildrenProps>) {
136160
isLoading,
137161
setIsLoading,
138162
deleteStock,
163+
theme,
164+
setTheme,
139165
]
140166
);
141167

src/layouts/stock/InstallmentMenuInsert.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,7 +150,7 @@ export default function InstallmentMenuInsert({
150150
PaymentService.InstallmentNumber(documentId).then((res) => {
151151
String(res.data) === "false"
152152
? ($("#alert-installment-modal") as any).modal("show")
153-
: setInstallmentNo(Number(res.data) + 1);
153+
: setInstallmentNo(Number(res.data));
154154
});
155155
}}
156156
>

src/pages/LoginPage/index.tsx

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
import ContentLayOut from '../../layouts/ContentLayOut'
22
import Logo from '../../assets/logo.png'
33
import AccountServices from '../../services/AccountService'
4-
import { useContext, useState } from 'react'
4+
import { useContext, useEffect, useState } from 'react'
55
import { AlertError, AlertSuccess } from '../../common/ToastrCommon'
66
import { AppContext } from '../../contexts'
7+
import { ThemesEnum } from '../../enum/mode.enum'
78

89
export default function LoginPage() {
910
const [username, setUsername] = useState('')
1011
const [password, setPassword] = useState('')
11-
const { setIsLoading } = useContext(AppContext)
12+
const { setIsLoading, setTheme } = useContext(AppContext)
13+
14+
useEffect(() => {
15+
setTheme(ThemesEnum.DARK)
16+
}, [setTheme])
1217

1318
const login = (e: any) => {
1419
e.preventDefault()

0 commit comments

Comments
 (0)