Skip to content

Conversation

@jansm04
Copy link
Contributor

@jansm04 jansm04 commented Dec 6, 2025

Implemented the first chunk of the profile settings page. Still need to add profile picture updating once the endpoint is done.

image image

Copy link
Collaborator

@theosiemensrhodes theosiemensrhodes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Look at term-form.tsx and the upload-profile section of edit classes. Otherwise good but you should rebase off of main and look at those for guidance

theosiemensrhodes and others added 5 commits January 12, 2026 18:47
* 112 - Added FullCalendar boilerplate

Schedule page now shows default fullcalendar component

* 112 - added current day styling for schedule

* 112 - implemented day view toggling based on window width

* Added day header for narrower views

* Split code into multiple files

* Fixed styling issues

* Added CalendarAside

* Day view now triggers based on CALENDAR width

* Added list view dropdown

* Added volunteers to schedule aside

* wip integrating list and calendar views

* Added meeting link in schedule aside

* Fixed day view not activating on page shrink

* upgrade: rebase main

* fetch real shifts

* feat: schedule calendarstyles, minor class page bugs

* create check-in, cancel, and request coverage buttons

* componentize calendar

* make controls reactive

* feat: request coverage button

* chore: upgrade drizzle

---------

Co-authored-by: Felix Ma <112669786+felixma9@users.noreply.github.com>
Co-authored-by: edlng <edwardliangedli@gmail.com>
@jansm04
Copy link
Contributor Author

jansm04 commented Jan 29, 2026

@theosiemensrhodes FYI renamed use-class-image-upload.ts to use-image-upload.ts and moved it to the root /hooks folder, since im using it for the profile form as well

@theosiemensrhodes
Copy link
Collaborator

@jansm04 is there anything you need from me endpoint wise? I saw you mentioned it's a blocker in the description

@jansm04
Copy link
Contributor Author

jansm04 commented Jan 30, 2026

@theosiemensrhodes nope should be all good now

@theosiemensrhodes theosiemensrhodes linked an issue Jan 30, 2026 that may be closed by this pull request
@theosiemensrhodes
Copy link
Collaborator

Hey @jansm04 so just tested it and it seems to not work for admins/instructors. We should just hide the fields besides the essential ones (first/last name, email, photo). If it makes it easier you can split it up to have 2 separate sections of info. Maybe profile for all and personal information for volunteers.

You should be able to use authClient.useSession() to grab the current user's info and the update it with authClient.updateUser(). And then use the other volunteer api only for volunteers.

@theosiemensrhodes
Copy link
Collaborator

@greptile

@greptile-apps
Copy link

greptile-apps bot commented Jan 31, 2026

Greptile Overview

Greptile Summary

This PR implements a basic volunteer profile settings page that allows users to edit their personal information including name, email, pronouns, location, bio, and profile picture.

Key Changes:

  • Created comprehensive profile form with React Hook Form and Zod validation
  • Added profile image upload with drag-and-drop, automatic cropping to 512x512, and WebP conversion
  • Implemented transaction-based backend update splitting changes between user and volunteer tables
  • Changed API permissions from users:view to profile:view for better access control
  • Proper blob URL cleanup in image component to prevent memory leaks

Issues Found:

  • Critical type mismatch in profile image component where undefined is used instead of null, conflicting with the schema definition
  • Use of deprecated Zod .nonempty() method instead of .min(1) in validation schema

Confidence Score: 4/5

  • This PR is mostly safe to merge with minor type consistency issues that should be fixed
  • The implementation is well-structured with proper form validation, error handling, and database transactions. However, there's a type mismatch in the image input component that could cause validation errors, and deprecated Zod methods should be updated. The backend changes are solid with proper transaction handling.
  • Pay close attention to src/components/settings/pages/profile/content/profile-image-input.tsx for the null/undefined type mismatch

Important Files Changed

Filename Overview
src/components/settings/pages/profile/schema.ts Added Zod validation schema for profile form with required fields (firstName, lastName, email) and optional fields
src/components/settings/pages/profile/hooks/use-profile-upsert.ts Added custom hook for profile updates with image upload handling and session refetch
src/components/settings/pages/profile/content/profile-image-input.tsx Added profile image upload component with drag-and-drop, image cropping, and blob URL cleanup; potential issue with clearing image
src/server/services/entity/volunteerService.ts Updated profile update logic to use transaction and split updates between user and volunteer tables
src/models/api/volunteer.ts Changed image field in UpdateVolunteerInput from optional to nullish to properly handle image clearing

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

5 files reviewed, 5 comments

Edit Code Review Agent Settings | Greptile

type="button"
size="sm"
variant="outline"
onClick={() => setValue("image", undefined, { shouldDirty: true })}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Image cleared to undefined but schema expects null. The schema defines image: z.string().nullable(), but this sets it to undefined. This mismatch could cause validation issues.

Suggested change
onClick={() => setValue("image", undefined, { shouldDirty: true })}
onClick={() => setValue("image", null, { shouldDirty: true })}
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/components/settings/pages/profile/content/profile-image-input.tsx
Line: 97:97

Comment:
Image cleared to `undefined` but schema expects `null`. The schema defines `image: z.string().nullable()`, but this sets it to `undefined`. This mismatch could cause validation issues.

```suggestion
            onClick={() => setValue("image", null, { shouldDirty: true })}
```

How can I resolve this? If you propose a fix, please make it concise.

shouldTouch: true,
});
} else {
setValue("image", undefined);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting to undefined when file is invalid, but schema expects null. This should be null to match the schema definition.

Suggested change
setValue("image", undefined);
setValue("image", null);
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/components/settings/pages/profile/content/profile-image-input.tsx
Line: 76:76

Comment:
Setting to `undefined` when file is invalid, but schema expects `null`. This should be `null` to match the schema definition.

```suggestion
          setValue("image", null);
```

How can I resolve this? If you propose a fix, please make it concise.

import { z } from "zod";

export const ProfileSchema = z.object({
firstName: z.string().nonempty("Please enter your first name."),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using deprecated .nonempty(). Replace with .min(1) as nonempty() is deprecated in newer Zod versions.

Suggested change
firstName: z.string().nonempty("Please enter your first name."),
firstName: z.string().min(1, "Please enter your first name."),
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/components/settings/pages/profile/schema.ts
Line: 4:4

Comment:
Using deprecated `.nonempty()`. Replace with `.min(1)` as `nonempty()` is deprecated in newer Zod versions.

```suggestion
  firstName: z.string().min(1, "Please enter your first name."),
```

How can I resolve this? If you propose a fix, please make it concise.


export const ProfileSchema = z.object({
firstName: z.string().nonempty("Please enter your first name."),
lastName: z.string().nonempty("Please enter your last name."),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using deprecated .nonempty(). Replace with .min(1).

Suggested change
lastName: z.string().nonempty("Please enter your last name."),
lastName: z.string().min(1, "Please enter your last name."),
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/components/settings/pages/profile/schema.ts
Line: 5:5

Comment:
Using deprecated `.nonempty()`. Replace with `.min(1)`.

```suggestion
  lastName: z.string().min(1, "Please enter your last name."),
```

How can I resolve this? If you propose a fix, please make it concise.

email: z
.string()
.email("Please enter a valid email address.")
.nonempty("Email is required."),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using deprecated .nonempty(). Replace with .min(1).

Suggested change
.nonempty("Email is required."),
.min(1, "Email is required."),
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/components/settings/pages/profile/schema.ts
Line: 9:9

Comment:
Using deprecated `.nonempty()`. Replace with `.min(1)`.

```suggestion
    .min(1, "Email is required."),
```

How can I resolve this? If you propose a fix, please make it concise.

@jansm04
Copy link
Contributor Author

jansm04 commented Feb 4, 2026

@theosiemensrhodes Ok should be fixed in my most recent commit. Idk if thats the cleanest way to do it but lmk if its alright. Also noticed that authClient.updateUser() doesn't allow email to be updated. Is that expected? For now I just disabled the email field on admin/instructor side so they can see it but not change it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Start the profile section of the settings dialog

2 participants