Skip to content

Commit 229c828

Browse files
authored
Merge pull request #71 from deepraj21/main
fix: updated settings and refactored
2 parents b1576b6 + dc0b68b commit 229c828

File tree

12 files changed

+402
-584
lines changed

12 files changed

+402
-584
lines changed

client/src/App.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,12 @@ import Login from './pages/Login';
66
import Home from './pages/Home';
77
import Profile from './pages/Profile';
88
import { Toaster } from "@/components/ui/sonner";
9-
import EditProfileForm from './pages/EditProfileForm';
109
import { MessagePage } from './pages/MessagePage';
1110
import Projects from './pages/Projects';
1211
import Visualization from './pages/Visualization';
1312
import PrivacyPolicy from './pages/Privacypolicy';
1413
import ProjectDisplay from './pages/ProjectDisplay';
14+
import TermsAndConditions from './pages/TermsAndConditions';
1515

1616
const App = () => {
1717

@@ -23,13 +23,13 @@ const App = () => {
2323
<Route path="/signup" element={<Signup />} />
2424
<Route path="/login" element={<Login />} />
2525
<Route path="/home" element={<Home />} />
26-
<Route path="/settings" element={<EditProfileForm />} />
2726
<Route path="/message" element={<MessagePage/>} />
2827
<Route path="/projects/:username" element={<Projects />} />
2928
<Route path="/projects/:username/:projectId" element={<ProjectDisplay />} />
3029
<Route path="/user/:username" element={<Profile />} />
3130
<Route path="/relations/:username" element={<Visualization />} />
3231
<Route path="/privacy-policy" element={<PrivacyPolicy/>} />
32+
<Route path="/terms-and-conditions" element={<TermsAndConditions/>}/>
3333
<Route path="*" element={<div>404</div>} />
3434
</Routes>
3535
</Router>

client/src/components/Footer/Footer.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ const Footer = () => {
6868
</a>
6969
</li>
7070
<li>
71-
<a href="#" className="hover:underline">
71+
<a href="/terms-and-conditions" className="hover:underline">
7272
Terms &amp; Conditions
7373
</a>
7474
</li>

client/src/components/Projects/ProjectCard.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ export function ProjectCard({ project, onProjectChange }: ProjectProps) {
151151
</AlertDialogTrigger>
152152
<AlertDialogContent>
153153
<div className="flex">
154-
<AlertDialogHeader className="text-2xl">
154+
<AlertDialogHeader className="text-2xl mt-1.5">
155155
Update Project
156156
</AlertDialogHeader>
157157
<div className="flex-grow"></div>
@@ -168,7 +168,7 @@ export function ProjectCard({ project, onProjectChange }: ProjectProps) {
168168
</AlertDialogTrigger>
169169
<AlertDialogContent>
170170
<div className="flex">
171-
<AlertDialogHeader className="text-2xl">
171+
<AlertDialogHeader className="text-2xl mt-1.5">
172172
Delete Project
173173
</AlertDialogHeader>
174174
<div className="flex-grow"></div>
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import {
2+
Tabs,
3+
TabsContent,
4+
TabsList,
5+
TabsTrigger,
6+
} from "@/components/ui/tabs"
7+
import UpdateProfile from "./UpdateProfile"
8+
import WebappSettings from "./WebappSettings"
9+
10+
const Settings = () => {
11+
return (
12+
<Tabs defaultValue="profile" className="mt-5 w-full">
13+
<TabsList className="grid w-full grid-cols-2">
14+
<TabsTrigger value="profile">Profile</TabsTrigger>
15+
<TabsTrigger value="webapp">WebApp</TabsTrigger>
16+
</TabsList>
17+
<TabsContent value="profile">
18+
<UpdateProfile />
19+
</TabsContent>
20+
<TabsContent value="webapp">
21+
<WebappSettings />
22+
</TabsContent>
23+
</Tabs>
24+
)
25+
}
26+
27+
export default Settings
Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import React, { useState, useEffect } from 'react';
2+
import axios from 'axios';
3+
import { Button } from '@/components/ui/button';
4+
import { Input } from '@/components/ui/input';
5+
import { Label } from '@/components/ui/label';
6+
import { toast } from 'sonner';
7+
import { Textarea } from '../ui/textarea';
8+
import { Icons } from "@/components/ui/icons";
9+
10+
const backendUrl = import.meta.env.VITE_BACKEND_URL || 'http://localhost:5000';
11+
12+
interface ProfileData {
13+
name: string;
14+
bio: string;
15+
githubUsername: string;
16+
leetcodeUsername: string;
17+
}
18+
19+
const UpdateProfile = () => {
20+
const [username, setUsername] = useState<string | null>(null);
21+
const [profileData, setProfileData] = useState<ProfileData>({
22+
name: '',
23+
bio: '',
24+
githubUsername: '',
25+
leetcodeUsername: ''
26+
});
27+
const [isLoading, setIsLoading] = useState(false);
28+
29+
30+
useEffect(() => {
31+
const storedUsername = localStorage.getItem('devhub_username');
32+
setUsername(storedUsername);
33+
}, []);
34+
35+
useEffect(() => {
36+
const fetchProfile = async () => {
37+
if (username) {
38+
try {
39+
const response = await axios.get(`${backendUrl}/profile/${username}`);
40+
setProfileData(response.data);
41+
} catch (error) {
42+
console.error('Failed to fetch profile data:', error);
43+
}
44+
}
45+
};
46+
47+
fetchProfile();
48+
}, [username]);
49+
50+
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>) => {
51+
const { name, value } = e.target;
52+
setProfileData((prevData: ProfileData) => ({
53+
...prevData,
54+
[name]: value,
55+
}));
56+
};
57+
58+
59+
60+
const handleSubmit = async (e: React.SyntheticEvent) => {
61+
e.preventDefault();
62+
if (!username) return;
63+
setIsLoading(true);
64+
65+
try {
66+
await axios.put(`${backendUrl}/profile/${username}`, profileData, {
67+
withCredentials: true,
68+
});
69+
toast.success('Profile updated successfully');
70+
} catch (error) {
71+
console.error('Failed to update profile:', error);
72+
toast.error('Failed to update profile', {
73+
description: 'Please check your details and try again.',
74+
});
75+
} finally {
76+
setIsLoading(false);
77+
}
78+
};
79+
80+
return (
81+
<div className='p-2 mt-4 h-full overflow-auto'>
82+
<h2 className='text-xl font-semibold mb-4 dark:text-neutral-100'>
83+
Update Profile
84+
</h2>
85+
<form onSubmit={handleSubmit} className='grid gap-4'>
86+
<div>
87+
<Label htmlFor='name' className='dark:text-neutral-200'>
88+
Name
89+
</Label>
90+
<Input
91+
id='name'
92+
name='name'
93+
value={profileData.name || ''}
94+
onChange={handleChange}
95+
disabled={isLoading}
96+
placeholder='Your name'
97+
className='mt-2'
98+
/>
99+
</div>
100+
<div>
101+
<Label htmlFor='bio' className='dark:text-neutral-200'>
102+
Bio
103+
</Label>
104+
<Textarea
105+
id='bio'
106+
name='bio'
107+
value={profileData.bio || ''}
108+
onChange={handleChange}
109+
disabled={isLoading}
110+
placeholder='Write something about yourself'
111+
className='mt-2'
112+
/>
113+
</div>
114+
<div className='grid grid-cols-1 sm:grid-cols-2 gap-6'>
115+
<div>
116+
<Label htmlFor='githubUsername' className='dark:text-neutral-200'>
117+
GitHub Username
118+
</Label>
119+
<Input
120+
id='githubUsername'
121+
name='githubUsername'
122+
value={profileData.githubUsername || ''}
123+
onChange={handleChange}
124+
disabled={isLoading}
125+
placeholder='GitHub username'
126+
className='mt-2'
127+
/>
128+
</div>
129+
<div>
130+
<Label htmlFor='leetcodeUsername' className='dark:text-neutral-200'>
131+
Leetcode Username
132+
</Label>
133+
<Input
134+
id='leetcodeUsername'
135+
name='leetcodeUsername'
136+
value={profileData.leetcodeUsername || ''}
137+
onChange={handleChange}
138+
disabled={isLoading}
139+
placeholder='Leetcode username'
140+
className='mt-2 '
141+
/>
142+
</div>
143+
</div>
144+
<Button type='submit' disabled={isLoading} className='w-full mt-4'>
145+
{isLoading ? (<><Icons.spinner className="mr-2 h-4 w-4 animate-spin" /> 'Updating...'
146+
</>) : 'Update Profile'}
147+
</Button>
148+
</form>
149+
</div>
150+
);
151+
};
152+
153+
export default UpdateProfile;
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { ModeToggle } from "../Theme/mode-toggle"
2+
3+
const WebappSettings = () => {
4+
return (
5+
<div className = 'p-2 mt-4 h-full overflow-auto'>
6+
<h2 className='text-xl font-semibold mb-4 dark:text-neutral-100'>
7+
Update Theme
8+
</h2>
9+
<ModeToggle/>
10+
</div>
11+
)
12+
}
13+
14+
export default WebappSettings

0 commit comments

Comments
 (0)