Skip to content

Commit 9a79f9b

Browse files
jacovkimedwardneoprime
authored andcommitted
Added CSS
Added minimal frontend changes
1 parent aa2e655 commit 9a79f9b

File tree

5 files changed

+245
-123
lines changed

5 files changed

+245
-123
lines changed

csm_web/frontend/src/components/ImageUploader.tsx

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useState, useEffect } from "react";
1+
import React, { useState } from "react";
22
import { fetchWithMethod, HTTP_METHODS } from "../utils/api";
33

44
// file size limits
@@ -9,11 +9,6 @@ const ImageUploader = () => {
99
const [file, setFile] = useState<File | null>(null);
1010
const [status, setStatus] = useState<string>("");
1111

12-
// useEffect(() => {
13-
// if (file) {
14-
// }
15-
// }, [file]);
16-
1712
const handleFileChange = (e: React.ChangeEvent<HTMLInputElement>) => {
1813
if (e.target.files && e.target.files[0]) {
1914
const selectedFile = e.target.files[0];
@@ -56,7 +51,6 @@ const ImageUploader = () => {
5651

5752
return (
5853
<div>
59-
<h1>Image Upload Tester</h1>
6054
<input type="file" onChange={handleFileChange} />
6155
<button onClick={handleUpload}>Upload</button>
6256
{status && <p>{status}</p>}

csm_web/frontend/src/components/UserProfile.tsx

Lines changed: 172 additions & 115 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,11 @@ import { PermissionError } from "../utils/queries/helpers";
44
import { useUserInfo, useUserInfoUpdateMutation } from "../utils/queries/profiles";
55
import ImageUploader from "./ImageUploader";
66
import LoadingSpinner from "./LoadingSpinner";
7+
import LogoNoText from "../../static/frontend/img/logo_no_text.svg";
78

89
import "../css/base/form.scss";
910
import "../css/base/table.scss";
11+
import "../css/profile.scss";
1012

1113
interface UserInfo {
1214
firstName: string;
@@ -40,7 +42,6 @@ const UserProfile: React.FC = () => {
4042
// Populate form data with fetched user data
4143
useEffect(() => {
4244
if (requestedData) {
43-
console.log(requestedData);
4445
setFormData({
4546
firstName: requestedData.firstName || "",
4647
lastName: requestedData.lastName || "",
@@ -127,123 +128,179 @@ const UserProfile: React.FC = () => {
127128
setIsEditing(true);
128129
};
129130

131+
const handleCancelToggle = () => {
132+
setIsEditing(false);
133+
};
134+
130135
return (
131-
<div id="user-profile-form">
132-
<h2 className="form-title">User Profile</h2>
133-
<div className="csm-form">
134-
<div className="form-item">
135-
<label htmlFor="profile" className="form-label">
136-
Profile Image
137-
</label>
138-
{isEditing ? (
139-
<ImageUploader />
140-
) : (
141-
// <p>{formData.profileImage}</p>
142-
<img src={formData.profileImage} />
143-
)}
144-
</div>
145-
<div className="form-item">
146-
<label htmlFor="firstName" className="form-label">
147-
First Name:
148-
</label>
149-
{isEditing ? (
150-
<input
151-
type="text"
152-
id="firstName"
153-
name="firstName"
154-
className="form-input"
155-
value={formData.firstName}
156-
onChange={handleInputChange}
157-
required
158-
/>
159-
) : (
160-
<p className="form-static">{formData.firstName}</p>
161-
)}
162-
</div>
163-
<div className="form-item">
164-
<label htmlFor="lastName" className="form-label">
165-
Last Name:
166-
</label>
167-
{isEditing ? (
168-
<input
169-
type="text"
170-
id="lastName"
171-
name="lastName"
172-
className="form-input"
173-
value={formData.lastName}
174-
onChange={handleInputChange}
175-
required
176-
/>
177-
) : (
178-
<p className="form-static">{formData.lastName}</p>
179-
)}
180-
</div>
181-
<div className="form-item">
182-
<label htmlFor="pronunciation" className="form-label">
183-
Pronunciation:
184-
</label>
185-
{isEditing ? (
186-
<input
187-
type="text"
188-
id="pronunciation"
189-
name="pronunciation"
190-
className="form-input"
191-
value={formData.pronunciation}
192-
onChange={handleInputChange}
193-
/>
194-
) : (
195-
<p className="form-static">{formData.pronunciation}</p>
196-
)}
136+
<div className="user-profile-page">
137+
<div className="user-profile-main">
138+
<div className="user-profile-item">
139+
{formData.profileImage?.trim() ? <img src={formData.profileImage} /> : <LogoNoText id="logo" />}
140+
{isEditing && <ImageUploader />}
197141
</div>
198-
<div className="form-item">
199-
<label htmlFor="pronouns" className="form-label">
200-
Pronouns:
201-
</label>
202-
{isEditing ? (
203-
<input
204-
type="text"
205-
id="pronouns"
206-
name="pronouns"
207-
className="form-input"
208-
value={formData.pronouns}
209-
onChange={handleInputChange}
210-
/>
211-
) : (
212-
<p className="form-static">{formData.pronouns}</p>
213-
)}
214-
</div>
215-
<div className="form-item">
216-
<label htmlFor="email" className="form-label">
217-
Email:
218-
</label>
219-
<p className="form-static">{requestedData?.email}</p>
220-
</div>
221-
<div className="form-item">
222-
<label htmlFor="bio" className="form-label">
223-
Bio:
224-
</label>
225-
{isEditing ? (
226-
<textarea id="bio" name="bio" className="form-input" value={formData.bio} onChange={handleInputChange} />
227-
) : (
228-
<p className="form-static">{formData.bio}</p>
229-
)}
230-
</div>
231-
<div className="form-actions">
232-
{validationText && (
233-
<div className="form-validation-container">
234-
<span className="form-validation-text">{validationText}</span>
142+
143+
<div className="user-profile-fields">
144+
<div className="user-profile-wrapper">
145+
<div className="user-profile-form">
146+
<div className="user-profile-item">
147+
<label htmlFor="firstName" className="form-label">
148+
First Name:
149+
</label>
150+
{isEditing ? (
151+
<input
152+
type="text"
153+
id="firstName"
154+
name="firstName"
155+
className="form-input"
156+
value={formData.firstName}
157+
onChange={handleInputChange}
158+
required
159+
/>
160+
) : (
161+
<p className="form-static">{formData.firstName}</p>
162+
)}
163+
</div>
164+
<div className="user-profile-item">
165+
<label htmlFor="lastName" className="form-label">
166+
Last Name:
167+
</label>
168+
{isEditing ? (
169+
<input
170+
type="text"
171+
id="lastName"
172+
name="lastName"
173+
className="form-input"
174+
value={formData.lastName}
175+
onChange={handleInputChange}
176+
required
177+
/>
178+
) : (
179+
<p className="form-static">{formData.lastName}</p>
180+
)}
181+
</div>
182+
</div>
183+
</div>
184+
<div className="user-profile-wrapper">
185+
<div className="user-profile-form">
186+
<div className="user-profile-item">
187+
{formData.pronunciation?.trim() && (
188+
<>
189+
<label htmlFor="pronunciation" className="form-label">
190+
Pronunciation:
191+
</label>
192+
<p className="form-static">{formData.pronunciation}</p>
193+
</>
194+
)}
195+
{isEditing && (
196+
<>
197+
<label htmlFor="pronunciation" className="form-label">
198+
Pronunciation:
199+
</label>
200+
<input
201+
type="text"
202+
id="pronunciation"
203+
name="pronunciation"
204+
className="form-input"
205+
value={formData.pronunciation}
206+
onChange={handleInputChange}
207+
/>
208+
</>
209+
)}
210+
</div>
211+
212+
<div className="user-profile-item">
213+
{formData.pronouns?.trim() && (
214+
<>
215+
<label htmlFor="pronouns" className="form-label">
216+
Pronouns:
217+
</label>
218+
<p className="form-static">{formData.pronouns}</p>
219+
</>
220+
)}
221+
{isEditing && (
222+
<>
223+
<label htmlFor="pronouns" className="form-label">
224+
Pronouns:
225+
</label>
226+
<input
227+
type="text"
228+
id="pronouns"
229+
name="pronouns"
230+
className="form-input"
231+
value={formData.pronouns}
232+
onChange={handleInputChange}
233+
/>
234+
</>
235+
)}
236+
</div>
237+
</div>
238+
</div>
239+
240+
<div className="user-profile-wrapper">
241+
<div className="user-profile-form">
242+
<div className="user-profile-item">
243+
<label htmlFor="email" className="form-label">
244+
Email:
245+
</label>
246+
<p className="form-static">{requestedData?.email}</p>
247+
</div>
248+
</div>
249+
</div>
250+
251+
<div className="user-profile-wrapper">
252+
<div className="user-profile-form">
253+
<div className="user-profile-item">
254+
{formData.bio?.trim() && (
255+
<>
256+
<label htmlFor="bio" className="form-label">
257+
Bio:
258+
</label>
259+
<p className="form-static">{formData.bio}</p>
260+
</>
261+
)}
262+
{isEditing && (
263+
<>
264+
<label htmlFor="bio" className="form-label">
265+
Bio:
266+
</label>
267+
<textarea
268+
id="bio"
269+
name="bio"
270+
className="form-input"
271+
value={formData.bio}
272+
onChange={handleInputChange}
273+
/>
274+
</>
275+
)}
276+
</div>
277+
</div>
278+
</div>
279+
280+
<div className="user-profile-wrapper">
281+
<div className="form-actions">
282+
{validationText && (
283+
<div className="form-validation-container">
284+
<span className="form-validation-text">{validationText}</span>
285+
</div>
286+
)}
287+
{isCurrUser &&
288+
(isEditing ? (
289+
<div className="user-profile-edit">
290+
<button className="primary-btn" onClick={handleCancelToggle}>
291+
Cancel
292+
</button>
293+
<button className="primary-btn" onClick={handleFormSubmit} disabled={showSaveSpinner}>
294+
{showSaveSpinner ? <LoadingSpinner /> : "Save"}
295+
</button>
296+
</div>
297+
) : (
298+
<button className="primary-btn" onClick={handleEditToggle}>
299+
Edit
300+
</button>
301+
))}
235302
</div>
236-
)}
237-
{isCurrUser &&
238-
(isEditing ? (
239-
<button className="primary-btn" onClick={handleFormSubmit} disabled={showSaveSpinner}>
240-
{showSaveSpinner ? <LoadingSpinner /> : "Save"}
241-
</button>
242-
) : (
243-
<button className="primary-btn" onClick={handleEditToggle}>
244-
Edit
245-
</button>
246-
))}
303+
</div>
247304
</div>
248305
</div>
249306
</div>

csm_web/frontend/src/css/profile.scss

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
@use "base/variables" as *;
2+
3+
.user-profile-page {
4+
display: flex;
5+
align-items: center;
6+
justify-content: center;
7+
}
8+
9+
.user-profile-main {
10+
display: flex;
11+
flex-direction: column;
12+
gap: 2rem;
13+
align-items: center;
14+
justify-content: center;
15+
width: 500px;
16+
padding: 48px;
17+
border: 2px solid $csm-green;
18+
border-radius: 25px;
19+
}
20+
21+
.user-profile-fields {
22+
display: flex;
23+
flex-direction: column;
24+
gap: 1rem;
25+
align-items: center;
26+
justify-content: center;
27+
}
28+
29+
.user-profile-wrapper {
30+
display: flex;
31+
gap: 2rem;
32+
}
33+
34+
.user-profile-form {
35+
display: flex;
36+
gap: 2rem;
37+
}
38+
39+
.user-profile-item {
40+
display: flex;
41+
gap: 1rem;
42+
align-items: center;
43+
}
44+
45+
.user-profile-item img {
46+
display: block;
47+
margin: 0 auto;
48+
}
49+
50+
.user-profile-edit {
51+
display: flex;
52+
gap: 2rem;
53+
}

0 commit comments

Comments
 (0)