Skip to content

[codex] ユーザー画面の未翻訳箇所をi18n対応#2039

Open
hikahana wants to merge 1 commit intogm3/developfrom
codex/user-i18n-missing-translations
Open

[codex] ユーザー画面の未翻訳箇所をi18n対応#2039
hikahana wants to merge 1 commit intogm3/developfrom
codex/user-i18n-missing-translations

Conversation

@hikahana
Copy link
Copy Markdown
Contributor

@hikahana hikahana commented May 1, 2026

resolved #2033

概要

  • /user の未翻訳表示を既存の next-i18next 構成に合わせて i18n 化
  • 参加形式と物品名は英語表示時に API の name_en を使うように修正
  • 火気使用申請のフォーム、一覧、toast、バリデーションを日英対応
  • ユーザーモーダル、編集ボタン、ローディング表示などの直書き文言を翻訳キーへ移行

背景

英語表示時にも一部の画面文言やマスタ名称が日本語のまま表示されていました。DB/fixture 側に用意されている英語名を使い、UI 文言は locale ファイルに集約しています。

補足

場所名は今年は日本語のままにする方針のため、翻訳対象から外しています。

Summary by CodeRabbit

Release Notes

  • New Features
    • Added comprehensive multi-language support with dynamic text rendering for English and Japanese across all application interfaces, including forms, validation messages, and user-facing labels.
    • Enabled language-specific display for fire equipment applications, login modals, and user profile sections.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 1, 2026

📝 Walkthrough

Walkthrough

This PR introduces comprehensive internationalization support for the Fire Equipment application feature and other UI components. Changes include adding English and Japanese translation entries in locale files, updating API types to support English names, replacing hardcoded Japanese strings with i18n translation keys across Fire Equipment components, and converting various UI components to use translation hooks instead of hardcoded text.

Changes

Cohort / File(s) Summary
Localization Entries
user/public/locales/en/common.json, user/public/locales/ja/common.json
Added translation keys for loginModal.validation (required, email), fireEquipment (fields, fuel options, notes, buttons, messages, validation), and userModal (guest labels, logout toasts) across English and Japanese locales.
Fire Equipment Components
user/src/components/Applications/FireEquipment/FireEquipment.tsx, user/src/components/Applications/FireEquipment/components/FireEquipmentForm.tsx, user/src/components/Applications/FireEquipment/components/FireEquipmentFormView.tsx, user/src/components/Applications/FireEquipment/components/hooks.ts
Replaced hardcoded Japanese strings with useFireEquipmentTexts() hook for form labels, button text, fuel options, radio options (yes/no), notes, and toast messages.
Fire Equipment Constants & Schema
user/src/components/Applications/FireEquipment/constant.ts, user/src/components/Applications/FireEquipment/components/schema.ts, user/src/components/Applications/FireEquipment/hooks.ts
Converted hardcoded form field labels and instruction exports to translation-driven useFireEquipmentTexts() hook; updated validation error messages to use i18n keys; removed exported YES_NAME, NO_NAME constants and replaced with inline literals.
API Type Extensions
user/src/api/groupApi.ts, user/src/api/rentItemsApi.ts
Added optional nameEn field to GroupCategoryResponse and RentalItem types; implemented logic to display English names when current language is English and nameEn exists.
General UI Components
user/src/components/LoginModal/schema.ts, user/src/components/UserModal/UserModal.tsx, user/src/components/UserModal/hooks.ts, user/src/components/Applications/Stage/StageForm/StageForm.tsx, user/src/components/EditButton/EditButton.tsx, user/src/components/Form/TextArea/TextArea.tsx, user/src/icons/Icons.tsx
Replaced hardcoded Japanese text with i18n translation calls; updated login validation messages, user modal guest/email labels, logout toasts, stage form loading message, edit button label, textarea required messages, and loading icon aria-label.
Constants & Utilities
user/src/utils/constant.ts
Removed exported YES_NAME and NO_NAME constants; updated RADIO_OPTIONS to use inline string literals 'yes' and 'no' instead of removed constants.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • PR #1925: Introduced the FireEquipment feature which this PR now adapts with comprehensive i18n support, replacing hardcoded strings with translation-driven hooks and locale entries across all FireEquipment components.
  • PR #1986: Also modifies FireEquipmentFormView.tsx, touching the same component that this PR updates for i18n localization support.

Suggested reviewers

  • KokiWakatsuki

Poem

🐰 A fluffy fix for words so fine,
English and Japanese now align!
Fire equipment speaks many tongues,
Translation magic on everyone's lungs,
From Tokyo to the English lands—
i18n weaves through every command! 🌍✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly describes the main change: adding i18n support for untranslated text on the user screen (/user).
Description check ✅ Passed The PR description follows the template structure with clear sections covering objective, implementation details, and context.
Linked Issues check ✅ Passed The code changes fully address issue #2033 by implementing i18n support for the fire-use application component and related user screen elements across forms, lists, toast messages, and validation.
Out of Scope Changes check ✅ Passed All changes are scoped to implementing i18n support for untranslated text on the user screen, including fire equipment forms, user modal, edit button, loading states, and translation keys for validation messages.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/user-i18n-missing-translations

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
Review rate limit: 0/1 reviews remaining, refill in 60 minutes.

Comment @coderabbitai help to get the list of available commands and usage tips.

@hikahana hikahana marked this pull request as ready for review May 1, 2026 14:16
Copy link
Copy Markdown

@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: 4

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@user/src/components/Applications/FireEquipment/components/FireEquipmentForm.tsx`:
- Around line 86-93: In FireEquipmentForm, the rendering of
fireEquipmentTexts.notes.takeaway only inserts a <br /> after the first split
line so multi-line translations collapse; update the map so a line break is
rendered after every line except the last (e.g., compare index to
takeaway.split('\n').length - 1 or join with interleaved <br />), ensuring
fireEquipmentTexts.notes.takeaway is split on '\n' and each line renders its
following <br /> when not the final element.

In `@user/src/components/Applications/FireEquipment/components/schema.ts`:
- Around line 25-29: The current validation only rejects empty-string remarks;
tighten the check in the schema where ctx.addIssue is called by validating
remarks for undefined/null and whitespace-only content: change the conditional
around data.isTakeaway/data.remarks to use a trimmed emptiness test (e.g.,
!data.remarks || data.remarks.trim() === '') before calling ctx.addIssue so
undefined or whitespace-only remarks also trigger the
'applications.fireEquipment.validation.remarkRequired' error on path
['remarks'].

In `@user/src/components/EditButton/EditButton.tsx`:
- Line 13: The EditButton component's <button> lacks an explicit type which
defaults to "submit" and can cause accidental form submissions; update the
button element in EditButton.tsx to include type="button" (while keeping the
existing className and onClick handler reference OnClick) so clicks only trigger
the OnClick callback and do not submit parent forms.

In `@user/src/icons/Icons.tsx`:
- Line 12: The loading container currently uses a plain div with aria-label
which doesn't guarantee SR announcement; update the loading node in Icons (the
div with className="flex justify-center") to be a proper live status region by
adding role="status" and aria-live="polite" (and optionally aria-busy="true")
while keeping the existing aria-label so screen readers announce the loading
state.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 72b96d3e-f6e8-48b6-9af7-db2e06320517

📥 Commits

Reviewing files that changed from the base of the PR and between 35ebba1 and e8bd8f4.

📒 Files selected for processing (19)
  • user/public/locales/en/common.json
  • user/public/locales/ja/common.json
  • user/src/api/groupApi.ts
  • user/src/api/rentItemsApi.ts
  • user/src/components/Applications/FireEquipment/FireEquipment.tsx
  • user/src/components/Applications/FireEquipment/components/FireEquipmentForm.tsx
  • user/src/components/Applications/FireEquipment/components/FireEquipmentFormView.tsx
  • user/src/components/Applications/FireEquipment/components/hooks.ts
  • user/src/components/Applications/FireEquipment/components/schema.ts
  • user/src/components/Applications/FireEquipment/constant.ts
  • user/src/components/Applications/FireEquipment/hooks.ts
  • user/src/components/Applications/Stage/StageForm/StageForm.tsx
  • user/src/components/EditButton/EditButton.tsx
  • user/src/components/Form/TextArea/TextArea.tsx
  • user/src/components/LoginModal/schema.ts
  • user/src/components/UserModal/UserModal.tsx
  • user/src/components/UserModal/hooks.ts
  • user/src/icons/Icons.tsx
  • user/src/utils/constant.ts

Comment on lines +86 to +93
{fireEquipmentTexts.notes.takeaway
.split('\n')
.map((line, index) => (
<span key={index}>
{line}
{index === 0 && <br />}
</span>
)
)}
))}
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 | 🟡 Minor | ⚡ Quick win

Handle all translated newline breaks, not just the first one.

Line 86-93 currently adds <br /> only after the first line. If a locale string has 3+ lines, later lines will run together.

💡 Proposed fix
-            {fireEquipmentTexts.notes.takeaway
-              .split('\n')
-              .map((line, index) => (
-                <span key={index}>
-                  {line}
-                  {index === 0 && <br />}
-                </span>
-              ))}
+            {fireEquipmentTexts.notes.takeaway
+              .split('\n')
+              .map((line, index, lines) => (
+                <span key={`${line}-${index}`}>
+                  {line}
+                  {index < lines.length - 1 && <br />}
+                </span>
+              ))}
📝 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
{fireEquipmentTexts.notes.takeaway
.split('\n')
.map((line, index) => (
<span key={index}>
{line}
{index === 0 && <br />}
</span>
)
)}
))}
{fireEquipmentTexts.notes.takeaway
.split('\n')
.map((line, index, lines) => (
<span key={`${line}-${index}`}>
{line}
{index < lines.length - 1 && <br />}
</span>
))}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In
`@user/src/components/Applications/FireEquipment/components/FireEquipmentForm.tsx`
around lines 86 - 93, In FireEquipmentForm, the rendering of
fireEquipmentTexts.notes.takeaway only inserts a <br /> after the first split
line so multi-line translations collapse; update the map so a line break is
rendered after every line except the last (e.g., compare index to
takeaway.split('\n').length - 1 or join with interleaved <br />), ensuring
fireEquipmentTexts.notes.takeaway is split on '\n' and each line renders its
following <br /> when not the final element.

Comment on lines 25 to 29
if (!data.isTakeaway && data.remarks == '') {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: '持ち帰りが「いいえ」の場合、備考欄は必須です',
message: 'applications.fireEquipment.validation.remarkRequired',
path: ['remarks'],
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 | 🟡 Minor | ⚡ Quick win

Tighten non-takeaway remark validation.

Line 25 only checks ''; undefined or whitespace-only remarks can bypass this requirement.

Suggested fix
-    if (!data.isTakeaway && data.remarks == '') {
+    if (!data.isTakeaway && !data.remarks?.trim()) {
       ctx.addIssue({
         code: z.ZodIssueCode.custom,
         message: 'applications.fireEquipment.validation.remarkRequired',
         path: ['remarks'],
       });
     }
📝 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
if (!data.isTakeaway && data.remarks == '') {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: '持ち帰りが「いいえ」の場合、備考欄は必須です',
message: 'applications.fireEquipment.validation.remarkRequired',
path: ['remarks'],
if (!data.isTakeaway && !data.remarks?.trim()) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: 'applications.fireEquipment.validation.remarkRequired',
path: ['remarks'],
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@user/src/components/Applications/FireEquipment/components/schema.ts` around
lines 25 - 29, The current validation only rejects empty-string remarks; tighten
the check in the schema where ctx.addIssue is called by validating remarks for
undefined/null and whitespace-only content: change the conditional around
data.isTakeaway/data.remarks to use a trimmed emptiness test (e.g.,
!data.remarks || data.remarks.trim() === '') before calling ctx.addIssue so
undefined or whitespace-only remarks also trigger the
'applications.fireEquipment.validation.remarkRequired' error on path
['remarks'].

const { t } = useTranslation('common');

return (
<button className="flex w-32 gap-3" onClick={OnClick}>
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 | 🟠 Major | ⚡ Quick win

Set an explicit button type to prevent unintended form submits.

<button> defaults to submit, so this can trigger accidental form submission when rendered inside a form wrapper.

Suggested fix
-    <button className="flex w-32 gap-3" onClick={OnClick}>
+    <button type="button" className="flex w-32 gap-3" onClick={OnClick}>
📝 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
<button className="flex w-32 gap-3" onClick={OnClick}>
<button type="button" className="flex w-32 gap-3" onClick={OnClick}>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@user/src/components/EditButton/EditButton.tsx` at line 13, The EditButton
component's <button> lacks an explicit type which defaults to "submit" and can
cause accidental form submissions; update the button element in EditButton.tsx
to include type="button" (while keeping the existing className and onClick
handler reference OnClick) so clicks only trigger the OnClick callback and do
not submit parent forms.

Comment thread user/src/icons/Icons.tsx
const { t } = useTranslation('common');

return (
<div className="flex justify-center" aria-label={t('general.loading')}>
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 | 🟡 Minor | ⚡ Quick win

Add status semantics so screen readers announce the loading state.

On a plain div, aria-label is weak for announcement. Mark this as a live status region.

Suggested fix
-    <div className="flex justify-center" aria-label={t('general.loading')}>
+    <div
+      className="flex justify-center"
+      role="status"
+      aria-live="polite"
+      aria-label={t('general.loading')}
+    >
📝 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
<div className="flex justify-center" aria-label={t('general.loading')}>
<div
className="flex justify-center"
role="status"
aria-live="polite"
aria-label={t('general.loading')}
>
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@user/src/icons/Icons.tsx` at line 12, The loading container currently uses a
plain div with aria-label which doesn't guarantee SR announcement; update the
loading node in Icons (the div with className="flex justify-center") to be a
proper live status region by adding role="status" and aria-live="polite" (and
optionally aria-busy="true") while keeping the existing aria-label so screen
readers announce the loading state.

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.

[fix] user画面の火器使用申請の英語対応

1 participant