Commit fd3b22b
authored
Feat/issue55 profile photo (#394)
## Description
This PR adds a new edit profile photo feature. Prior to this, RecNet
displays a user's Google account profile photo and does not allow
changes. This feature allows any RecNet user to upload a profile photo,
which is stored in an AWS S3 bucket and make updates to the user profile
information in the database.
## Related Issue
* See [PR#392](#392) for previous
comments and requested changes. Reopening PR for the same issue to merge
to `dev` before `master`.
## Frontend Changes
* Modified
`/apps/recnet/src/components/setting/profile/ProfileEditForm.tsx` adding
new form element and function:
* Added profile photo `<input>` element with a photo preview image to
accept and display the selected photo.
* Added `handleUploadS3` function to get a secure uploadUrl from the
backend, put objects to the S3 bucket, and update the form data.
* Modified the `onSubmit` function to call the `handleUploadS3` function
when a user saves the form.
* Updated the `ProfileEditSchema`, `useForm` hook to include the
photoUrl field.
* Added a `generateUploadUrlMutation` hook to send a request to the
backend to get a secure S3 upload URL.
* Added new state hooks `[isUploading, setIsUploading]`, `[selectedFile,
setSelectedFile]`, `[photoPreviewUrl, setPhotoPreviewUrl]` ,
`[fileError, setFileError]` to manage the selected photo and upload
status.
* Created a new router `generateS3UploadUrl` in the
`/apps/recnet/src/server/routers/user.ts`
* Modified the router `updateUser` in
`/apps/recnet/src/server/routers/user.ts` to fetch the original photoUrl
and delete the corresponding S3 file if a new profile photo is uploaded.
## Backend Changes
* Added a new folder `photo-storage` under
`/apps/recnet-api/src/modules`
* Created a `photo-storage.controler.ts` to handle requests to the
`photo-storage` endpoint.
* Created a `photo-storage.service.ts`. Included a `generateS3UploadUrl`
method and a `deleteS3Object` method.
* Created a `photo-storage.module.ts` to package and export the s3
class.
* Modified `common.config.ts` under `/apps/recnet-api/src/config` to
register AWS S3 configuration.
* Updated `env.schema.ts` under `/apps/recnet-api/src/config` to include
the s3 environment variable data types.
* Updated `app.module.ts` under `/apps/recnet-api/src` to include and
import the `PhotoStorageModule`.
## Other Changes
* Added `photo-storage.ts` under `/libs/recnet-api-model/src/lib/api` to
document the new APIs related to `photo-storage`.
* Updated `package.json` to include `aws-sdk/client-s3` and
`aws-sdk/s3-request-presigner` .
* Install aws-sdk: `@aws-sdk/client-s3 @aws-sdk/s3-request-presigner`.
Make sure to use aws-sdk v3.
## How To Test
1. Log in to your account.
2. Navigate to the Profile page.
3. Click on the "Settings" button and open the first tab "Edit profile".
4. Click on "Choose file" to choose a file and attach to the form.
5. Click on the "Save" button and wait for the upload to complete.
6. Check your profile photo and it should be updated to the new photo
you uploaded.
## Screenshots (if appropriate):
<img width="863" alt="1_profile-photo-before"
src="https://github.com/user-attachments/assets/608bfba6-883f-4fbd-a50f-329434d920f3"
/>
<img width="783" alt="2_edit-photo"
src="https://github.com/user-attachments/assets/38ed449d-d572-4259-b7f6-fe42a4a44664"
/>
<img width="799" alt="3_photo-attached"
src="https://github.com/user-attachments/assets/94b94372-5dfa-4c7d-9dba-5586850799f0"
/>
<img width="739" alt="4_uploading"
src="https://github.com/user-attachments/assets/8c3bc13c-e06b-40d9-b254-5648e78bfd8f"
/>
<img width="851" alt="5_photo-updated"
src="https://github.com/user-attachments/assets/a8267cfa-dd82-45ba-a6d6-11908eed4dcd"
/>
## TODO
- Add AWS S3 configurations in the `.env` file under `/apps/recnet-api`
for the dev and prod environment for deploymentFile tree
15 files changed
+1652
-141
lines changed- apps
- recnet-api
- src
- config
- modules/photo-storage
- utils/error
- recnet
- src
- components/setting/profile
- server/routers
- libs/recnet-api-model/src/lib/api
15 files changed
+1652
-141
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
26 | | - | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
8 | | - | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
9 | 9 | | |
10 | 10 | | |
11 | 11 | | |
| 12 | + | |
12 | 13 | | |
13 | 14 | | |
14 | 15 | | |
| |||
32 | 33 | | |
33 | 34 | | |
34 | 35 | | |
| 36 | + | |
35 | 37 | | |
36 | 38 | | |
37 | 39 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
33 | 38 | | |
34 | 39 | | |
35 | 40 | | |
| |||
Lines changed: 27 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
Lines changed: 10 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
Lines changed: 83 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
23 | 23 | | |
24 | 24 | | |
25 | 25 | | |
| 26 | + | |
| 27 | + | |
26 | 28 | | |
27 | 29 | | |
28 | 30 | | |
| |||
49 | 51 | | |
50 | 52 | | |
51 | 53 | | |
| 54 | + | |
| 55 | + | |
52 | 56 | | |
Lines changed: 109 additions & 3 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
10 | 10 | | |
11 | 11 | | |
12 | 12 | | |
| 13 | + | |
13 | 14 | | |
| 15 | + | |
14 | 16 | | |
15 | 17 | | |
16 | 18 | | |
| |||
61 | 63 | | |
62 | 64 | | |
63 | 65 | | |
| 66 | + | |
64 | 67 | | |
65 | 68 | | |
66 | 69 | | |
67 | 70 | | |
68 | 71 | | |
| 72 | + | |
| 73 | + | |
69 | 74 | | |
70 | 75 | | |
71 | 76 | | |
| |||
83 | 88 | | |
84 | 89 | | |
85 | 90 | | |
| 91 | + | |
86 | 92 | | |
87 | 93 | | |
88 | 94 | | |
| |||
92 | 98 | | |
93 | 99 | | |
94 | 100 | | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
95 | 139 | | |
96 | 140 | | |
97 | 141 | | |
| |||
104 | 148 | | |
105 | 149 | | |
106 | 150 | | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
107 | 155 | | |
108 | | - | |
| 156 | + | |
109 | 157 | | |
110 | 158 | | |
111 | 159 | | |
| |||
183 | 231 | | |
184 | 232 | | |
185 | 233 | | |
| 234 | + | |
| 235 | + | |
| 236 | + | |
| 237 | + | |
| 238 | + | |
| 239 | + | |
| 240 | + | |
| 241 | + | |
| 242 | + | |
| 243 | + | |
| 244 | + | |
| 245 | + | |
| 246 | + | |
| 247 | + | |
| 248 | + | |
| 249 | + | |
| 250 | + | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
| 259 | + | |
| 260 | + | |
| 261 | + | |
| 262 | + | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
| 269 | + | |
| 270 | + | |
| 271 | + | |
| 272 | + | |
| 273 | + | |
| 274 | + | |
| 275 | + | |
| 276 | + | |
| 277 | + | |
| 278 | + | |
| 279 | + | |
| 280 | + | |
| 281 | + | |
| 282 | + | |
| 283 | + | |
| 284 | + | |
| 285 | + | |
| 286 | + | |
| 287 | + | |
| 288 | + | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
186 | 292 | | |
187 | 293 | | |
188 | 294 | | |
| |||
313 | 419 | | |
314 | 420 | | |
315 | 421 | | |
316 | | - | |
| 422 | + | |
317 | 423 | | |
318 | | - | |
| 424 | + | |
319 | 425 | | |
320 | 426 | | |
321 | 427 | | |
| |||
0 commit comments