diff --git a/web/src/components/Settings/MemberSection.tsx b/web/src/components/Settings/MemberSection.tsx
index 9eae10f1..1b2883f6 100644
--- a/web/src/components/Settings/MemberSection.tsx
+++ b/web/src/components/Settings/MemberSection.tsx
@@ -12,7 +12,6 @@ import "../../less/settings/member-section.less";
interface State {
createUserUsername: string;
createUserPassword: string;
- repeatUserPassword: string;
}
const PreferencesSection = () => {
@@ -21,7 +20,6 @@ const PreferencesSection = () => {
const [state, setState] = useState
({
createUserUsername: "",
createUserPassword: "",
- repeatUserPassword: "",
});
const [userList, setUserList] = useState([]);
@@ -48,22 +46,11 @@ const PreferencesSection = () => {
});
};
- const handleRepeatPasswordInputChange = (event: React.ChangeEvent) => {
- setState({
- ...state,
- repeatUserPassword: event.target.value,
- });
- };
-
const handleCreateUserBtnClick = async () => {
if (state.createUserUsername === "" || state.createUserPassword === "") {
toastHelper.error(t("message.fill-form"));
return;
}
- if (state.createUserPassword !== state.repeatUserPassword) {
- toastHelper.error(t("message.password-not-match"));
- return;
- }
const userCreate: UserCreate = {
username: state.createUserUsername,
@@ -80,7 +67,6 @@ const PreferencesSection = () => {
setState({
createUserUsername: "",
createUserPassword: "",
- repeatUserPassword: "",
});
};
@@ -131,19 +117,22 @@ const PreferencesSection = () => {
{t("common.username")}
-
+
{t("common.password")}
-
-
-
- {t("common.repeat-password-short")}
diff --git a/web/src/components/Settings/PreferencesSection.tsx b/web/src/components/Settings/PreferencesSection.tsx
index d26b60e1..1f3285ce 100644
--- a/web/src/components/Settings/PreferencesSection.tsx
+++ b/web/src/components/Settings/PreferencesSection.tsx
@@ -4,6 +4,7 @@ import { globalService, userService } from "../../services";
import { useAppSelector } from "../../store";
import { VISIBILITY_SELECTOR_ITEMS, MEMO_DISPLAY_TS_OPTION_SELECTOR_ITEMS } from "../../helpers/consts";
import Selector from "../common/Selector";
+import AppearanceSelect from "../AppearanceSelect";
import "../../less/settings/preferences-section.less";
const localeSelectorItems = [
@@ -66,6 +67,10 @@ const PreferencesSection = () => {
{t("common.language")}
+
{t("setting.preference")}
diff --git a/web/src/router/index.tsx b/web/src/router/index.tsx
index f2398098..467fe954 100644
--- a/web/src/router/index.tsx
+++ b/web/src/router/index.tsx
@@ -18,6 +18,7 @@ const router = createBrowserRouter([
} catch (error) {
// do nth
}
+ return null;
},
},
{
@@ -37,6 +38,7 @@ const router = createBrowserRouter([
} else if (isNullorUndefined(user)) {
return redirect("/explore");
}
+ return null;
},
},
{
@@ -54,6 +56,7 @@ const router = createBrowserRouter([
if (isNullorUndefined(host)) {
return redirect("/auth");
}
+ return null;
},
},
{
@@ -71,6 +74,7 @@ const router = createBrowserRouter([
if (isNullorUndefined(host)) {
return redirect("/auth");
}
+ return null;
},
},
{
@@ -88,6 +92,7 @@ const router = createBrowserRouter([
if (isNullorUndefined(host)) {
return redirect("/auth");
}
+ return null;
},
},
]);
diff --git a/web/src/services/globalService.ts b/web/src/services/globalService.ts
index 6a46c0d8..492f5f2c 100644
--- a/web/src/services/globalService.ts
+++ b/web/src/services/globalService.ts
@@ -1,7 +1,7 @@
import store from "../store";
import * as api from "../helpers/api";
import * as storage from "../helpers/storage";
-import { setGlobalState, setLocale } from "../store/modules/global";
+import { setAppearance, setGlobalState, setLocale } from "../store/modules/global";
const globalService = {
getState: () => {
@@ -11,6 +11,7 @@ const globalService = {
initialState: async () => {
const defaultGlobalState = {
locale: "en" as Locale,
+ appearance: "system" as Appearance,
systemStatus: {
allowSignUp: false,
additionalStyle: "",
@@ -38,6 +39,10 @@ const globalService = {
setLocale: (locale: Locale) => {
store.dispatch(setLocale(locale));
},
+
+ setAppearance: (appearance: Appearance) => {
+ store.dispatch(setAppearance(appearance));
+ },
};
export default globalService;
diff --git a/web/src/services/userService.ts b/web/src/services/userService.ts
index 79d8d9c6..f61cdf69 100644
--- a/web/src/services/userService.ts
+++ b/web/src/services/userService.ts
@@ -8,6 +8,7 @@ import { setUser, patchUser, setHost, setOwner } from "../store/modules/user";
const defaultSetting: Setting = {
locale: "en",
+ appearance: "system",
memoVisibility: "PRIVATE",
memoDisplayTsOption: "created_ts",
};
diff --git a/web/src/store/modules/global.ts b/web/src/store/modules/global.ts
index 7156d37f..492b9613 100644
--- a/web/src/store/modules/global.ts
+++ b/web/src/store/modules/global.ts
@@ -2,6 +2,7 @@ import { createSlice, PayloadAction } from "@reduxjs/toolkit";
interface State {
locale: Locale;
+ appearance: Appearance;
systemStatus: SystemStatus;
}
@@ -9,6 +10,7 @@ const globalSlice = createSlice({
name: "global",
initialState: {
locale: "en",
+ appearance: "system",
systemStatus: {
host: undefined,
profile: {
@@ -31,9 +33,15 @@ const globalSlice = createSlice({
locale: action.payload,
};
},
+ setAppearance: (state, action: PayloadAction
) => {
+ return {
+ ...state,
+ appearance: action.payload,
+ };
+ },
},
});
-export const { setGlobalState, setLocale } = globalSlice.actions;
+export const { setGlobalState, setLocale, setAppearance } = globalSlice.actions;
export default globalSlice.reducer;
diff --git a/web/src/theme/index.ts b/web/src/theme/index.ts
index 1d59cc39..6dac7471 100644
--- a/web/src/theme/index.ts
+++ b/web/src/theme/index.ts
@@ -3,10 +3,8 @@ import { extendTheme } from "@mui/joy";
const theme = extendTheme({
components: {
JoySelect: {
- styleOverrides: {
- root: {
- fontSize: "0.875rem",
- },
+ defaultProps: {
+ size: "sm",
},
},
},
diff --git a/web/src/types/modules/setting.d.ts b/web/src/types/modules/setting.d.ts
index 49d49b9f..abf07b83 100644
--- a/web/src/types/modules/setting.d.ts
+++ b/web/src/types/modules/setting.d.ts
@@ -1,5 +1,8 @@
+type Appearance = "light" | "dark" | "system";
+
interface Setting {
locale: Locale;
+ appearance: Appearance;
memoVisibility: Visibility;
memoDisplayTsOption: "created_ts" | "updated_ts";
}
@@ -13,12 +16,17 @@ interface UserLocaleSetting {
value: Locale;
}
+interface UserAppearanceSetting {
+ key: "appearance";
+ value: Appearance;
+}
+
interface UserMemoVisibilitySetting {
key: "memoVisibility";
value: Visibility;
}
-type UserSetting = UserLocaleSetting | UserMemoVisibilitySetting;
+type UserSetting = UserLocaleSetting | UserAppearanceSetting | UserMemoVisibilitySetting;
interface UserSettingUpsert {
key: keyof Setting;