Skip to content

Commit b4ed5bb

Browse files
authored
Merge pull request #51 from Saurabh254/feat/general_settings_page_integration
feat/general settings page integration
2 parents 53de387 + 95ee987 commit b4ed5bb

10 files changed

Lines changed: 161 additions & 96 deletions

File tree

server/pin_sphere/constants.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
"mail_updates": True,
1313
"incoming_sound": True,
1414
},
15-
"appearance": {"accent_colors": "dark"},
15+
"appearance": {"theme": "dark"},
1616
"privacy_and_security": {
1717
"private_account": False,
1818
"two_factor_auth": False,

server/pin_sphere/users/filters.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -43,9 +43,9 @@ class NotificationSettingsFilter(BaseModel):
4343

4444

4545
class AppearanceSettingsFilter(BaseModel):
46-
accent_colors: Optional[str] = Field(
46+
theme: Optional[str] = Field(
4747
default=None,
48-
description="accent color (e.g. 'blue' or 'purple').",
48+
description="accent color (e.g. 'light' or 'dark').",
4949
)
5050

5151

webapp/src/components/SettingsMenu.tsx

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,4 @@
1-
import {
2-
RiHomeSmileLine,
3-
RiNotificationLine,
4-
RiPaletteLine,
5-
} from "@remixicon/react";
1+
import { RiHomeSmileLine, RiNotificationLine } from "@remixicon/react";
62
import { Lock } from "lucide-react";
73

84
const SettingsMenu: React.FC<{
@@ -33,24 +29,14 @@ const SettingsMenu: React.FC<{
3329
<RiNotificationLine />
3430
</a>
3531
</li>
32+
3633
<li>
3734
<a
3835
className={` ${
3936
settingsType === 2 ? "dark:bg-gray-700 bg-gray-300" : ""
4037
}`}
41-
data-tip="Appearance"
42-
onClick={() => setSettingsType(2)}
43-
>
44-
<RiPaletteLine />
45-
</a>
46-
</li>
47-
<li>
48-
<a
49-
className={` ${
50-
settingsType === 3 ? "dark:bg-gray-700 bg-gray-300" : ""
51-
}`}
5238
data-tip="Privacy & Security"
53-
onClick={() => setSettingsType(3)}
39+
onClick={() => setSettingsType(2)}
5440
>
5541
<Lock />
5642
</a>

webapp/src/components/settings/AppearanceSettings.tsx

Lines changed: 0 additions & 42 deletions
This file was deleted.

webapp/src/components/settings/GeneralSettings.tsx

Lines changed: 82 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,7 @@
1+
import { save_settings } from "@/service/user_service";
2+
import { GeneralSettings as GeneralSettingsType } from "@/types/userSettings";
3+
import { useState } from "react";
4+
15
const languages = [
26
{ label: "English", value: "en" },
37
{ label: "Hindi", value: "hi" },
@@ -16,21 +20,66 @@ const timezones = [
1620
{ label: "JST (Japan Standard Time)", value: "Asia/Tokyo" },
1721
];
1822

19-
const GeneralSettings = () => {
23+
const GeneralSettings: React.FC<{ generalSettings: GeneralSettingsType }> = ({
24+
generalSettings,
25+
}) => {
26+
const [settings, setSettings] =
27+
useState<GeneralSettingsType>(generalSettings);
28+
const [changed, setChanged] = useState<boolean>(false);
29+
30+
const handleLanguageChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
31+
setChanged(true);
32+
setSettings({ ...settings, language: e.target.value });
33+
};
34+
35+
const handleTimezoneChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
36+
setChanged(true);
37+
setSettings({ ...settings, timezone: e.target.value });
38+
};
39+
40+
const handleBackgroundSyncToggle = () => {
41+
setChanged(true);
42+
setSettings({ ...settings, background_sync: !settings.background_sync });
43+
};
44+
45+
const handleAutoplayMediaToggle = () => {
46+
setChanged(true);
47+
setSettings({ ...settings, autoplay_media: !settings.autoplay_media });
48+
};
49+
50+
const handleSave = async () => {
51+
await save_settings("general", settings);
52+
setChanged(false);
53+
};
54+
2055
return (
2156
<div className="px-4 py-0 dark:text-gray-200 text-black">
22-
<div className="rounded-xl p-2 py-0 text-sm">
23-
<h1 className="text-lg font-semibold mb-4">General Settings</h1>
57+
{changed && (
58+
<div className="absolute bottom-10 px-4 w-[calc(100%-2rem)] justify-between flex items-center bg-gray-800 rounded-lg py-3">
59+
<span className="text-sm text-nowrap">You have unsaved changes!</span>
60+
<button
61+
type="button"
62+
className="btn-primary btn btn-sm"
63+
onClick={handleSave}
64+
>
65+
Save
66+
</button>
67+
</div>
68+
)}
69+
<div className="rounded-xl p-2 py-0 text-sm">
70+
<h1 className="text-lg font-semibold mb-4">General Settings</h1>
2471

25-
<div className="space-y-4 text-black dark:text-gray-200 ">
72+
<div className="space-y-4 text-black dark:text-gray-200">
2673
{/* Language Selector */}
27-
<div className="flex flex-col ">
74+
<div className="flex flex-col">
2875
<label htmlFor="language" className="mb-1 font-semibold">
2976
Language
3077
</label>
3178
<select
3279
id="language"
3380
name="language"
81+
value={settings.language}
82+
onChange={handleLanguageChange}
3483
className="border-2 border-black font-semibold dark:text-gray-400 px-3 py-2 rounded focus:outline-none focus:ring focus:ring-indigo-500"
3584
>
3685
{languages.map((lang) => (
@@ -49,7 +98,9 @@ const GeneralSettings = () => {
4998
<select
5099
id="timezone"
51100
name="timezone"
52-
className="border-2 border-black dark:text-gray-400 font-semibold px-3 py-2 rounded focus:outline-none focus:ring focus:ring-indigo-500"
101+
value={settings.timezone}
102+
onChange={handleTimezoneChange}
103+
className="border-2 border-black dark:text-gray-400 font-semibold px-3 py-2 rounded focus:outline-none focus:ring focus:ring-indigo-500"
53104
>
54105
{timezones.map((zone) => (
55106
<option key={zone.value} value={zone.value}>
@@ -58,6 +109,7 @@ const GeneralSettings = () => {
58109
))}
59110
</select>
60111
</div>
112+
61113
{/* Background Sync */}
62114
<div className="flex items-center justify-between gap-6">
63115
<div>
@@ -68,7 +120,30 @@ const GeneralSettings = () => {
68120
Get faster performance by syncing messages in the background
69121
</p>
70122
</div>
71-
<input type="checkbox" className="toggle toggle-primary bg-black" />
123+
<input
124+
type="checkbox"
125+
className="toggle toggle-primary bg-black"
126+
checked={settings.background_sync}
127+
onChange={handleBackgroundSyncToggle}
128+
/>
129+
</div>
130+
131+
{/* AutoPlay Media */}
132+
<div className="flex items-center justify-between gap-6">
133+
<div>
134+
<div className="font-semibold text-black dark:text-gray-200">
135+
AutoPlay Media
136+
</div>
137+
<p className="text-xs text-gray-500">
138+
when checked media will play automatically
139+
</p>
140+
</div>
141+
<input
142+
type="checkbox"
143+
className="toggle toggle-primary bg-black"
144+
checked={settings.autoplay_media}
145+
onChange={handleAutoplayMediaToggle}
146+
/>
72147
</div>
73148
</div>
74149
</div>

webapp/src/components/settings/PrivacyAndSettings.tsx

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ import React, { useState } from "react";
33
const PrivacyAndSecuritySettings = () => {
44
const [profileType, setProfileType] = useState(0);
55
const [twoFactorAuth, setTwoFactorAuth] = useState(false);
6-
const [readReceipts, setReadReceipts] = useState(true);
76
const [profileDiscovery, setProfileDiscovery] = useState(true);
87

98
return (
@@ -53,26 +52,6 @@ const PrivacyAndSecuritySettings = () => {
5352
</label>
5453
</div>
5554

56-
{/* Read Receipts */}
57-
<div className="form-control mb-4">
58-
<label className="label cursor-pointer">
59-
<div>
60-
<span className="label-text font-semibold text-black dark:text-gray-200">
61-
Read Receipts
62-
</span>
63-
<p className="text-xs text-gray-500 ml-1 mt-1 text-wrap">
64-
Allow others to see when you've read their messages.
65-
</p>
66-
</div>
67-
<input
68-
type="checkbox"
69-
className="toggle toggle-primary bg-black"
70-
checked={readReceipts}
71-
onChange={() => setReadReceipts(!readReceipts)}
72-
/>
73-
</label>
74-
</div>
75-
7655
{/* Profile Discovery */}
7756
<div className="form-control mb-4">
7857
<label className="label cursor-pointer">

webapp/src/constants.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
export const API_URL: string = "http://localhost:8000/api/v1";
1+
export const API_URL: string = "http://192.168.234.146:8000/api/v1";

webapp/src/pages/Settings.tsx

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,36 @@
1-
import AppearanceSettings from "@/components/settings/AppearanceSettings";
21
import GeneralSettings from "@/components/settings/GeneralSettings";
32
import NotificationSettings from "@/components/settings/NotificationSettings";
43
import PrivacyAndSecuritySettings from "@/components/settings/PrivacyAndSettings";
54
import SettingsMenu from "@/components/SettingsMenu";
6-
import { useState } from "react";
5+
import { getUserSettings } from "@/service/user_service";
6+
import { UserSettings } from "@/types/userSettings";
7+
import { useEffect, useState } from "react";
78

89
import React from "react";
910

1011
const SettingsContent: React.FC<{
1112
settingsType: number;
1213
}> = ({ settingsType }) => {
14+
const [userSettings, setUserSettings] = useState<UserSettings | null>(null);
15+
useEffect(() => {
16+
const call_api = async () => {
17+
try {
18+
setUserSettings(await getUserSettings());
19+
} catch (e) {
20+
console.error(e);
21+
}
22+
};
23+
call_api();
24+
}, []);
25+
if (userSettings === null) {
26+
return <h1>loadingg....</h1>;
27+
}
1328
switch (settingsType) {
1429
case 0:
15-
return <GeneralSettings />;
30+
return <GeneralSettings generalSettings={userSettings.general} />;
1631
case 1:
1732
return <NotificationSettings />;
1833
case 2:
19-
return <AppearanceSettings />;
20-
case 3:
2134
return <PrivacyAndSecuritySettings />;
2235
}
2336

webapp/src/service/user_service.tsx

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,13 @@
11
import { Page, SlimContent } from "@/types";
22
import api_client from "../api_client";
33
import { API_URL } from "../constants";
4+
import {
5+
AppearanceSettings,
6+
GeneralSettings,
7+
NotificationSettings,
8+
PrivacyAndSecurity,
9+
UserSettings,
10+
} from "@/types/userSettings";
411

512
export const checkUserNameAvailablity = async (userName: string) => {
613
const response = await api_client.get(
@@ -29,3 +36,22 @@ export const getUserContents = async (): Promise<Page<SlimContent>> => {
2936
const response = await api_client.get(`${API_URL}/content/me`);
3037
return response.data;
3138
};
39+
40+
export const getUserSettings = async (): Promise<UserSettings> => {
41+
const response = await api_client.get(`${API_URL}/users/settings`);
42+
return response.data;
43+
};
44+
45+
export const save_settings = async (
46+
settings_type: string,
47+
settings:
48+
| GeneralSettings
49+
| NotificationSettings
50+
| AppearanceSettings
51+
| PrivacyAndSecurity
52+
) => {
53+
const response = await api_client.put(`${API_URL}/users/settings`, {
54+
[settings_type]: settings,
55+
});
56+
return response.data;
57+
};

webapp/src/types/userSettings.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
export type GeneralSettings = {
2+
language: string;
3+
timezone: string;
4+
background_sync: boolean;
5+
autoplay_media: boolean;
6+
};
7+
export type NotificationSettings = {
8+
updates_notification: boolean;
9+
mail_updates: boolean;
10+
incoming_sound: boolean;
11+
};
12+
13+
export type AppearanceSettings = {
14+
theme: string;
15+
16+
}
17+
18+
export type PrivacyAndSecurity = {
19+
private_account: boolean;
20+
two_factor_auth: boolean;
21+
read_receipts: boolean;
22+
profile_discovery: boolean;
23+
}
24+
export type UserSettings = {
25+
general: GeneralSettings
26+
notification: NotificationSettings
27+
privacy_and_security: PrivacyAndSecurity
28+
}

0 commit comments

Comments
 (0)