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]: Added Translations For The UI In Multiple Languages #3265

Merged
merged 3 commits into from
Nov 8, 2024

Conversation

Innocent-Akim
Copy link
Contributor

@Innocent-Akim Innocent-Akim commented Nov 8, 2024

Description

Please include a summary of the changes and the related issue.

Type of Change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation update

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings

Previous screenshots

Please add here videos or images of previous status

Current screenshots

Please add here videos or images of previous status

Summary by CodeRabbit

Release Notes

  • New Features

    • Enhanced localization support across various components, allowing for dynamic text rendering based on user language preferences.
    • New translatable strings added for role selection, time management actions, and confirmation messages.
  • Improvements

    • UI elements such as buttons and labels now utilize translation functions for better internationalization.
    • Improved visual feedback for UI components like toggle buttons.
  • Localization Updates

    • New entries added in multiple languages, including Arabic, Bulgarian, German, Spanish, French, Hebrew, Italian, Dutch, Polish, Portuguese, Russian, and Chinese, enhancing user experience through localized content.

@Innocent-Akim Innocent-Akim self-assigned this Nov 8, 2024
Copy link
Contributor

coderabbitai bot commented Nov 8, 2024

Caution

Review failed

The pull request is closed.

Walkthrough

The changes in this pull request primarily focus on enhancing localization across various components in the web application. Key updates include the integration of the useTranslations hook for dynamic text rendering based on the user's locale. Components such as Permissions, EditTaskModal, RejectSelectedModal, and others have been modified to utilize translation functions for displaying text. Additionally, several localization files have been updated with new entries and modifications, improving the overall internationalization support of the application.

Changes

File Path Change Summary
apps/web/app/[locale]/permissions/component.tsx Updated SelectRole function to use useTranslations for dynamic text. Replaced static text with translatable strings. Adjusted rendering logic for clarity.
apps/web/app/[locale]/timesheet/[memberId]/components/EditTaskModal.tsx Localization improvements for labels and buttons using translation functions. Updated background color for ToggleButton component.
apps/web/app/[locale]/timesheet/[memberId]/components/RejectSelectedModal.tsx Added useTranslations for dynamic text. Updated modal text and button labels to use translation functions.
apps/web/app/[locale]/timesheet/[memberId]/components/TimeSheetFilterPopover.tsx Integrated useTranslations for button labels and section headers, enhancing internationalization support.
apps/web/app/[locale]/timesheet/[memberId]/components/TimesheetFilter.tsx Updated interface to include t for translation hooks. Modified button label to use translation function.
apps/web/app/[locale]/timesheet/[memberId]/components/TimesheetFilterDate.tsx Added t property for translations. Updated button and placeholder texts to use translation functions.
apps/web/app/[locale]/timesheet/[memberId]/page.tsx Added t prop to TimesheetFilter component for translation hooks.
apps/web/lib/features/manual-time/add-manual-time-modal.tsx Localization updates for modal title and button texts using useTranslations.
apps/web/lib/features/task/task-filters.tsx Enhanced task filtering functionality with new state variable and search feature. Updated button text to use translation function.
apps/web/locales/ar.json Added new keys and updated existing ones for Arabic localization.
apps/web/locales/bg.json Added new keys and updated existing entries for Bulgarian localization.
apps/web/locales/de.json Added new keys and updated existing ones for German localization.
apps/web/locales/en.json Added new keys for English localization.
apps/web/locales/es.json Added new keys and updated existing entries for Spanish localization.
apps/web/locales/fr.json Added new keys for French localization.
apps/web/locales/he.json Added new keys for Hebrew localization.
apps/web/locales/it.json Added new keys for Italian localization.
apps/web/locales/nl.json Added new keys for Dutch localization.
apps/web/locales/pl.json Added new keys for Polish localization.
apps/web/locales/pt.json Added new keys for Portuguese localization.
apps/web/locales/ru.json Added new keys for Russian localization.
apps/web/locales/zh.json Added new keys and updated existing entries for Chinese localization.

Possibly related PRs

Suggested labels

feature, WEB, Ever Teams

Suggested reviewers

  • Cedric921

Poem

🐇 In the world of code, we hop and play,
With translations ready for every day.
Roles and times, in every tongue,
A joyful song of code we've sung!
So let us cheer for changes bright,
Making our app a pure delight! 🌟


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 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.

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: 5

🧹 Outside diff range and nitpick comments (32)
apps/web/app/[locale]/timesheet/[memberId]/components/RejectSelectedModal.tsx (2)

Line range hint 31-31: Translate remaining hardcoded strings.

Several text strings are still hardcoded and should be translated for consistency:

 <Modal
     isOpen={isOpen}
     showCloseIcon={false}
     closeModal={closeModal}
-    title={'Reject Selected'}
+    title={t('pages.timesheet.REJECT_SELECTED')}
     className="bg-light--theme-light dark:bg-dark--theme-light p-5 rounded-xl w-full md:w-40 md:min-w-[24rem] justify-start"
     titleClass="font-bold">
     {/* ... */}
     <textarea
         value={reason}
         onChange={(e) => setReason(e.target.value)}
-        placeholder="Add reason here..."
+        placeholder={t('pages.timesheet.ADD_REASON_PLACEHOLDER')}
         {/* ... */}
     />
     {/* ... */}
     <button
         type="submit"
         disabled={isSubmitting || reason.length < minReasonLength!}
         aria-label="Confirm rejection"
         className={clsxm(
             'bg-red-600 h-[2.2rem] font-normal flex items-center text-white px-2 rounded-lg',
             'disabled:opacity-50 disabled:cursor-not-allowed'
         )} >
-        {isSubmitting ? 'Rejecting...' : 'Reject Entry'}
+        {isSubmitting ? t('common.REJECTING') : t('pages.timesheet.REJECT_ENTRY')}
     </button>

Also applies to: 74-74


Line range hint 40-53: Improve accessibility for form validation.

Consider these accessibility enhancements:

  1. Translate aria-labels
  2. Add aria-invalid and aria-errormessage for validation feedback
 <textarea
     value={reason}
     onChange={(e) => setReason(e.target.value)}
     placeholder={t('pages.timesheet.ADD_REASON_PLACEHOLDER')}
     className={clsxm(/* ... */)}
     maxLength={120}
     minLength={0}
-    aria-label="Rejection reason"
+    aria-label={t('pages.timesheet.REJECTION_REASON_LABEL')}
+    aria-invalid={reason.length < minReasonLength!}
+    aria-errormessage="reason-error"
     required
 />
+{reason.length < minReasonLength! && (
+  <div id="reason-error" className="text-red-500 text-sm" role="alert">
+    {t('pages.timesheet.MINIMUM_REASON_LENGTH_ERROR')}
+  </div>
+)}

Also update the button aria-labels:

 <button
     onClick={closeModal}
     type="button"
     disabled={isSubmitting}
-    aria-label="Cancel rejection"
+    aria-label={t('pages.timesheet.CANCEL_REJECTION_LABEL')}
     className="..." >
     {t('common.CANCEL')}
 </button>
 <button
     type="submit"
     disabled={isSubmitting || reason.length < minReasonLength!}
-    aria-label="Confirm rejection"
+    aria-label={t('pages.timesheet.CONFIRM_REJECTION_LABEL')}
     className="..." >
     {isSubmitting ? t('common.REJECTING') : t('pages.timesheet.REJECT_ENTRY')}
 </button>
apps/web/app/[locale]/timesheet/[memberId]/components/TimeSheetFilterPopover.tsx (3)

11-18: Clean up import spacing

Remove the unnecessary blank lines between imports to maintain consistent code organization.

import { SettingFilterIcon } from "@/assets/svg";
-
-
import { useTranslations } from "next-intl";
-

38-38: Standardize translation namespace usage

The filter labels are using inconsistent namespaces:

  • Employee: manualTime.EMPLOYEE
  • Projects: sidebar.PROJECTS
  • Task: hotkeys.TASK
  • Status: common.STATUS

Consider moving all filter-related translations to a dedicated namespace (e.g., filters) for better maintainability.

-<span className="text-[12px]">{t('manualTime.EMPLOYEE')}</span>
-<span className="text-[12px]">{t('sidebar.PROJECTS')}</span>
-<span className="text-[12px]">{t('hotkeys.TASK')}</span>
-<span className="text-[12px]">{t('common.STATUS')}</span>
+<span className="text-[12px]">{t('filters.EMPLOYEE')}</span>
+<span className="text-[12px]">{t('filters.PROJECTS')}</span>
+<span className="text-[12px]">{t('filters.TASK')}</span>
+<span className="text-[12px]">{t('filters.STATUS')}</span>

Also applies to: 52-52, 66-66, 80-80


Line range hint 94-101: Add missing translations for action buttons

The "Clear Filter" and "Apply Filter" button texts are still hardcoded. These should be translated for consistency with the rest of the component.

<Button
    variant={'outline'}
    className='flex items-center text-sm justify-center h-10 rounded-lg dark:text-gray-300' >
-   <span className="text-sm">Clear Filter</span>
+   <span className="text-sm">{t('filters.CLEAR_FILTER')}</span>
</Button>
<Button
    className='flex items-center text-sm justify-center h-10 rounded-lg bg-primary dark:bg-primary-light dark:text-gray-300' >
-   <span className="text-sm">Apply Filter</span>
+   <span className="text-sm">{t('filters.APPLY_FILTER')}</span>
</Button>
apps/web/app/[locale]/timesheet/[memberId]/page.tsx (3)

Line range hint 89-106: Internationalize remaining hardcoded strings in TimesheetCard components

Several strings are still hardcoded and should be moved to translation files:

  • "Pending Tasks"
  • "Tasks waiting for your approval"
  • "Men Hours"
  • "Members Worked"
  • "People worked since last time"

Example implementation:

 <TimesheetCard
     count={72}
-    title='Pending Tasks'
-    description='Tasks waiting for your approval'
+    title={t('pages.timesheet.cards.PENDING_TASKS')}
+    description={t('pages.timesheet.cards.PENDING_TASKS_DESC')}
     icon={<GrTask className='font-bold' />}
     classNameIcon='bg-[#FBB650] shadow-[#fbb75095]'
 />

Line range hint 124-134: Implement search functionality for the timesheet entries

The search input is missing essential functionality:

  1. No state management for the search term
  2. No filtering implementation
  3. No debounce for performance optimization
  4. Hardcoded "Search.." placeholder needs translation

Example implementation:

+const [searchTerm, setSearchTerm] = useState('');
+const debouncedSearch = useDebounce(searchTerm, 300);

+// Add this to your component's effect
+useEffect(() => {
+    // Implement search logic here
+}, [debouncedSearch]);

 <input
     role="searchbox"
     aria-label="Search timesheet"
     type="search"
     name="timesheet-search"
     id="timesheet-search"
     className="!h-[2.2rem] w-full bg-transparent focus:border-transparent focus:ring-2 focus:ring-transparent placeholder-gray-500 placeholder:font-medium shadow-sm outline-none"
-    placeholder="Search.."
+    placeholder={t('pages.timesheet.SEARCH_PLACEHOLDER')}
+    value={searchTerm}
+    onChange={(e) => setSearchTerm(e.target.value)}
 />

Line range hint 25-149: Consider architectural improvements for better maintainability

The TimeSheet component is handling multiple responsibilities. Consider the following improvements:

  1. Extract search logic into a custom hook (e.g., useTimesheetSearch)
  2. Move TimesheetCard components to a separate file
  3. Consider splitting the view logic (List/Calendar) into separate components with lazy loading

This will improve code organization, maintainability, and potentially performance through code splitting.

apps/web/app/[locale]/timesheet/[memberId]/components/TimesheetFilterDate.tsx (2)

32-33: Minor: Maintain consistent prop formatting.

The spacing between props is inconsistent. Consider aligning the new t prop with the existing props' indentation.

-    maxDate,
-    t
+    maxDate,
+    t

Line range hint 178-236: Extend internationalization to child components.

The DatePickerFilter component uses hardcoded English labels ("From" and "To"). For consistency, these should also be internationalized.

 export function DatePickerFilter({
     label,
     date,
     setDate,
     minDate,
-    maxDate
+    maxDate,
+    t
 }: {
     label: string;
     date: Date | null;
     setDate: (date: Date | null) => void;
     minDate?: Date | null;
-    maxDate?: Date | null
+    maxDate?: Date | null;
+    t: TranslationHooks;
 }) {
     // ...
     return (
         <div>
             <DatePicker
                 // ...
-                customInput={<DatePickerInput date={date} label={label} />}
+                customInput={<DatePickerInput date={date} label={t(`timesheet.${label.toUpperCase()}`)} />}
                 // ...
             />
         </div>
     );
 }

Update the parent component to pass the translation function:

 <DatePickerFilter
-    label="From"
+    label="from"
     date={dateRange.from}
     setDate={handleFromChange}
+    t={t}
 />
 <DatePickerFilter
-    label="To"
+    label="to"
     date={dateRange.to}
     setDate={handleToChange}
     minDate={dateRange.from}
+    t={t}
 />
apps/web/app/[locale]/timesheet/[memberId]/components/EditTaskModal.tsx (4)

Line range hint 136-145: Add ARIA attributes for better accessibility

While the translation implementation is correct, the toggle button group needs proper accessibility attributes.

Consider applying these changes:

-                        <div className="flex items-center gap-3">
+                        <div 
+                            role="radiogroup" 
+                            aria-label={t('pages.timesheet.BILLABLE.BILLABLE')} 
+                            className="flex items-center gap-3"
+                        >
                             <ToggleButton
                                 isActive={isBillable}
                                 onClick={() => setIsBillable(!isBillable)}
                                 label={t('pages.timesheet.BILLABLE.YES')}
+                                role="radio"
+                                aria-checked={isBillable}
                             />

Line range hint 189-198: Wrap modal content in a form element

The save button is type="submit" but there's no form element wrapping the content. This could lead to unexpected behavior.

Consider applying this change:

     <Modal
         closeModal={closeModal}
         isOpen={isOpen}
         showCloseIcon
         title={'Edit Task'}
         className="bg-light--theme-light dark:bg-dark--theme-light p-5 rounded-xl w-full md:w-40 md:min-w-[30rem] justify-start h-[auto]"
         titleClass="font-bold">
+        <form onSubmit={handleSubmit}>
             <div className="flex flex-col w-full">
                 {/* existing content */}
             </div>
+        </form>
     </Modal>

224-227: Standardize styling approach using design system tokens

The current implementation mixes inline styles with className and uses hardcoded colors. This could lead to inconsistency in the theme system.

Consider applying these changes:

-            style={{
-                background: isActive
-                    ? 'linear-gradient(to right, #9d91efb7, #8a7bedb7)'
-                    : '#1f2937'
-            }}
+            className={clsxm(
+                "w-6 h-6 flex items-center rounded-full p-1 cursor-pointer",
+                isActive 
+                    ? "bg-gradient-to-r from-primary-light/70 to-primary-dark/70"
+                    : "bg-gray-800 dark:bg-gray-700"
+            )}

Line range hint 1-231: Additional improvements needed

A few more items need attention:

  1. The modal title "Edit Task" should use the translation system
  2. The DatePicker label "Oct 01 2024" should be dynamic
  3. Add error message display for the required notes field

Example for the modal title:

-    title={'Edit Task'}
+    title={t('pages.timesheet.EDIT_TASK')}
apps/web/app/[locale]/permissions/component.tsx (2)

69-72: Consider using a className utility for better maintainability.

The template literal for conditional classes could be simplified using a utility like clsx or classnames. This would improve readability and maintainability.

-className={`flex items-center justify-between w-full py-2 px-5 rounded-xl cursor-pointer ${selectedRole && selectedRole.id === role.id
-  ? 'bg-primary dark:bg-primary-light text-white'
-  : ''
-  }`}
+className={clsx(
+  'flex items-center justify-between w-full py-2 px-5 rounded-xl cursor-pointer',
+  selectedRole?.id === role.id && 'bg-primary dark:bg-primary-light text-white'
+)}

277-286: Consider namespace consistency for translation keys.

The implementation looks good, but consider using the same namespace ('pages.settingsTeam') as other translations in this component for consistency, instead of 'common'.

-{t("common.SELECT_ROLE")}
+{t("pages.settingsTeam.SELECT_ROLE")}
apps/web/lib/features/manual-time/add-manual-time-modal.tsx (7)

242-242: Consider using consistent translation namespaces.

The billable toggle label uses the pages.timesheet.BILLABLE.BILLABLE translation key, while other labels in this component use the manualTime namespace. Consider moving this translation to the manualTime namespace for better organization and maintainability.


Line range hint 89-89: Translate error messages.

The error message "End time should be after than start time" should use a translation key for consistency with the rest of the UI.

-setErrorMsg('End time should be after than start time');
+setErrorMsg(t('manualTime.errors.INVALID_TIME_RANGE'));

Line range hint 297-321: Remove or restore commented code block.

There's a commented-out team selection block that should either be removed if it's no longer needed or restored if it's still required. Commented-out code can lead to confusion and maintenance issues.


Line range hint 322-397: Consider consolidating duplicate team selection logic.

The team selection logic is duplicated between the AddManuelTime and AddTime modes. Consider extracting this into a shared component or utility function to improve maintainability.

+const TeamSelection = ({ team, teams, setTeam }) => (
+  <div className="">
+    <label className="block text-gray-500 mb-1">
+      {t('manualTime.TEAM')}
+      <span className="text-[#de5505e1] ml-1">*</span>
+    </label>
+    <SelectItems
+      defaultValue={team}
+      items={teams}
+      onValueChange={setTeam}
+      itemId={(team) => (team ? team.id : '')}
+      itemToString={(team) => (team ? team.name : '')}
+      triggerClassName="border-gray-300 dark:border-slate-600"
+    />
+  </div>
+);

Line range hint 367-367: Translate placeholder text.

The description field's placeholder text "What worked on?" and "What did you worked on..." should use translation keys for consistency.

-placeholder="What worked on? "
+placeholder={t('manualTime.placeholders.DESCRIPTION')}

Also applies to: 398-398


Line range hint 419-426: Consider using theme variables for colors.

The button styles use hardcoded colors (e.g., bg-[#3826A6]). Consider using theme variables or CSS custom properties for better maintainability and consistency across the application.

-className={clsxm('bg-[#3826A6] font-bold flex items-center text-white',
+className={clsxm('bg-primary font-bold flex items-center text-white',

Line range hint 32-431: Consider splitting the component for better maintainability.

The component handles two different modes (AddManuelTime and AddTime) with significant differences in their UI and logic. Consider splitting this into two separate components that share common functionality through custom hooks or utility functions. This would:

  1. Reduce complexity
  2. Make the code more maintainable
  3. Make it easier to test each mode independently
apps/web/lib/features/task/task-filters.tsx (3)

360-360: Consider removing type casting for translation keys

While the translation implementation is good, casting translation keys as DottedLanguageObjectStringPaths might indicate missing type definitions. Consider defining proper types for these translation keys to maintain type safety without casting.


Line range hint 252-280: Optimize task filtering performance

The current implementation could be optimized to reduce unnecessary operations:

  1. Multiple filter chains could be combined into a single pass
  2. The toLowerCase() call on task title could be moved outside the filter
  3. The intersection operation for labels could be optimized

Consider refactoring to this more efficient implementation:

  const $tasks = useMemo(() => {
    const n = taskName.trim().toLowerCase();
    const statusFilters = appliedStatusFilter;
    const hasStatusFilters = Object.keys(statusFilters).some(
      (k) => statusFilters[k as IStatusType].length > 0
    );

-   return tasks
-     .filter((task) => {
-       return n ? task.title.toLowerCase().includes(n) : true;
-     })
-     .filter((task) => {
-       const keys = Object.keys(statusFilters) as IStatusType[];
-
-       return keys
-         .filter((k) => statusFilters[k].length > 0)
-         .every((k) => {
-           return k === 'label'
-             ? intersection(
-               statusFilters[k],
-               task['tags'].map((item) => item.name)
-             ).length === statusFilters[k].length
-             : statusFilters[k].includes(task[k]);
-         });
-     });

+   return tasks.filter((task) => {
+     if (n && !task.title.toLowerCase().includes(n)) {
+       return false;
+     }
+     
+     if (!hasStatusFilters) {
+       return true;
+     }
+
+     return Object.entries(statusFilters).every(([key, values]) => {
+       if (values.length === 0) return true;
+       
+       if (key === 'label') {
+         const taskTags = new Set(task.tags.map(item => item.name));
+         return values.every(value => taskTags.has(value));
+       }
+       
+       return values.includes(task[key as keyof typeof task]);
+     });
+   });
  }, [tasks, taskName, appliedStatusFilter]);

Line range hint 516-553: Fix potential memory leak in TaskNameFilter component

The current implementation doesn't clean up the typing timeout when the component unmounts, which could lead to memory leaks and setState calls on unmounted components.

Add a cleanup function using useEffect:

  export function TaskNameFilter({
    value,
    setValue,
    close,
    fullWidth = false
  }: {
    value: string;
    setValue: (v: string) => void;
    close: () => void;
    fullWidth?: boolean;
  }) {
    const t = useTranslations();

    const [typingTimeout, setTypingTimeout] = useState<NodeJS.Timeout | null>(null);
    const [tempValue, setTempValue] = useState<string>(value);

+   useEffect(() => {
+     return () => {
+       if (typingTimeout) {
+         clearTimeout(typingTimeout);
+       }
+     };
+   }, [typingTimeout]);

    const handleInputChange = (e: React.ChangeEvent<HTMLInputElement>) => {
      const inputValue = e.target.value;
      setTempValue(inputValue);

      if (typingTimeout) {
        clearTimeout(typingTimeout);
      }

      const newTimeout = setTimeout(() => {
        setValue(inputValue);
      }, 300);

      setTypingTimeout(newTimeout);
    };
    // ... rest of the component
apps/web/locales/zh.json (1)

574-575: Consider improving the translation for rejection confirmation.

The translations for timesheet-related strings are generally good, but the rejection confirmation message could be more formal and clearer:

-			"YOU_ARE_ABOUT_TO_REJECT_ENTRY": "你即将拒绝选定的条目,是否继续?"
+			"YOU_ARE_ABOUT_TO_REJECT_ENTRY": "您确定要拒绝所选的时间记录吗?"

Rationale:

  • Using "您" instead of "你" is more formal and professional
  • "时间记录" is more specific than "条目" in the timesheet context
  • The question is rephrased to be more natural in Chinese

Also applies to: 577-579

apps/web/locales/ar.json (1)

Line range hint 557-579: Consider a more formal phrasing for the rejection confirmation message.

While the translations are generally excellent, the rejection confirmation message could be more formal:

-"YOU_ARE_ABOUT_TO_REJECT_ENTRY": "أنت على وشك رفض الإدخال المحدد، هل ترغب في المتابعة؟"
+"YOU_ARE_ABOUT_TO_REJECT_ENTRY": "هل تؤكد رغبتك في رفض الإدخال المحدد؟"

The suggested version is more formal and aligns better with standard Arabic UI conventions.

apps/web/locales/en.json (1)

257-260: Maintain consistency in translation messages

The translation key SELECT_ROLE includes "Please" in its message while similar selection-related keys don't include such prefixes. Consider removing "Please" for consistency:

-		"SELECT_ROLE": "Please Select any Role",
+		"SELECT_ROLE": "Select Role",
apps/web/locales/nl.json (1)

574-575: Consider grouping YES/NO translations together.

The "NO" translation is currently separated from its corresponding "YES" translation (line 574). For better maintainability and consistency, consider grouping them together.

 "BILLABLE": {
   "YES": "Ja",
-  "NO": "Nee",
-  "BILLABLE": "Factureerbaar"
+  "NO": "Nee",
+  "BILLABLE": "Factureerbaar"
 }
apps/web/locales/it.json (1)

574-575: Enhance natural language flow in Italian translations.

While the translations are functionally correct, they could be more idiomatic in Italian.

Consider these more natural Italian expressions:

  "BILLABLE": {
    "YES": "Sì",
    "NO": "No",
-   "BILLABLE": "FATTURABILE"
+   "BILLABLE": "Fatturabile"
  },
- "NO_ENTRIES_FOUND": "Nessuna voce di registrazione ore trovata",
+ "NO_ENTRIES_FOUND": "Nessuna registrazione ore trovata",
- "YOU_ARE_ABOUT_TO_REJECT_ENTRY": "Stai per rifiutare l'elemento selezionato, vuoi procedere?"
+ "YOU_ARE_ABOUT_TO_REJECT_ENTRY": "Vuoi procedere con il rifiuto dell'elemento selezionato?"

Changes explained:

  1. Removed unnecessary capitalization of "FATTURABILE"
  2. Simplified "voce di registrazione" to just "registrazione"
  3. Restructured the rejection confirmation to be more natural in Italian

Also applies to: 578-579

apps/web/locales/es.json (1)

574-575: Consider grouping all BILLABLE-related translations together.

The BILLABLE section has "YES" defined earlier in the file while "NO" and "BILLABLE" are added here. Consider moving all BILLABLE-related translations together for better maintainability.

 "BILLABLE": {
   "YES": "Sí",
   "NO": "No",
   "BILLABLE": "FACTURABLE"
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 3740f52 and a22a21e.

📒 Files selected for processing (22)
  • apps/web/app/[locale]/permissions/component.tsx (3 hunks)
  • apps/web/app/[locale]/timesheet/[memberId]/components/EditTaskModal.tsx (5 hunks)
  • apps/web/app/[locale]/timesheet/[memberId]/components/RejectSelectedModal.tsx (4 hunks)
  • apps/web/app/[locale]/timesheet/[memberId]/components/TimeSheetFilterPopover.tsx (4 hunks)
  • apps/web/app/[locale]/timesheet/[memberId]/components/TimesheetFilter.tsx (2 hunks)
  • apps/web/app/[locale]/timesheet/[memberId]/components/TimesheetFilterDate.tsx (5 hunks)
  • apps/web/app/[locale]/timesheet/[memberId]/page.tsx (1 hunks)
  • apps/web/lib/features/manual-time/add-manual-time-modal.tsx (4 hunks)
  • apps/web/lib/features/task/task-filters.tsx (1 hunks)
  • apps/web/locales/ar.json (3 hunks)
  • apps/web/locales/bg.json (2 hunks)
  • apps/web/locales/de.json (2 hunks)
  • apps/web/locales/en.json (2 hunks)
  • apps/web/locales/es.json (2 hunks)
  • apps/web/locales/fr.json (2 hunks)
  • apps/web/locales/he.json (2 hunks)
  • apps/web/locales/it.json (2 hunks)
  • apps/web/locales/nl.json (2 hunks)
  • apps/web/locales/pl.json (2 hunks)
  • apps/web/locales/pt.json (2 hunks)
  • apps/web/locales/ru.json (2 hunks)
  • apps/web/locales/zh.json (2 hunks)
🧰 Additional context used
📓 Learnings (4)
apps/web/app/[locale]/timesheet/[memberId]/components/TimesheetFilter.tsx (1)
Learnt from: Innocent-Akim
PR: ever-co/ever-teams#3208
File: apps/web/app/[locale]/timesheet/components/TimesheetFilter.tsx:30-35
Timestamp: 2024-10-30T16:31:01.294Z
Learning: In the `TimesheetFilter` component, the `Add Time` button does not need to use the `AddManualTimeModal` component, as per the user's decision.
apps/web/app/[locale]/timesheet/[memberId]/page.tsx (1)
Learnt from: Innocent-Akim
PR: ever-co/ever-teams#3208
File: apps/web/app/[locale]/timesheet/components/TimesheetFilter.tsx:30-35
Timestamp: 2024-10-30T16:31:01.294Z
Learning: In the `TimesheetFilter` component, the `Add Time` button does not need to use the `AddManualTimeModal` component, as per the user's decision.
apps/web/lib/features/manual-time/add-manual-time-modal.tsx (1)
Learnt from: Innocent-Akim
PR: ever-co/ever-teams#3208
File: apps/web/app/[locale]/timesheet/components/TimesheetFilter.tsx:30-35
Timestamp: 2024-10-30T16:31:01.294Z
Learning: In the `TimesheetFilter` component, the `Add Time` button does not need to use the `AddManualTimeModal` component, as per the user's decision.
apps/web/locales/it.json (1)
Learnt from: Innocent-Akim
PR: ever-co/ever-teams#3225
File: apps/web/locales/it.json:554-571
Timestamp: 2024-11-03T08:34:33.295Z
Learning: In the Italian localization (`apps/web/locales/it.json`), use "Registro ore" as the translation for "timesheet" instead of "Foglio presenze".
🔇 Additional comments (44)
apps/web/app/[locale]/timesheet/[memberId]/components/TimesheetFilter.tsx (4)

5-11: LGTM: Interface changes for translation support

The interface update properly types the translation hook, ensuring type safety for internationalization.


12-12: LGTM: Component signature properly updated

The function signature correctly implements the updated interface with translation support.


Line range hint 25-33: Consider consistent translation implementation across child components

The translation prop is passed to some child components but not to others (FilterWithStatus, FrequencySelect). Consider implementing a consistent approach to translations across all child components for better maintainability.

#!/bin/bash
# Description: Check if other components have translation support

# Check for translation imports in related components
echo "Checking translation imports in components:"
rg -l "import.*next-intl" $(fd "FilterWithStatus|FrequencySelect" --type f)

# Check for hardcoded strings in these components
echo "Checking for potential hardcoded strings:"
rg -n '"[^"]{4,}"' $(fd "FilterWithStatus|FrequencySelect" --type f)

34-34: Verify TimesheetFilterDate translation implementation

Ensure that the TimesheetFilterDate component is properly configured to handle the translation prop.

✅ Verification successful

Let me gather more specific information about the TimesheetFilterDate component.


Let me check one final thing to verify the component's interface and imports.


TimesheetFilterDate component is properly configured for translations

The component is correctly implemented with:

  • Proper interface definition including t: TranslationHooks
  • Required next-intl import
  • Translation usage for strings like manualTime.PICK_A_DATE, common.CANCEL, and common.APPLY
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify if TimesheetFilterDate component properly implements translation prop

# Check TimesheetFilterDate component implementation
ast-grep --pattern 'interface $interface {
  $$$
  t: TranslationHooks
  $$$
}'

# Check for translation usage in the component
rg -l "import.*next-intl.*" $(fd TimesheetFilterDate)

Length of output: 6507


Script:

#!/bin/bash
# Search for TimesheetFilterDate component file
fd TimesheetFilterDate

# Check TimesheetFilterDate component implementation
ast-grep --pattern 'interface $interface {
  t: $_
  $$$
}'

# Check component implementation
ast-grep --pattern 'function TimesheetFilterDate({ $$ }) {
  $$$
}'

# Check for translation usage
rg -n "t\(" $(fd TimesheetFilterDate)

Length of output: 786


Script:

#!/bin/bash
# Check the interface and imports in TimesheetFilterDate
rg -A 5 "^import|^interface|^type" apps/web/app/[locale]/timesheet/[memberId]/components/TimesheetFilterDate.tsx

Length of output: 933

apps/web/app/[locale]/timesheet/[memberId]/components/RejectSelectedModal.tsx (2)

3-3: LGTM! Proper initialization of translations.

The useTranslations hook is correctly imported and initialized at the component level.

Also applies to: 15-15


37-37: Verify translation keys exist in language files.

The translation implementation looks good, but let's verify these keys exist in all language files:

  • pages.timesheet.YOU_ARE_ABOUT_TO_REJECT_ENTRY
  • common.CANCEL

Also applies to: 64-64

✅ Verification successful

Translation keys are properly implemented and available in all language files

Both translation keys are present and correctly implemented across all language files:

  • pages.timesheet.YOU_ARE_ABOUT_TO_REJECT_ENTRY exists in all web locale files (ar, bg, de, en, es, fr, he, it, nl, pl, pt, ru, zh)
  • common.CANCEL is available in all required locale files with appropriate translations
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if the translation keys exist in all language files
# Expected: Both keys should be present in all language files

# Search for the timesheet rejection message key
echo "Checking 'YOU_ARE_ABOUT_TO_REJECT_ENTRY' key:"
rg "YOU_ARE_ABOUT_TO_REJECT_ENTRY" --type json

# Search for the cancel button key
echo -e "\nChecking 'CANCEL' key:"
rg '"CANCEL"' --type json

Length of output: 6985

apps/web/app/[locale]/timesheet/[memberId]/components/TimeSheetFilterPopover.tsx (2)

25-27: LGTM! Translation implementation is correct

The filter button properly uses the translation hook with a semantic key structure.


Line range hint 1-104: Verify translation key existence

Let's verify that all translation keys used in this component exist in the translation files.

✅ Verification successful

All translation keys are present and correctly defined

After analyzing the English translation file (apps/web/locales/en.json), I can confirm that all translation keys used in the TimeSheetFilterPopover component are present and correctly defined:

  • "common.FILTER" - Found in common section
  • "manualTime.EMPLOYEE" - Found in manualTime section
  • "sidebar.PROJECTS" - Found in sidebar section
  • "hotkeys.TASK" - Found in hotkeys section
  • "common.STATUS" - Found in common section

All keys are properly defined and accessible through the useTranslations hook.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if all used translation keys exist in translation files
# Expected results: All keys should be found in at least one translation file

# Define the keys to check
KEYS=(
  "common.FILTER"
  "manualTime.EMPLOYEE"
  "sidebar.PROJECTS"
  "hotkeys.TASK"
  "common.STATUS"
)

# Search for these keys in translation files
echo "Checking translation keys..."
for key in "${KEYS[@]}"; do
  echo "Looking for: $key"
  rg -l "\"$key\"" "public/locales/"
done

Length of output: 1122


Script:

#!/bin/bash
# Let's first find where the translation files are located
fd -t f -e json messages

Length of output: 26


Script:

#!/bin/bash
# Let's try to find any JSON files that might contain translations
fd -t f -e json . | grep -i "lang\|local\|i18n\|translation"

# Also search for translation-related imports to find where translations might be stored
rg -l "useTranslations|i18n|messages" --type ts --type tsx

Length of output: 1069


Script:

#!/bin/bash
# Since we found the translation files in apps/web/locales, let's check for our keys in the English translation file
echo "Checking translation keys in apps/web/locales/en.json:"
cat apps/web/locales/en.json | grep -E "\"(common.FILTER|manualTime.EMPLOYEE|sidebar.PROJECTS|hotkeys.TASK|common.STATUS)\""

Length of output: 243


Script:

#!/bin/bash
# Let's look at the actual structure of the English translation file
echo "Content of apps/web/locales/en.json:"
cat apps/web/locales/en.json

Length of output: 29409

apps/web/app/[locale]/timesheet/[memberId]/page.tsx (2)

Line range hint 1-23: LGTM! Translation setup follows Next.js internationalization best practices.

The implementation correctly uses the useTranslations hook from next-intl and properly types the translation props.


139-141: Verify TimesheetFilter component's translation implementation

The translation prop is correctly passed to TimesheetFilter. Let's verify its implementation.

✅ Verification successful

Translation implementation in TimesheetFilter is correctly handled

The component properly:

  • Defines the translation prop in its interface as t: TranslationHooks
  • Passes the translation prop to child component TimesheetFilterDate
  • Uses the translation function for the "Add Time" button with t('common.ADD_TIME')
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify TimesheetFilter component's translation implementation

# Test: Check if TimesheetFilter component properly uses the translation prop
ast-grep --pattern 'function TimesheetFilter({ t }: { t: TranslationHooks }) {
  $$$
}'

# Test: Look for any remaining hardcoded strings in TimesheetFilter
rg -i "const TimesheetFilter" -A 20 "timesheet/components/TimesheetFilter"

Length of output: 241


Script:

#!/bin/bash
# Let's try to find the TimesheetFilter component file first
fd TimesheetFilter

# Then search for translation usage patterns in the found files
rg -l "t\(" $(fd TimesheetFilter)

# Look for the component definition with translation prop
ast-grep --pattern 'export $_ function TimesheetFilter($_) {
  $$$
}'

Length of output: 588


Script:

#!/bin/bash
# Let's examine the content of TimesheetFilter component
cat apps/web/app/[locale]/timesheet/[memberId]/components/TimesheetFilter.tsx

# Also check for any translation usage
rg "t\(" apps/web/app/[locale]/timesheet/[memberId]/components/TimesheetFilter.tsx -A 2 -B 2

Length of output: 2192

apps/web/app/[locale]/timesheet/[memberId]/components/TimesheetFilterDate.tsx (1)

11-11: LGTM: Translation hook integration looks good!

The addition of the TranslationHooks import and the interface update properly integrate the translation functionality into the component's type system.

Also applies to: 25-25

apps/web/app/[locale]/timesheet/[memberId]/components/EditTaskModal.tsx (1)

117-117: LGTM: Proper translation implementation for date label

The translation implementation follows the project's localization pattern correctly.

apps/web/app/[locale]/permissions/component.tsx (2)

Line range hint 1-294: Overall implementation looks good!

The internationalization changes are well-implemented, making all text content translatable. The code maintains its functionality while improving accessibility for multiple languages, which aligns perfectly with the PR objectives.


105-105: Verify translation key definitions.

The translation keys follow a good hierarchical pattern. However, we should verify that all keys are properly defined in the translation files to avoid runtime errors.

apps/web/lib/features/manual-time/add-manual-time-modal.tsx (1)

Line range hint 82-89: Add validation for realistic time entries.

Consider adding validation to ensure:

  1. Time entries are within reasonable business hours
  2. The duration doesn't exceed a maximum limit (e.g., 24 hours)
  3. The time entry doesn't overlap with existing entries
apps/web/locales/zh.json (1)

257-260: LGTM: Common translations look good!

The new translations for common actions like selecting roles, adding time, and viewing timesheets are clear and consistent with Chinese language conventions.

apps/web/locales/he.json (4)

257-260: LGTM! Common translations are properly added.

The new translations are consistent with the existing Hebrew translations and follow proper grammar.


574-575: LGTM! Billable translations are properly added.

The translations are concise and clear in Hebrew.


578-579: LGTM! Timesheet error messages are properly added.

The translations are well-formed and provide clear user feedback in Hebrew.


Line range hint 257-579: Verify completeness of translations.

Let's ensure all necessary translations are present for the timesheet and task management features.

✅ Verification successful

Based on the output, I can generate the final response since we have comprehensive information about translations across all language files. The output shows that all translation keys are present exactly 13 times (once in each language file: ar.json, bg.json, de.json, en.json, es.json, fr.json, he.json, it.json, nl.json, pl.json, pt.json, ru.json, zh.json).

All translations are consistently present across language files

The verification shows that all translation keys in the Hebrew (he.json) file are properly synchronized with other language files. Each translation key appears exactly 13 times in the output, indicating that it exists in all language files. This confirms that the translations are complete and consistent across the entire localization system.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for missing translations in other language files

# Test: Compare translation keys with other language files
fd -e json . apps/web/locales -x echo "Checking {}" \; -x jq -r 'path(..|select(type=="string")) | join(".")' {} \; | sort | uniq -c

Length of output: 23995

apps/web/locales/ar.json (2)

239-242: LGTM! Translations are accurate and well-formatted.

The new Arabic translations are grammatically correct, culturally appropriate, and maintain consistency with the UI terminology.


573-576: ⚠️ Potential issue

Fix JSON formatting in BILLABLE section.

There's an inconsistency in the trailing commas in the BILLABLE section. Ensure consistent use of trailing commas:

 "BILLABLE": {
   "YES": "نعم",
-  "NO": "لا",
+  "NO": "لا"
   "BILLABLE": "قابل للفوترة"
 }

Likely invalid or redundant comment.

apps/web/locales/en.json (1)

574-575: LGTM! Translations follow existing patterns

The new timesheet-related translations maintain consistent formatting and follow existing patterns for similar messages in the file.

Also applies to: 578-579

apps/web/locales/nl.json (2)

257-260: LGTM! Common translations are well-structured and accurate.

The new translations follow the established naming conventions and provide clear Dutch translations.


578-579: LGTM! Timesheet translations are clear and well-structured.

The translations for timesheet entries are accurate and maintain consistency with the application's tone.

apps/web/locales/bg.json (4)

257-260: LGTM: New common translations are well-structured.

The new translations for role selection and time-related actions are properly formatted and use natural Bulgarian phrasing.


557-558: Improved clarity in timesheet translations.

The updates to timesheet title and description use more precise Bulgarian terminology, making the meaning clearer for users.

Also applies to: 562-562


569-570: LGTM: View and billable translations are accurate.

The translations for list/calendar views and billable status use natural Bulgarian expressions that accurately convey their meaning.

Also applies to: 574-575


577-579: LGTM: Additional timesheet messages are clear.

The new translations for loading states, empty states, and confirmation messages are well-written and maintain consistency with the rest of the interface.

apps/web/locales/pl.json (2)

257-260: LGTM: Common translations are well-structured and accurate.

The new translations for selecting roles, adding time, and viewing timesheets are properly organized under the "common" section and follow the established naming conventions.


574-575: LGTM: Timesheet translations are properly implemented.

The translations for billable status and timesheet messages are correctly nested in their respective sections and maintain consistency with the existing structure.

Also applies to: 578-579

apps/web/locales/ru.json (2)

257-260: LGTM! New translations added to common section.

The new translations for SELECT_AND_CLOSE, SELECT_ROLE, ADD_TIME, and VIEW_TIMESHEET are properly structured and follow the established naming conventions.


574-575: LGTM! Timesheet section updates look good.

The BILLABLE section and updated NO_ENTRIES_FOUND message with rejection confirmation are properly formatted and maintain consistency with the rest of the translations.

Also applies to: 578-579

apps/web/locales/pt.json (3)

257-260: LGTM! Common section translations are properly added.

The new translations for role selection and time actions are consistent and well-structured.


574-575: LGTM! Billable status translations are properly added.

The translations for billable status options are consistent and properly nested under the timesheet section.


578-579: ⚠️ Potential issue

Fix inconsistent language usage in timesheet messages.

The loading message on line 578 is in Russian ("Загрузка данных учета рабочего времени...") while this is a Portuguese (pt) localization file. This should be translated to Portuguese.

Apply this fix:

-			"LOADING": "Загрузка данных учета рабочего времени...",
+			"LOADING": "Carregando dados da folha de ponto...",

Likely invalid or redundant comment.

apps/web/locales/es.json (2)

257-260: LGTM! Common section translations are well-formed.

The new translations are grammatically correct and consistent with Spanish language conventions.


578-579: LGTM! Timesheet messages are well-translated.

The translations for entries not found and rejection confirmation are grammatically correct and maintain a natural flow in Spanish.

apps/web/locales/de.json (3)

257-260: LGTM! Common translations are properly added.

The new translations for role selection and time-related actions are correctly translated to German and maintain consistency with the existing format.


574-575: LGTM! Billable status translations are properly added.

The translations for billable status (Yes/No) are correctly translated to German and maintain consistency with the existing format.


578-579: LGTM! Timesheet-related translations are properly added.

The translations for timesheet entries and rejection confirmation are correctly translated to German and maintain consistency with the existing format.

apps/web/locales/fr.json (3)

257-260: LGTM! Common section translations are well-formed.

The new translations are grammatically correct and maintain consistency with the existing style:

  • "SELECT_AND_CLOSE": "Sélectionner et fermer"
  • "SELECT_ROLE": "Veuillez sélectionner un rôle"
  • "ADD_TIME": "Ajouter du temps"
  • "VIEW_TIMESHEET": "Voir la feuille de temps"

574-575: LGTM! Billable section translations are accurate.

The translations maintain consistency with the existing entries and use appropriate French terms:

  • "NO": "Non"
  • "BILLABLE": "Facturable"

578-579: LGTM! Timesheet section translations are well-structured.

The translations are grammatically correct and maintain a professional tone:

  • "NO_ENTRIES_FOUND": "Aucune entrée de feuille de temps trouvée"
  • "YOU_ARE_ABOUT_TO_REJECT_ENTRY": "Vous êtes sur le point de rejeter l'entrée sélectionnée, souhaitez-vous continuer ?"

@Innocent-Akim Innocent-Akim added the Don't Merge Do not merge this PR until label not removed label Nov 8, 2024
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

🧹 Outside diff range and nitpick comments (2)
apps/web/locales/ar.json (1)

The translation change appears inconsistent with other translations and introduces confusion.

Based on the search results:

  1. The Arabic translation in the desktop app consistently uses "سجل الوقت" (time log) for all time-related entries
  2. In the web app locales, there's a clear distinction between:
    • "WORK_SCHEDULE": "جدول العمل" (work schedule)
    • "TIMESHEET_TITLE": Should be different from work schedule as they represent different concepts

The current change makes "TIMESHEET_TITLE" identical to "WORK_SCHEDULE" (both "جدول العمل"), which:

  • Creates ambiguity between two distinct features
  • Deviates from the consistent terminology used in the desktop app
  • Differs from other languages where timesheet and work schedule are distinctly translated

Recommend changing "TIMESHEET_TITLE" back to "سجل الساعات" to maintain consistency with:

  • The desktop app's terminology
  • The distinction between timesheet and work schedule
  • The pattern seen in other languages where these terms are translated differently
🔗 Analysis chain

Line range hint 562-584: Verify the terminology change for "TIMESHEET_TITLE".

The translation for "TIMESHEET_TITLE" has been changed from "سجل الساعات" (time log) to "جدول العمل" (work schedule). While both are valid translations, they carry slightly different meanings:

  • "سجل الساعات": Emphasizes the logging/recording aspect
  • "جدول العمل": Emphasizes the scheduling aspect

Please verify if this change in terminology is intentional and aligns with the application's intended meaning.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for other occurrences of timesheet-related terminology
rg -i "timesheet.*title|time.*log|work.*schedule" --type json

Length of output: 18513

apps/web/locales/fr.json (1)

579-584: Consider standardizing capitalization in the billable section.

While the translations are accurate, there's an inconsistency in capitalization:

  • "NO": "Non" (lowercase)
  • "BILLABLE": "Facturable" (uppercase)

For consistency with other similar entries in the file, consider using lowercase for "facturable".

 "BILLABLE": {
   "YES": "Oui",
   "NO": "Non",
-  "BILLABLE": "Facturable"
+  "BILLABLE": "facturable"
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between a22a21e and e2f6eb2.

📒 Files selected for processing (14)
  • apps/web/app/[locale]/timesheet/[memberId]/components/TimesheetFilterDate.tsx (6 hunks)
  • apps/web/locales/ar.json (3 hunks)
  • apps/web/locales/bg.json (2 hunks)
  • apps/web/locales/de.json (2 hunks)
  • apps/web/locales/en.json (2 hunks)
  • apps/web/locales/es.json (2 hunks)
  • apps/web/locales/fr.json (2 hunks)
  • apps/web/locales/he.json (2 hunks)
  • apps/web/locales/it.json (2 hunks)
  • apps/web/locales/nl.json (2 hunks)
  • apps/web/locales/pl.json (2 hunks)
  • apps/web/locales/pt.json (2 hunks)
  • apps/web/locales/ru.json (2 hunks)
  • apps/web/locales/zh.json (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (5)
  • apps/web/locales/bg.json
  • apps/web/locales/en.json
  • apps/web/locales/es.json
  • apps/web/locales/it.json
  • apps/web/locales/ru.json
🔇 Additional comments (17)
apps/web/app/[locale]/timesheet/[memberId]/components/TimesheetFilterDate.tsx (4)

11-11: LGTM: Proper integration of translation types

The TranslationHooks import and interface updates correctly integrate the translation functionality into the component's type system.

Also applies to: 25-25


32-33: LGTM: Clean prop implementation

The translation prop is properly destructured alongside other props, following React best practices.


59-62: LGTM: Date presets properly internationalized

The date presets have been successfully internationalized using the translation system.

Also applies to: 68-74, 80-81


112-112: LGTM: Comprehensive UI text internationalization

All UI text elements have been properly internationalized with appropriate translation keys.

Also applies to: 140-140, 149-149, 157-163, 169-173

apps/web/locales/zh.json (2)

257-265: LGTM! Common section translations are well implemented.

The new translations are accurate, maintain consistent style, and properly handle placeholders.


579-584: LGTM! Timesheet section translations are properly implemented.

The translations are accurate, maintain consistent style, and follow proper Chinese grammar conventions.

apps/web/locales/he.json (2)

257-265: LGTM! Common translations are well-structured and properly formatted.

The translations follow proper Hebrew language conventions and maintain consistent RTL formatting. The keys are logically organized and the placeholder usage is correct.


579-580: LGTM! Timesheet translations are accurate and well-organized.

The translations maintain proper Hebrew language conventions and are correctly nested under their respective sections. The confirmation message for rejection is clear and grammatically correct.

Also applies to: 583-584

apps/web/locales/ar.json (1)

239-247: LGTM: New timesheet-related translations are well-structured and accurate.

The new Arabic translations for timesheet functionality are grammatically correct and maintain consistent terminology.

apps/web/locales/nl.json (2)

257-265: LGTM! Common section translations are well-structured and accurate.

The new translations for role selection, time management, and filtering options are properly implemented in Dutch and follow consistent naming patterns.


579-584: LGTM! Timesheet section translations are accurate and well-organized.

The new translations for billable status and rejection confirmation messages are properly implemented in Dutch and maintain consistent structure within the timesheet section.

apps/web/locales/pl.json (2)

257-265: LGTM: Common section translations are well-structured and accurate.

The new translation keys follow the established naming conventions, and the Polish translations are grammatically correct. The placeholder usage in FILTER_THIS_YEAR is properly implemented.


579-584: LGTM: Timesheet section translations are accurate and well-organized.

The translations for billable status and rejection confirmation are properly structured and grammatically correct in Polish.

apps/web/locales/pt.json (1)

257-265: LGTM! Common translations are well-structured and complete.

The new translations maintain consistency with the existing style and properly handle the placeholder in FILTER_THIS_YEAR.

apps/web/locales/de.json (2)

257-265: LGTM! New common section translations are well-structured.

The new translation keys follow the established naming convention, and the German translations are grammatically correct. The placeholder {year} in FILTER_THIS_YEAR is properly formatted.


579-584: LGTM! Timesheet section translations are accurate.

The timesheet-related translations are properly structured and maintain consistency with German language standards. The nested JSON structure is correctly maintained.

apps/web/locales/fr.json (1)

258-265: LGTM! Common section translations are accurate and well-structured.

The new French translations for role selection, time management, and date filtering are linguistically correct and maintain consistency with the existing translations.

@Innocent-Akim Innocent-Akim requested a review from evereq November 8, 2024 19:12
@Innocent-Akim Innocent-Akim added feature WEB Web app Ever Teams and removed Don't Merge Do not merge this PR until label not removed labels Nov 8, 2024
@evereq evereq merged commit d5a4eeb into develop Nov 8, 2024
7 of 13 checks passed
@evereq evereq deleted the feat/add-translations branch November 8, 2024 19:49
@evereq
Copy link
Member

evereq commented Nov 8, 2024

@Innocent-Akim there were merge conflicts and I resolved quickly, but could make a mistakes, please check if all work as it should and do fixes if needed :)

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

Successfully merging this pull request may close these issues.

2 participants