Skip to content

Add groups#196

Open
tenkus47 wants to merge 3 commits into
devfrom
add-groups
Open

Add groups#196
tenkus47 wants to merge 3 commits into
devfrom
add-groups

Conversation

@tenkus47
Copy link
Copy Markdown
Member

No description provided.

tenkus47 added 3 commits May 28, 2026 23:23
- Updated package version to 2026.05.28.1200.
- Introduced new routes for managing groups, including group creation, editing, and details pages.
- Enhanced the Navbar to include a link for groups management.
- Modified PlanTagSearchInput to conditionally hide the label.
- Replaced error handling in Tags component to utilize a centralized API error message function.
- Added PlanAudioDTO and PlanAudioListResponse interfaces for audio data handling.
- Implemented fetchPlanAudioList function to retrieve audio files associated with plans.
- Introduced attachDayAudio function to link audio files to specific days.
- Updated TaskForm to include plan title in DayAudioSection.
- Integrated PlanAudioSearchInput component for searching existing audio files in DayAudioSection.
- Improved user instructions for audio uploads and management in the UI.
…sk management

- Added new API functions for creating multiple days and bulk deleting days.
- Updated the SideBar component to support day selection mode for bulk actions.
- Enhanced the DayDeleteDialog to handle bulk deletion.
- Refactored usePlanMutations to integrate new API functions for creating and deleting days.
- Improved user experience with feedback messages for successful and failed operations.
@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented May 29, 2026

Confidence Score: 3/5

The groups form has several correctness gaps visible to users immediately after merging: no existing avatar shown when editing, plan titles displayed as raw IDs, and uploads attempted with an empty group ID for new groups.

Four distinct defects on the new groups edit path affect core workflows that users will hit on first use of the feature.

src/components/routes/groups/GroupFormPage.tsx and src/lib/constant.ts

Reviews (1): Last reviewed commit: "feat(task): implement bulk delete and cr..." | Re-trigger Greptile

Comment thread src/lib/constant.ts
Comment on lines 20 to 23
export const SOCIAL_PLATFORMS = [
{ value: "facebook", label: "Facebook", icon: "Facebook" },
{ value: "SignIn", label: "SignIn", icon: "SignIn" },
{ value: "x.com", label: "X (Twitter)", icon: "Twitter" },
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Erroneous "SignIn" social platform entry

"SignIn" is not a social platform and appears to be an accidental addition. It will show up in the platform dropdown in GroupSocialLinksEditor as a real option for every group's social links, producing malformed data.

Suggested change
export const SOCIAL_PLATFORMS = [
{ value: "facebook", label: "Facebook", icon: "Facebook" },
{ value: "SignIn", label: "SignIn", icon: "SignIn" },
{ value: "x.com", label: "X (Twitter)", icon: "Twitter" },
export const SOCIAL_PLATFORMS = [
{ value: "facebook", label: "Facebook", icon: "Facebook" },
{ value: "x.com", label: "X (Twitter)", icon: "Twitter"},

Comment on lines +357 to +394
render={({ field }) => (
<Pecha.FormItem className="flex items-center gap-3">
<Pecha.FormControl>
<Pecha.Checkbox
checked={field.value}
onCheckedChange={(checked) =>
field.onChange(checked === true)
}
/>
</Pecha.FormControl>
<Pecha.FormLabel className="text-sm font-bold !mt-0">
Public group
</Pecha.FormLabel>
</Pecha.FormItem>
)}
/>
<div className="space-y-4">
{addedLanguages.map((code) => (
<div
key={code}
className="relative rounded-lg border border-input bg-[#FAFAFA] dark:bg-[#262626] p-4 space-y-3"
>
<button
type="button"
onClick={() => removeLanguage(code)}
className="absolute top-2 right-2 text-muted-foreground hover:text-foreground p-1"
aria-label={`Remove ${languageLabelForCode(code)}`}
>
<IoMdClose className="h-4 w-4" />
</button>
<Pecha.FormField
control={form.control}
name={`languages.${code}.title`}
render={({ field }) => (
<Pecha.FormItem>
<Pecha.FormLabel className="text-sm font-bold">
{languageLabelForCode(code)} title
</Pecha.FormLabel>
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Plan titles show as IDs due to hydration race condition

The hydration effect guards on hydratedRef.current === groupData.id to avoid running twice, but planOptions is an async query that may arrive after groupData. When that happens, the effect runs with planOptions = [], sets hydratedRef, and when planOptions finally populates (triggering the effect again), the hydratedRef guard returns early — leaving selectedPlans filled with raw IDs as titles via the titleById.get(id) ?? id fallback.

The series_ids hydration correctly avoids this by using a separate useEffect that fetches titles independently; the plan_ids side needs the same treatment.

Comment on lines +380 to +387
type="button"
onClick={() => removeLanguage(code)}
className="absolute top-2 right-2 text-muted-foreground hover:text-foreground p-1"
aria-label={`Remove ${languageLabelForCode(code)}`}
>
<IoMdClose className="h-4 w-4" />
</button>
<Pecha.FormField
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Existing avatar URL never loaded into preview state

During hydration, setBannerPreview(resolveGroupBannerUrl(groupData)) is called so the banner shows correctly on the edit page, but there is no equivalent call for the avatar — setAvatarPreview(...) is never populated from groupData.avatar. As a result, the "Avatar" field always shows empty when editing an existing group that already has an avatar, until the user uploads a new one.


setUploading(true);
try {
const { image, key } = await uploadImageToS3(file, groupId ?? "");
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Image upload passes empty string as groupId for new groups

When isNew is true, groupId is undefined, so uploadImageToS3(file, groupId ?? "") sends "" to the upload API. If the server uses this parameter for path/ownership resolution, the upload may be rejected or filed under an unowned S3 prefix. The image upload dialogs are rendered unconditionally so a user can trigger this code path before creating the group.

Suggested change
const { image, key } = await uploadImageToS3(file, groupId ?? "");
if (!groupId) {
toast.error("Save the group first before uploading images");
return;
}
const { image, key } = await uploadImageToS3(file, groupId);

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.

1 participant