Skip to content

rename employees route, and fix employee details styling#216

Merged
Marfuen merged 5 commits into
mainfrom
mariano/cleanup
Mar 28, 2025
Merged

rename employees route, and fix employee details styling#216
Marfuen merged 5 commits into
mainfrom
mariano/cleanup

Conversation

@Marfuen

@Marfuen Marfuen commented Mar 28, 2025

Copy link
Copy Markdown
Contributor

Summary by CodeRabbit

  • New Features

    • Introduced new actions and UI components for updating and viewing employee details, departments, and statuses.
    • Launched dedicated employee details and dashboard pages with localization support for seamless navigation.
  • Refactor

    • Standardized naming and routes by replacing "people" with "employees" throughout the app.
    • Updated menu labels, sidebar text, and URL links while removing legacy components tied to the old naming convention.

@vercel

vercel Bot commented Mar 28, 2025

Copy link
Copy Markdown

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

Name Status Preview Comments Updated (UTC)
app ✅ Ready (Inspect) Visit Preview 💬 Add feedback Mar 28, 2025 3:00pm
1 Skipped Deployment
Name Status Preview Comments Updated (UTC)
comp-portal ⬜️ Skipped (Inspect) Mar 28, 2025 3:00pm

@coderabbitai

coderabbitai Bot commented Mar 28, 2025

Copy link
Copy Markdown

Walkthrough

This pull request refactors various parts of the application by shifting terminology and URL paths from "people" to "employees." It updates revalidation paths, navigation links, and localization keys, while introducing new actions and React components for updating employee details, department, and status. Additionally, obsolete components and pages under the "people" namespace have been removed and replaced with their "employees" counterparts. Authentication, input validation, and revalidation flows are maintained with minor adjustments.

Changes

Files Change Summary
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/actions/update-department.ts, .../employees/all/components/table/EmployeesTable.tsx, .../employees/layout.tsx, apps/app/src/components/main-menu.tsx, apps/app/src/components/sheets/invite-user-sheet.tsx, .../tables/people/data-table.tsx, .../tables/people/empty-states.tsx, apps/app/src/locales/layout/sidebar.ts Updated URL paths and names from "people" to "employees" for revalidation, navigation, and localization.
.../employees/[employeeId]/actions/update-employee-details.ts, .../employees/[employeeId]/actions/update-employee-status.ts, .../employees/[employeeId]/actions/update-employee.ts Introduced new action files for updating employee details, status, and general employee data with input validation and database operations.
.../employees/[employeeId]/components/EditableDepartment.tsx, .../employees/[employeeId]/components/EditableDetails.tsx, .../employees/[employeeId]/components/EditableStatus.tsx, .../employees/[employeeId]/components/EmployeeDetails.tsx Added new React components for handling employee department changes, displaying details, updating status, and presenting comprehensive employee information.
.../employees/[employeeId]/page.tsx, .../(dashboard)/[orgId]/page.tsx Created new pages for employee details and dashboard redirection with localization, authentication, and metadata handling.
.../people/[employeeId]/components/EditableDepartment.tsx, .../people/[employeeId]/components/EmployeeDetails.tsx, .../people/[employeeId]/page.tsx Removed obsolete "people" components and pages, superseded by the new "employees" implementations.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant UI
    participant Action
    participant DB
    participant Cache

    User->>UI: Initiate update (e.g., detail or status change)
    UI->>Action: Invoke updateEmployeeDetails/updateEmployeeStatus
    Action->>DB: Validate session & fetch employee data
    DB-->>Action: Return employee data or error
    Action->>DB: Update employee record (if applicable)
    DB-->>Action: Acknowledge update
    Action->>Cache: Trigger revalidation of paths
    Action-->>UI: Return success or error response
Loading
sequenceDiagram
    participant User
    participant DashboardPage
    participant Auth
    participant Router

    User->>DashboardPage: Request dashboard
    DashboardPage->>Auth: Retrieve session details
    Auth-->>DashboardPage: Return organizationId (or missing)
    alt organizationId present
        DashboardPage->>Router: Redirect to "/<orgId>/overview"
    else organizationId missing
        DashboardPage->>Router: Redirect to "/"
    end
Loading

Possibly related PRs

  • Organization Switcher #165: The changes in the main PR, specifically the updates to the revalidatePath calls in the updateEmployeeDepartment function, are related to the modifications in the retrieved PR, which also involves the use of revalidatePath in the changeOrganizationAction function. Both PRs focus on revalidating paths after updates, indicating a shared functionality in managing employee and organization data.

Poem

I'm a rabbit hopping on the code,
Shifting paths and lightening the load.
From "people" to "employees" we glide,
With endpoints and interfaces redefined.
Leaping through changes with a joyful beat,
Hop on, dear coder—our update is neat! 🐇
Enjoy the journey on this wired street!

✨ Finishing Touches
  • 📝 Generate Docstrings

🪧 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.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai plan to trigger planning for file edits and PR creation.
  • @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 left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (14)
apps/app/src/components/tables/people/empty-states.tsx (1)

38-38: Router path updated correctly, but consider additional consistency improvements

The navigation path has been updated from people to employees as expected, but there are several inconsistencies that could be addressed:

  1. The file itself is still in a people directory (components/tables/people/)
  2. Translation keys still use the people prefix (e.g., people.empty.no_results.title)
  3. Component names haven't been updated (e.g., NoEmployees has always been using the term "employees")

Consider updating these for complete consistency in the renaming effort.

apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/layout.tsx (1)

20-23: Menu paths updated correctly, but translation keys could be updated too

The navigation paths have been properly updated from people to employees. However, the translation keys in lines 21 and 23 still use the people prefix:

label: t("people.dashboard.title")
label: t("people.all")

Consider updating these translation keys to use an employees prefix for complete consistency in the renaming effort.

apps/app/src/components/sheets/invite-user-sheet.tsx (1)

3-3: Import path updated but translation keys remain unchanged.

The import path has been correctly updated to use "employees" instead of "people", which aligns with the PR objective. However, there are multiple translation keys throughout the component (lines 61, 76, 77, 84, 87, 95, 98, 108, 116, 137, 138) that still use the "people" namespace. Consider updating these translation keys to maintain consistency between code structure and UI text.

apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/actions/update-employee-status.ts (1)

9-9: Update import path to align with "employees" naming convention.

The import on line 9 still references the "people" namespace:

import type { EmployeeStatusType } from "@/components/tables/people/employee-status";

For consistency with the PR's goal of renaming from "people" to "employees", consider updating this import path.

apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/components/EmployeeDetails.tsx (4)

50-78: Consider refactoring state management and change detection logic.

The component initializes multiple state variables and uses multiple useEffect hooks to track changes. This could be simplified to improve readability and maintainability.

Consider combining related state variables into a single object and using a reducer pattern:

- const [department, setDepartment] = useState<Departments | null>(null);
- const [status, setStatus] = useState<EmployeeStatusType | null>(null);
- const [hasChanges, setHasChanges] = useState(false);
+ const [state, dispatch] = useReducer(reducer, {
+   department: null as Departments | null,
+   status: null as EmployeeStatusType | null,
+   hasChanges: false
+ });

This would simplify the change tracking logic and reduce the number of re-renders.


133-162: The save handler could be simplified and better error handling added.

The current implementation has multiple nested conditions and could be streamlined for clarity.

Consider this revised implementation:

const handleSave = async () => {
  setIsSaving(true);
  try {
    // Prepare update data
    const updateData = { employeeId };
    
-   // Only include changed fields
-   if (department && department !== employee.department) {
-     updateData.department = department;
-   }
-
-   if (status) {
-     const isActive = status === "active";
-     if (isActive !== employee.isActive) {
-       updateData.isActive = isActive;
-     }
-   }
+   // Only include changed fields using spread operator
+   if (department && department !== employee.department) {
+     Object.assign(updateData, { department });
+   }
+
+   if (status) {
+     const isActive = status === "active";
+     if (isActive !== employee.isActive) {
+       Object.assign(updateData, { isActive });
+     }
+   }

    // Execute the update
    await execute(updateData);
  } catch (error) {
-   toast.error("Failed to update employee details");
+   console.error("Save error:", error);
+   toast.error(error instanceof Error ? error.message : "Failed to update employee details");
  } finally {
    setIsSaving(false);
  }
};

283-298: Implement the Remind button functionality.

The Remind button doesn't appear to have any functionality implemented.

Would you like me to suggest an implementation for the Remind button functionality for employee tasks?


280-302: Missing empty state for tasks list.

There's no UI handling for when the tasks array is empty, which could lead to a confusing user experience.

Add an empty state message when there are no tasks:

<CardContent className="flex flex-col gap-2">
+  {tasks.length === 0 && (
+    <div className="text-center p-4 text-muted-foreground">
+      No tasks assigned to this employee.
+    </div>
+  )}
  {tasks.map((task) => {
    const isCompleted = task.status === "completed";
    
    return (
      // ... existing code
    );
  })}
</CardContent>
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/actions/update-employee.ts (2)

44-57: Consider adding a more specific error message for employee not found.

The current error message is generic. Since you have access to the employeeId, consider adding it to the error message.

if (!employee) {
  return {
    success: false,
-   error: appErrors.NOT_FOUND,
+   error: {
+     ...appErrors.NOT_FOUND,
+     message: `Employee with ID ${employeeId} not found`
+   },
  };
}

95-101: Consider adding more detailed error logging.

The current error logging is minimal. It would be helpful to add more details for debugging purposes.

} catch (error) {
- console.error("Error updating employee:", error);
+ console.error(`Error updating employee ${employeeId}:`, error);
+ if (error instanceof Error) {
+   console.error("Stack trace:", error.stack);
+ }
  return {
    success: false,
    error: appErrors.UNEXPECTED_ERROR,
  };
}
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/components/EditableDepartment.tsx (1)

50-53: Save handler doesn't check if department has changed.

The save handler executes even if the department hasn't changed, which could lead to unnecessary API calls.

const handleSave = () => {
+  if (department === currentDepartment) {
+    return;
+  }
  execute({ employeeId, department });
};
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/components/EditableStatus.tsx (3)

11-11: Unused import detected.

The Button component is imported but never used in this component. Consider removing this unused import to maintain clean code.

-import { Button } from "@bubba/ui/button";

16-16: Unused import detected.

The EMPLOYEE_STATUS_TYPES is imported but never utilized in this component.

-import {
-	EMPLOYEE_STATUS_TYPES,
-	getEmployeeStatusFromBoolean,
-} from "@/components/tables/people/employee-status";
+import {
+	getEmployeeStatusFromBoolean,
+} from "@/components/tables/people/employee-status";

40-50: Consider adding loading state feedback.

The action status is captured but not utilized to provide visual feedback to users. Consider disabling the UI or showing a loading indicator during the update process.

const { execute, status: actionStatus } = useAction(updateEmployeeStatus, {
	onSuccess: () => {
		toast.success("Employee status updated successfully");
		onSuccess?.();
	},
	onError: (error) => {
		toast.error(
			error?.error?.serverError || "Failed to update employee status",
		);
	},
});
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between bfb6190 and 07a0b18.

📒 Files selected for processing (20)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/actions/update-department.ts (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/actions/update-employee-details.ts (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/actions/update-employee-status.ts (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/actions/update-employee.ts (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/components/EditableDepartment.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/components/EditableDetails.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/components/EditableStatus.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/components/EmployeeDetails.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/page.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/all/components/table/EmployeesTable.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/layout.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/page.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/people/[employeeId]/components/EditableDepartment.tsx (0 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/people/[employeeId]/components/EmployeeDetails.tsx (0 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/people/[employeeId]/page.tsx (0 hunks)
  • apps/app/src/components/main-menu.tsx (1 hunks)
  • apps/app/src/components/sheets/invite-user-sheet.tsx (1 hunks)
  • apps/app/src/components/tables/people/data-table.tsx (1 hunks)
  • apps/app/src/components/tables/people/empty-states.tsx (1 hunks)
  • apps/app/src/locales/layout/sidebar.ts (1 hunks)
💤 Files with no reviewable changes (3)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/people/[employeeId]/components/EditableDepartment.tsx
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/people/[employeeId]/components/EmployeeDetails.tsx
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/people/[employeeId]/page.tsx
🧰 Additional context used
🧬 Code Definitions (3)
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/actions/update-employee.ts (2)
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/types/index.ts (1)
  • appErrors (45-58)
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/types.ts (1)
  • appErrors (8-17)
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/components/EditableStatus.tsx (1)
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/actions/update-employee-status.ts (1)
  • updateEmployeeStatus (16-84)
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/components/EditableDepartment.tsx (1)
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/actions/update-department.ts (1)
  • updateEmployeeDepartment (18-80)
🔇 Additional comments (26)
apps/app/src/locales/layout/sidebar.ts (1)

9-11: Terminology update looks good!

The change from "people" to "employees" is consistent with the PR objective to rename the route. The semicolon addition also improves code style consistency.

apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/all/components/table/EmployeesTable.tsx (1)

30-30: Router path update looks good!

The navigation path has been correctly updated from people to employees to maintain consistency with the route renaming.

apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/page.tsx (1)

1-13: Appropriate dashboard page implementation with redirection logic.

The implementation of this page component correctly handles authentication and redirection. It first verifies if the user has an associated organization and redirects accordingly.

apps/app/src/components/tables/people/data-table.tsx (1)

67-67:

Details

❓ Verification inconclusive

URL path updated to match new routes.

The Link component's URL has been correctly updated from "people" to "employees" to align with the route renaming in this PR.

Consider reviewing if this component should also be moved from the tables/people directory to a more appropriately named location to maintain consistency with the new "employees" terminology:


🏁 Script executed:

#!/bin/bash
# Check the current file structure to see if there are other components that might need renaming
find apps/app/src/components -type d -name "people" | grep -v "node_modules"

Length of output: 112


Verified URL update – please review directory naming consistency.

The updated Link now correctly navigates using the new /employees/ route. However, note that the component remains in the apps/app/src/components/tables/people directory. For consistency with the new naming convention, please consider relocating this component (and any related files) to a directory that reflects the "employees" terminology (e.g., renaming tables/people to tables/employees).

apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/actions/update-department.ts (1)

66-67: Revalidation paths updated to match new routes.

The revalidation paths have been correctly updated from "people" to "employees" to maintain consistency with the route renaming.

apps/app/src/components/main-menu.tsx (1)

224-227:

Details

✅ Verification successful

Menu item correctly updated to reflect new terminology.

The menu item has been appropriately updated from "people" to "employees" with the corresponding path and translation key changes.

Notice that there's a typo in the icon name on line 228 (Icons.Peolple instead of Icons.People), though this is pre-existing code:


🏁 Script executed:

#!/bin/bash
# Check if the misspelled icon definition exists elsewhere
grep -r "Peolple" --include="*.tsx" --include="*.ts" apps/

Length of output: 182


Approved: Menu item updates are correct.

  • The menu item now correctly uses "employees" with the updated path (/:organizationId/employees/dashboard) and translation key.
  • The shell script confirms the typo in the icon name (Icons.Peolple) on line 228. Since this appears to be pre-existing code, it need not be addressed in this update.
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/actions/update-employee-status.ts (1)

69-70: Revalidation paths correctly use "employees" route.

The revalidation paths have been properly updated to use the new "employees" route naming convention, which aligns with the PR objectives.

apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/actions/update-employee-details.ts (1)

1-85: Well-implemented server action for updating employee details.

This server action is well-structured with:

  • Strong input validation using Zod schema
  • Proper authentication and authorization checks
  • Appropriate error handling for various scenarios
  • Consistent revalidation paths using the new "employees" naming convention

The implementation follows best practices for Next.js server actions and properly integrates with the rest of the application.

apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/components/EmployeeDetails.tsx (7)

1-30: Client component with necessary imports looks good.

The imports are well-organized and the component is correctly marked as a client component with the "use client" directive at the top of the file.


31-44: Constants for select options are well-structured.

Defining the DEPARTMENTS and STATUS_OPTIONS constants outside the component is a good practice for reusability and preventing unnecessary re-renders.


46-48: Props interface is properly defined.

The interface specifies the required employeeId property with the correct type.


80-91: Action hook implementation looks good.

The useAction hook is properly implemented with appropriate success and error handling callbacks.


93-109: Error handling is thorough and user-friendly.

The error handling includes both redirection for specific error codes and a user-friendly error message display.


111-119: Loading state is properly implemented with skeletons.

Using skeleton loaders provides a good user experience during data loading.


125-131: Handler functions are clear and focused.

These handler functions are appropriately named and serve a single purpose each.

apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/actions/update-employee.ts (4)

1-16: Server action setup and schema validation look good.

The server action is properly set up with "use server" directive, and the schema validation with zod is well-defined.


17-42: Action definition and auth check are correctly implemented.

The server action is properly configured with metadata for tracking and has appropriate authentication checks.


59-77: Good practice to check if changes are needed before updating.

Checking if there are any changes before performing the update is an efficient approach that avoids unnecessary database operations.


79-95: Database update and path revalidation is properly implemented.

The database update operation includes the necessary constraints and the paths are revalidated correctly.

apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/page.tsx (2)

1-7: Imports are clean and focused.

The file imports only the necessary dependencies and components.


8-24: Page component is well-structured and secure.

The component correctly handles authentication and redirects unauthorized users. It also properly handles locale settings.

apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/components/EditableDepartment.tsx (3)

1-26: Component setup and constants look good.

The component is properly marked as a client component and the DEPARTMENTS constant is well-defined.


27-32: Props interface is properly defined.

The interface clearly specifies required and optional properties with the correct types.


33-49: State and action hook are correctly implemented.

The component correctly initializes state from props and the useAction hook has appropriate callbacks.

apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/[employeeId]/components/EditableStatus.tsx (2)

25-30: LGTM! Well-structured props interface.

The props interface is clear and concise with appropriate types.


21-24: LGTM! Good implementation of status options.

The status options are well-defined as an array of objects with value and label properties.

Comment on lines +1 to +33
"use client";

import { useState } from "react";
import { Button } from "@bubba/ui/button";
import { toast } from "sonner";
import { useAction } from "next-safe-action/hooks";
import { updateEmployeeDetails } from "../actions/update-employee-details";

interface EditableDetailsProps {
employeeId: string;
currentName: string;
currentEmail: string;
onSuccess?: () => void;
}

export function EditableDetails({
employeeId,
currentName,
currentEmail,
}: EditableDetailsProps) {
return (
<div className="flex flex-col gap-4">
<div className="flex flex-col gap-1.5">
<span className="text-sm font-medium">Name</span>
<span className="text-sm">{currentName}</span>
</div>
<div className="flex flex-col gap-1.5">
<span className="text-sm font-medium">Email</span>
<span className="text-sm">{currentEmail}</span>
</div>
</div>
);
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Component name "EditableDetails" doesn't match its current implementation.

This component is named "EditableDetails" but doesn't actually provide any editing functionality. It only displays the employee's name and email in a read-only format. There are several unused imports that suggest editing functionality was intended:

  • useState from React
  • Button from UI
  • toast for notifications
  • useAction for handling the update action
  • updateEmployeeDetails action
  • onSuccess prop that's defined but not used

Either implement the editing functionality using these imports or rename the component to something like "EmployeeDetails" to better reflect its current read-only behavior.

Comment on lines +26 to +39
export async function generateMetadata({
params,
}: {
params: Promise<{ locale: string; employeeId: string }>;
}): Promise<Metadata> {
const { locale } = await params;

setStaticParamsLocale(locale);
const t = await getI18n();

return {
title: t("people.details.title"),
};
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix inconsistency in i18n key naming.

The title uses people.details.title but should be updated to employees.details.title to maintain consistency with the route change from "people" to "employees".

return {
-  title: t("people.details.title"),
+  title: t("employees.details.title"),
};

This change is needed to maintain consistency with the route change from "people" to "employees" as mentioned in the PR objectives.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export async function generateMetadata({
params,
}: {
params: Promise<{ locale: string; employeeId: string }>;
}): Promise<Metadata> {
const { locale } = await params;
setStaticParamsLocale(locale);
const t = await getI18n();
return {
title: t("people.details.title"),
};
}
export async function generateMetadata({
params,
}: {
params: Promise<{ locale: string; employeeId: string }>;
}): Promise<Metadata> {
const { locale } = await params;
setStaticParamsLocale(locale);
const t = await getI18n();
return {
title: t("employees.details.title"),
};
}

Comment on lines +54 to +72
return (
<div>
<Select
value={department}
onValueChange={(value) => setDepartment(value as Departments)}
>
<SelectTrigger className="h-8 w-full">
<SelectValue placeholder="Select department" />
</SelectTrigger>
<SelectContent>
{DEPARTMENTS.map((dept) => (
<SelectItem key={dept.value} value={dept.value}>
{dept.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

The Save button is missing from the UI.

The component defines a handleSave function but doesn't include a button to trigger it, making it impossible for users to save their changes.

return (
  <div>
    <Select
      value={department}
      onValueChange={(value) => setDepartment(value as Departments)}
    >
      <SelectTrigger className="h-8 w-full">
        <SelectValue placeholder="Select department" />
      </SelectTrigger>
      <SelectContent>
        {DEPARTMENTS.map((dept) => (
          <SelectItem key={dept.value} value={dept.value}>
            {dept.label}
          </SelectItem>
        ))}
      </SelectContent>
    </Select>
+    <Button 
+      onClick={handleSave}
+      disabled={department === currentDepartment || status === 'loading'}
+      className="mt-2"
+      size="sm"
+    >
+      {status === 'loading' ? 'Saving...' : 'Save'}
+    </Button>
  </div>
);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return (
<div>
<Select
value={department}
onValueChange={(value) => setDepartment(value as Departments)}
>
<SelectTrigger className="h-8 w-full">
<SelectValue placeholder="Select department" />
</SelectTrigger>
<SelectContent>
{DEPARTMENTS.map((dept) => (
<SelectItem key={dept.value} value={dept.value}>
{dept.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
);
return (
<div>
<Select
value={department}
onValueChange={(value) => setDepartment(value as Departments)}
>
<SelectTrigger className="h-8 w-full">
<SelectValue placeholder="Select department" />
</SelectTrigger>
<SelectContent>
{DEPARTMENTS.map((dept) => (
<SelectItem key={dept.value} value={dept.value}>
{dept.label}
</SelectItem>
))}
</SelectContent>
</Select>
<Button
onClick={handleSave}
disabled={department === currentDepartment || status === 'loading'}
className="mt-2"
size="sm"
>
{status === 'loading' ? 'Saving...' : 'Save'}
</Button>
</div>
);

Comment on lines +52 to +55
const handleSave = () => {
const isActive = status === "active";
execute({ employeeId, isActive });
};

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue

The handleSave function is defined but never called.

There is no UI element (like a button) to trigger the handleSave function, making it impossible for users to submit status changes.

Consider adding a save button after the Select component:

return (
	<div>
		<Select
			value={status}
			onValueChange={(value) => setStatus(value as EmployeeStatusType)}
		>
			<SelectTrigger className="h-8 w-full">
				<SelectValue placeholder="Select status" />
			</SelectTrigger>
			<SelectContent>
				{STATUS_OPTIONS.map((option) => (
					<SelectItem key={option.value} value={option.value}>
						{option.label}
					</SelectItem>
				))}
			</SelectContent>
		</Select>
+		<Button
+			onClick={handleSave}
+			disabled={actionStatus === "executing" || status === initialStatus}
+			className="mt-2"
+			size="sm"
+		>
+			Save
+		</Button>
	</div>
);
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const handleSave = () => {
const isActive = status === "active";
execute({ employeeId, isActive });
};
return (
<div>
<Select
value={status}
onValueChange={(value) => setStatus(value as EmployeeStatusType)}
>
<SelectTrigger className="h-8 w-full">
<SelectValue placeholder="Select status" />
</SelectTrigger>
<SelectContent>
{STATUS_OPTIONS.map((option) => (
<SelectItem key={option.value} value={option.value}>
{option.label}
</SelectItem>
))}
</SelectContent>
</Select>
<Button
onClick={handleSave}
disabled={actionStatus === "executing" || status === initialStatus}
className="mt-2"
size="sm"
>
Save
</Button>
</div>
);

Comment on lines +57 to +75
return (
<div>
<Select
value={status}
onValueChange={(value) => setStatus(value as EmployeeStatusType)}
>
<SelectTrigger className="h-8 w-full">
<SelectValue placeholder="Select status" />
</SelectTrigger>
<SelectContent>
{STATUS_OPTIONS.map((option) => (
<SelectItem key={option.value} value={option.value}>
{option.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider auto-saving or adding save functionality.

Currently, this component allows users to select a new status but doesn't provide any way to save the change. Either implement auto-saving on selection change or add a save button to trigger the handleSave function.

Option 1: Implement auto-save on selection change:

<Select
	value={status}
-	onValueChange={(value) => setStatus(value as EmployeeStatusType)}
+	onValueChange={(value) => {
+		const newStatus = value as EmployeeStatusType;
+		setStatus(newStatus);
+		if (newStatus !== initialStatus) {
+			const isActive = newStatus === "active";
+			execute({ employeeId, isActive });
+		}
+	}}
>

Or Option 2: Add a save button below the dropdown (as shown in the previous comment).

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
return (
<div>
<Select
value={status}
onValueChange={(value) => setStatus(value as EmployeeStatusType)}
>
<SelectTrigger className="h-8 w-full">
<SelectValue placeholder="Select status" />
</SelectTrigger>
<SelectContent>
{STATUS_OPTIONS.map((option) => (
<SelectItem key={option.value} value={option.value}>
{option.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
);
return (
<div>
<Select
value={status}
onValueChange={(value) => {
const newStatus = value as EmployeeStatusType;
setStatus(newStatus);
if (newStatus !== initialStatus) {
const isActive = newStatus === "active";
execute({ employeeId, isActive });
}
}}
>
<SelectTrigger className="h-8 w-full">
<SelectValue placeholder="Select status" />
</SelectTrigger>
<SelectContent>
{STATUS_OPTIONS.map((option) => (
<SelectItem key={option.value} value={option.value}>
{option.label}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
);

@vercel vercel Bot temporarily deployed to Preview – comp-portal March 28, 2025 14:53 Inactive
@vercel vercel Bot temporarily deployed to Preview – comp-portal March 28, 2025 14:53 Inactive

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 0

🔭 Outside diff range comments (1)
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/all/page.tsx (1)

6-6: 🛠️ Refactor suggestion

Function name should be updated to match the new terminology.

The function is still named AllPeoplePage while the file path and component it renders (EmployeesList) use the "employees" terminology. This is inconsistent with the PR's objective of renaming from "people" to "employees".

Consider updating the function name for consistency:

-export default async function AllPeoplePage({
+export default async function AllEmployeesPage({
🧹 Nitpick comments (1)
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/dashboard/components/EmployeesOverview.tsx (1)

49-56: Clear filtering logic with helpful todo comment.

The filtering logic clearly communicates the intent to only include active employees that exist in both tables. The TODO comment provides important context about this being a temporary solution, which is helpful for future maintainers.

Consider adding a reference to an issue or ticket number in the TODO comment to make it easier to track when this technical debt will be addressed.

📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 07a0b18 and c7817a3.

📒 Files selected for processing (3)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/all/page.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/dashboard/components/EmployeesOverview.tsx (1 hunks)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/dashboard/page.tsx (1 hunks)
✅ Files skipped from review due to trivial changes (1)
  • apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/dashboard/page.tsx
🔇 Additional comments (5)
apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/all/page.tsx (1)

28-28: LGTM! Translation key properly updated.

The metadata title has been properly updated from "sidebar.people" to "sidebar.employees", which aligns with the PR objective of renaming from "people" to "employees".

apps/app/src/app/[locale]/(app)/(dashboard)/[orgId]/employees/dashboard/components/EmployeesOverview.tsx (4)

29-33: Variable renamed for clarity.

Good change - renaming to portalEmployees better reflects that these users come from the portal user table. This makes the code more maintainable and easier to understand, especially in context of the subsequent changes.


35-42: Enhanced data filtering for employee records.

This additional query improves data integrity by ensuring that employees returned by the component are actually present in both the portal user and employee tables. This is a good data validation approach.


44-47: Efficient status lookup with map implementation.

Creating a map for quick lookups is a good performance optimization when you need to repeatedly check employee status. This approach is more efficient than filtering arrays multiple times.


58-58: Return value updated to match new filtering logic.

The return value now correctly reflects the filtered active portal employees rather than all employees, which aligns with the component's purpose.

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