-
Notifications
You must be signed in to change notification settings - Fork 0
feat(admin): merge duplicate artists #15
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
8d23cac to
c6fc73a
Compare
- Split ArtistComparisonModal (509 lines) into smaller components: - ArtistComparisonCard: displays individual artist comparison data - MergePreviewDialog: handles merge preview and confirmation - FieldSelector & GenreSelector: reusable field selection components - Split BulkMergeDialog (304 lines) into smaller components: - BulkMergeStrategySelector: strategy selection interface - BulkMergeProgressDialog: progress tracking during merge - BulkMergeCompleteDialog: completion status and results Improves maintainability by following the guideline to extract substantial sections (>30 lines) into focused components and keep components under 150 lines. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
- Split ArtistBulkEditor (470 lines → ~120 lines) into focused components: - BulkEditorHeader: title, badges, and action buttons - BulkEditorSearchAndActions: search and bulk actions toolbar - BulkEditorTable: table with header and row components - BulkEditorFooter: statistics display - BulkEditorLoadingState: loading UI - Extracted business logic into specialized custom hooks: - useArtistSorting: type-safe sorting with multi-field support - useArtistFiltering: search/filter with memoized results - useArtistSelection: selection state management - useArtistChangeTracking: low-level change tracking (single responsibility) - useArtistMutations: high-level mutations combining change tracking - Achieved full type safety: - Generic ArtistChange<T> type with proper field constraints - No `any` types - all operations properly typed - Type-safe field mutations with Artist[T] constraints - Proper null handling for optional fields Each component/hook has single responsibility, enabling better testing, reusability, and maintainability. All functionality preserved while significantly improving code organization and type safety. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
- Hide export button (not implemented)
- Create efficient useBulkArchiveArtistsMutation using .in() for single query
- Add ArchiveButton component with confirmation dialog
- Update BulkActionsToolbar to use dedicated ArchiveButton
- Pass selectedIds through component hierarchy
Features:
- Single database query using .in("id", artistIds) for performance
- Confirmation dialog with proper pluralization
- Loading states during archive operation
- Automatic selection clearing on success
- Error handling with toast notifications
- Clean separation of concerns with dedicated ArchiveButton
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull Request Overview
This PR implements a comprehensive duplicate artist management system with bulk merging capabilities. It transforms the existing simple artist management interface into a sophisticated bulk editor with duplicate detection and merge functionality.
- Replaces the basic artist management table with a full-featured bulk editor supporting inline editing
- Adds a duplicate artist detection system that groups artists by name and provides merge strategies
- Implements timezone-aware CSV import functionality for better handling of event times
Reviewed Changes
Copilot reviewed 44 out of 44 changed files in this pull request and generated 5 comments.
Show a summary per file
| File | Description |
|---|---|
| src/services/csvImportService.ts | Adds timezone conversion functionality for proper UTC storage of imported event times |
| src/pages/admin/festivals/CSVImportDialog.tsx | Adds timezone selector UI component for CSV imports |
| src/pages/admin/ArtistsManagement/ | Complete rewrite from simple table to modular bulk editor with hooks-based architecture |
| src/hooks/queries/artists/ | New hooks for duplicate detection, merging, and bulk operations |
| src/components/router/ | Updates routing to support new duplicate management page |
| .oxlintrc.json | Adds TypeScript strict typing rule |
| // Helper function to add member counts to groups | ||
| async function addMemberCounts( | ||
| groups: any[], | ||
| groups: Group[], |
Copilot
AI
Sep 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type annotation should be Promise<Group[]> since this function returns a Promise. The current annotation suggests it returns the array directly.
| shouldFetchAll: boolean, | ||
| userGroupIds: string[], | ||
| ): Promise<any[]> { | ||
| ) { |
Copilot
AI
Sep 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Function is missing a return type annotation. Based on the context, this should return Promise<any[]> or preferably a more specific type.
| ) { | |
| ): Promise<Group[]> { |
| onError: (error: any) => { | ||
| if (error.code === "23505") { | ||
| onError: (error) => { | ||
| if ("code" in error && error.code === "23505") { |
Copilot
AI
Sep 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The type guard check should be more robust. Consider using a proper error type or checking for PostgreSQL error structure more specifically.
| onConfirm={() => { | ||
| // TODO: Implement bulk save | ||
| console.log("Saving changes:", changes); | ||
| resetChanges(); | ||
| setShowChangePreview(false); |
Copilot
AI
Sep 5, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TODO comment indicates incomplete functionality. The bulk save operation should be implemented before merging to production.
| onConfirm={() => { | |
| // TODO: Implement bulk save | |
| console.log("Saving changes:", changes); | |
| resetChanges(); | |
| setShowChangePreview(false); | |
| onConfirm={async () => { | |
| try { | |
| await bulkUpdateArtists(changes); | |
| resetChanges(); | |
| setShowChangePreview(false); | |
| } catch (error) { | |
| console.error("Failed to save changes:", error); | |
| // Optionally, show error feedback to the user here | |
| } |
No description provided.