Skip to content
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

feat: dynamic project tags UI and color generation system #136 #170

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from

Conversation

ussyalfaks
Copy link
Collaborator

@ussyalfaks ussyalfaks commented Feb 17, 2025

This PR implements the frontend components and logic for the dynamic project tags system, enabling users to create and manage tags with automatically generated colors.

Features Implemented

✅ Dynamic Color Generation for new tags
✅ Tag Normalization to PascalCase (supports separated words)
✅ Class Name Generation based on tag names
✅ Tag Management UI for creating, editing, and displaying tags
✅ State Management to handle tag data
✅ Consistent Tag Display with generated colors
✅ Error Handling and feedback for users

Technical Details

Tag Normalization: Converts tag names to PascalCase
Deterministic Color Generation: Ensures consistent colors for the same tag names
User Feedback: UI provides visual confirmation of tag creation, delete, edits, and updates

To view the implementation, navigate to:
📂 web/app/routes/project/create

Summary by CodeRabbit

  • New Features
    • Integrated a tag management interface into the project creation process, allowing users to add, edit, and remove project tags seamlessly.
    • Introduced an intuitive tag editing experience with real-time error feedback for improved user interactions.
    • Enhanced tags with customizable color properties, providing better visual distinction and consistency.

Copy link

vercel bot commented Feb 17, 2025

The latest updates on your projects. Learn more about Vercel for Git ↗︎

Name Status Preview Comments Updated (UTC)
kindfi ❌ Failed (Inspect) Feb 19, 2025 9:31am

Copy link

supabase bot commented Feb 17, 2025

This pull request has been ignored for the connected project gcqrhpprpqyfqabrhmla because there are no changes detected in services/supabase/supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

Copy link
Contributor

coderabbitai bot commented Feb 17, 2025

Walkthrough

This pull request implements new tag management functionality in the web application. A new ProjectTags component is added to the project creation page that leverages the useTags hook. In addition, new shared React components—TagEdit for editing and TagManager for adding, editing, and deleting tags—are introduced. The ProjectTag interface is updated with a new color property, and a utility module is added with helper functions for formatting tag names and generating accessible colors. These changes enable dynamic tag creation and management across the application.

Changes

File(s) Change Summary
apps/web/app/(routes)/project/create/page.tsx
apps/web/components/shared/tag-edit.tsx
apps/web/components/shared/tag-manager.tsx
New React components introduced for tag creation, editing, and management using the useTags hook.
apps/web/lib/types/project.types.ts Updated the ProjectTag interface to include a new color property with backgroundColor and textColor fields.
apps/web/lib/utils/tag-context.ts Added a new utility module providing the useTags hook alongside formatToPascalCase and getRandomAccessibleColor functions.

Sequence Diagram(s)

sequenceDiagram
    participant U as User
    participant PT as ProjectTags Component
    participant TM as TagManager Component
    participant HT as useTags Hook
    participant UT as Utility Functions

    U->>PT: Interact with tag UI
    PT->>TM: Render TagManager
    U->>TM: Submit new tag or request edit/remove
    TM->>HT: Invoke tag management (add/edit/remove)
    HT->>UT: Format tag name & get random color
    UT-->>HT: Return processed tag data
    HT-->>TM: Update tag list
    TM->>U: Refresh UI with updated tags
Loading

Possibly related PRs

Suggested labels

enhancement, webapp, documentation

Suggested reviewers

  • AndlerRL
  • Bran18

Poem

In the code’s realm, new tags take flight,
Colors and names now shine so bright,
Components align in harmonious art,
With hooks and utilities playing their part,
Cheers to clean code and tag delight! 😊

✨ Finishing Touches
  • 📝 Generate Docstrings (Beta)

Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@coderabbitai coderabbitai bot added documentation Improvements or additions to documentation enhancement New feature improvement or request webapp web app related labels Feb 17, 2025
Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (8)
apps/web/app/(routes)/project/create/page.tsx (1)

6-14: Consider passing tag management functions to TagManager.

The component correctly uses the useTags hook, but the retrieved functions (addTag, removeTag, updateTag) aren't being passed to the TagManager component. This could indicate that TagManager is internally using the same hook, which might lead to unnecessary hook duplications.

-			<TagManager />
+			<TagManager
+				tags={tags}
+				onAdd={addTag}
+				onRemove={removeTag}
+				onUpdate={updateTag}
+			/>
apps/web/components/shared/tag-edit.tsx (2)

19-19: Consider implementing the commented error state.

The commented error state suggests a planned feature. Implementing it would provide better user feedback beyond just toast notifications.

-// const [error, setError] = useState('')
+const [error, setError] = useState('')

21-36: Enhance form validation with proper error states.

The form validation could be more robust by setting error states and providing immediate feedback.

 const handleSubmit = useCallback(
   (e: React.FormEvent) => {
     e.preventDefault()
-    if (editedTag.trim()) {
+    const trimmedTag = editedTag.trim()
+    setError('')
+    
+    if (!trimmedTag) {
+      setError('Tag name cannot be empty')
+      toast.error('Tag name cannot be empty')
+      return
+    }
+    
+    const formattedNewTag = formatToPascalCase(trimmedTag)
+    if (formattedNewTag !== tag.text) {
       onUpdate(tag.id, formattedNewTag)
     } else {
       onCancel()
     }
-    } else {
-      toast.error('Tag name cannot be empty')
-    }
   },
-  [editedTag, tag, onUpdate, onCancel],
+  [editedTag, tag, onUpdate, onCancel, setError],
 )
apps/web/lib/utils/tag-context.ts (2)

33-42: Consider making color selection deterministic for consistent tag colors.

Currently, colors are randomly assigned. Making this deterministic based on the tag name would ensure consistent colors across sessions.

-export function getRandomAccessibleColor(): {
+export function getTagColor(tagName: string): {
   backgroundColor: string
   textColor: string
 } {
-  const randomIndex = Math.floor(Math.random() * ACCESSIBLE_COLORS.length)
+  // Use hash of tag name to determine color index
+  const hash = tagName.split('').reduce((acc, char) => {
+    return char.charCodeAt(0) + ((acc << 5) - acc)
+  }, 0)
+  const index = Math.abs(hash) % ACCESSIBLE_COLORS.length
   return {
-    backgroundColor: ACCESSIBLE_COLORS[randomIndex].bg,
-    textColor: ACCESSIBLE_COLORS[randomIndex].text,
+    backgroundColor: ACCESSIBLE_COLORS[index].bg,
+    textColor: ACCESSIBLE_COLORS[index].text,
   }
 }

47-63: Optimize tag addition with proper memoization.

The addTag callback has tags in its dependency array, which could cause unnecessary rerenders.

 const addTag = useCallback(
   (tagName: string) => {
     const formattedTag = formatToPascalCase(tagName)
-    if (!tags.some((tag) => tag.text === formattedTag)) {
-      const { backgroundColor, textColor } = getRandomAccessibleColor()
-      setTags((prevTags) => [
+    setTags((prevTags) => {
+      if (prevTags.some((tag) => tag.text === formattedTag)) {
+        return prevTags
+      }
+      const { backgroundColor, textColor } = getTagColor(formattedTag)
+      return [
         ...prevTags,
         {
           id: crypto.randomUUID(),
           text: formattedTag,
           color: { backgroundColor, textColor },
         },
-      ])
-    }
+      ]
+    })
   },
-  [tags],
+  [],
 )
apps/web/lib/types/project.types.ts (1)

35-38: Consider creating a dedicated type for tag colors.

The color object structure could be extracted into a reusable type, especially since it's used across multiple components.

+/** Interface representing tag color configuration */
+export interface TagColor {
+  /** Background color in hex format */
+  backgroundColor: string
+  /** Text color in hex format */
+  textColor: string
+}

 export interface ProjectTag {
   /** Unique identifier for the tag */
   id: string
   /** Display text for the tag */
   text: string
-  color: {
-    backgroundColor: string
-    textColor: string
-  }
+  /** Color configuration for the tag */
+  color: TagColor
 }
apps/web/components/shared/tag-manager.tsx (2)

12-17: Consider enhancing error handling implementation

The commented out error state suggests a potential enhancement opportunity. While toast notifications provide immediate feedback, consider implementing persistent error state for more complex error scenarios, such as validation errors that need to remain visible while the user corrects their input.

-	// const [error, setError] = useState('')
+	const [errors, setErrors] = useState<Record<string, string>>({})

54-108: Enhance user experience with additional states and confirmations

Consider implementing these UX improvements:

  1. Add loading states during tag operations
  2. Handle empty state when no tags exist
  3. Add confirmation dialog for tag deletion to prevent accidental removals
+			{tags.length === 0 && (
+				<p className="text-gray-500">No tags yet. Create your first tag above.</p>
+			)}

For the delete confirmation:

-								onClick={() => removeTag(tag.id)}
+								onClick={() => {
+									if (window.confirm(`Are you sure you want to delete "${tag.text}"?`)) {
+										removeTag(tag.id)
+									}
+								}}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 98f0e7d and b25abf6.

📒 Files selected for processing (5)
  • apps/web/app/(routes)/project/create/page.tsx (1 hunks)
  • apps/web/components/shared/tag-edit.tsx (1 hunks)
  • apps/web/components/shared/tag-manager.tsx (1 hunks)
  • apps/web/lib/types/project.types.ts (1 hunks)
  • apps/web/lib/utils/tag-context.ts (1 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
`**/*.ts`: Review TypeScript files ensuring type safety with...

**/*.ts: Review TypeScript files ensuring type safety with no 'any' usage unless justified. Verify named exports, proper error handling with typed errors, and pure functions. Check module encapsulation and consistent naming using camelCase for functions and PascalCase for types. Validate unit test coverage for utilities if required.

  • apps/web/lib/types/project.types.ts
  • apps/web/lib/utils/tag-context.ts
🔇 Additional comments (1)
apps/web/components/shared/tag-manager.tsx (1)

1-11: Well-structured imports and setup!

The imports are well-organized and each one serves a clear purpose in the component.

@Bran18 Bran18 requested review from Bran18 and AndlerRL and removed request for suhas-sensei February 17, 2025 16:14
@Bran18 Bran18 linked an issue Feb 17, 2025 that may be closed by this pull request
7 tasks
@AndlerRL
Copy link
Member

Hey @ussyalfaks I see some build fails, can you please check?

image

💡 Always do bun run build to check code integrity while building. Also make sure to have husky install by doing bun i -g husky && bun install in the root monorepo folder.

@AndlerRL
Copy link
Member

Hey @ussyalfaks I noticed that the first commit in your PR is still without a signature. Can you please check that out?

image

I will be sharing you a steps to follow to sign old commits:

Screenshot 2025-02-01 200730

⚠️ The commit hash in the steps is the first commit in the branch history.

cc - @Bran18

@Bran18
Copy link
Contributor

Bran18 commented Feb 21, 2025

@ussyalfaks did you check the suggestion and request from Andler?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature improvement or request webapp web app related
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Frontend: Implement Dynamic Project Tags UI and Color Generation
3 participants