Repository: KivSystemAdmin/aaasobo-management-system
Pull request #91: 87 add japanese to auth forms
Author: login: Shingo023
Created: 2025-05-08T01:31:34Z | Merged: 2025-05-15T18:13:07Z

### Overview
This PR introduces Japanese language support on the customer login page.

### Review Preparation

1. Run `npm run prisma:init` in the backend directory.
2. Set your browser language to Japanese temporarily.
![スクリーンショット 2025-05-07 午後4 04 19](https://github.com/user-attachments/assets/cd75a46c-8643-4824-99f8-de8909c50c35)

3. Navigate to the customer login page.

### Review Points

1. Confirm that the login page is displayed in Japanese.
![スクリーンショット 2025-05-07 午後4 03 22](https://github.com/user-attachments/assets/fb2559fd-d101-4786-b7fd-8dfee6913d24)
2. Try to log in with the email: kiv-developers@googlegroups.com and password: AaasoBo!Alice, and confirm that the error message is shown in Japanese — in this PR, Alice's email has not been verified.
![スクリーンショット 2025-05-07 午後4 07 34](https://github.com/user-attachments/assets/88234f6f-086a-4855-b11e-259d40e21e19)
3. Try to log in with an incorrect password or email, and confirm that the error message appears in Japanese.
![スクリーンショット 2025-05-07 午後4 05 53](https://github.com/user-attachments/assets/555e03d7-bef0-4be3-bacc-bf7b136926ca)




Diff:
diff --git a/backend/src/seed/dummy.ts b/backend/src/seed/dummy.ts
index 5f164c98..2c2c5d9d 100644
--- a/backend/src/seed/dummy.ts
+++ b/backend/src/seed/dummy.ts
@@ -963,7 +963,7 @@ async function main() {
     await insertAdmins();
 
     // Dependant on the above
-    // await insertInstructorAvailabilities();
+    await insertInstructorAvailabilities();
     await insertSubscriptions();
     await insertChildren();
 
diff --git a/frontend/src/app/actions/authActions.ts b/frontend/src/app/actions/authActions.ts
index 2d04cf6f..e7f138bf 100644
--- a/frontend/src/app/actions/authActions.ts
+++ b/frontend/src/app/actions/authActions.ts
@@ -5,17 +5,21 @@ import { signIn, signOut } from "../../../auth.config";
 import { userLoginSchema } from "../schemas/authSchema";
 import { extractLoginValidationErrors } from "../helper/utils/validationErrorUtils";
 import { authenticateUser } from "../helper/api/usersApi";
-import { GENERAL_ERROR_MESSAGE } from "../helper/messages/formValidation";
+import {
+  GENERAL_ERROR_MESSAGE,
+  GENERAL_ERROR_MESSAGE_JA,
+} from "../helper/messages/formValidation";
 
 export async function authenticate(
   prevState: { errorMessage: string } | undefined,
   formData: FormData,
 ): Promise<{ errorMessage: string } | undefined> {
-  try {
-    const email = formData.get("email");
-    const password = formData.get("password");
-    const userType = formData.get("userType");
+  const email = formData.get("email");
+  const password = formData.get("password");
+  const userType = formData.get("userType");
+  const language = formData.get("language") as LanguageType;
 
+  try {
     const parsedForm = userLoginSchema.safeParse({
       email,
       password,
@@ -24,13 +28,14 @@ export async function authenticate(
 
     if (!parsedForm.success) {
       const validationErrors = parsedForm.error.errors;
-      return extractLoginValidationErrors(validationErrors);
+      return extractLoginValidationErrors(validationErrors, language);
     }
 
     const response = await authenticateUser(
       parsedForm.data.email,
       parsedForm.data.password,
       parsedForm.data.userType,
+      language,
     );
 
     if ("errorMessage" in response) {
@@ -53,7 +58,8 @@ export async function authenticate(
     if (error instanceof AuthError) {
       console.error("Error in authenticate server action:", error);
       return {
-        errorMessage: GENERAL_ERROR_MESSAGE,
+        errorMessage:
+          language === "ja" ? GENERAL_ERROR_MESSAGE_JA : GENERAL_ERROR_MESSAGE,
       };
     }
     // Re-throw non-auth errors so that Next.js can handle redirects properly.
diff --git a/frontend/src/app/components/elements/formValidationMessage/FormValidationMessage.module.scss b/frontend/src/app/components/elements/formValidationMessage/FormValidationMessage.module.scss
index 5800ceb9..d7d992d8 100644
--- a/frontend/src/app/components/elements/formValidationMessage/FormValidationMessage.module.scss
+++ b/frontend/src/app/components/elements/formValidationMessage/FormValidationMessage.module.scss
@@ -1,6 +1,7 @@
 @import "../../../variables.module.scss";
 
 .message {
+  width: 100%;
   display: flex;
   gap: 0.5rem;
   align-items: center;
diff --git a/frontend/src/app/components/elements/textInput/TextInput.tsx b/frontend/src/app/components/elements/textInput/TextInput.tsx
index 8d928db7..928bb78a 100644
--- a/frontend/src/app/components/elements/textInput/TextInput.tsx
+++ b/frontend/src/app/components/elements/textInput/TextInput.tsx
@@ -6,7 +6,7 @@ import FormValidationMessage from "../formValidationMessage/FormValidationMessag
 
 type TextInputProps = {
   id?: string;
-  label: string;
+  label?: string;
   type: string;
   value?: string;
   placeholder: string;
@@ -21,6 +21,7 @@ type TextInputProps = {
   autoComplete?: string;
   showPassword?: boolean;
   onTogglePasswordVisibility?: () => void;
+  language?: LanguageType;
 };
 
 function TextInput({
@@ -40,6 +41,7 @@ function TextInput({
   autoComplete,
   showPassword = false,
   onTogglePasswordVisibility,
+  language = "en",
 }: TextInputProps) {
   return (
     <div className={styles.inputWrapper}>
@@ -63,7 +65,15 @@ function TextInput({
           />
           {type === "password" && (
             <Tooltip
-              message={showPassword ? "Click to hide" : "Click to reveal"}
+              message={
+                language === "ja"
+                  ? showPassword
+                    ? "パスワードを非表示"
+                    : "パスワードを表示"
+                  : showPassword
+                    ? "Click to hide"
+                    : "Click to reveal"
+              }
             >
               <div
                 className={styles.eyeIcon}
diff --git a/frontend/src/app/components/features/loginForm/LoginForm.module.scss b/frontend/src/app/components/features/loginForm/LoginForm.module.scss
index 56ac4f2d..b76ccfd8 100644
--- a/frontend/src/app/components/features/loginForm/LoginForm.module.scss
+++ b/frontend/src/app/components/features/loginForm/LoginForm.module.scss
@@ -35,4 +35,8 @@
 .resetLink {
   font-size: 0.9rem;
   text-decoration: none;
+
+  &:hover {
+    text-decoration: underline;
+  }
 }
diff --git a/frontend/src/app/components/features/loginForm/LoginForm.tsx b/frontend/src/app/components/features/loginForm/LoginForm.tsx
index f5266599..5656cb76 100644
--- a/frontend/src/app/components/features/loginForm/LoginForm.tsx
+++ b/frontend/src/app/components/features/loginForm/LoginForm.tsx
@@ -11,7 +11,13 @@ import { useFormMessages } from "@/app/hooks/useFormMessages";
 import Link from "next/link";
 import FormValidationMessage from "../../elements/formValidationMessage/FormValidationMessage";
 
-export default function LoginForm({ userType }: { userType: UserType }) {
+export default function LoginForm({
+  userType,
+  language,
+}: {
+  userType: UserType;
+  language: LanguageType;
+}) {
   const [errorState, formAction] = useFormState(authenticate, undefined);
   const [showPassword, setShowPassword] = useState(false);
   const { localMessages, clearErrorMessage } = useFormMessages(errorState);
@@ -20,10 +26,9 @@ export default function LoginForm({ userType }: { userType: UserType }) {
     <form action={formAction} className={styles.form}>
       <TextInput
         id="email"
-        label="Email"
         type="email"
         name="email"
-        placeholder="e.g., example@aaasobo.com"
+        placeholder={language === "ja" ? "メール" : "e-mail"}
         icon={<EnvelopeIcon className={styles.icon} />}
         required={true}
         onChange={() => clearErrorMessage("message")}
@@ -31,29 +36,34 @@ export default function LoginForm({ userType }: { userType: UserType }) {
 
       <TextInput
         id="password"
-        label="Password"
         type="password"
         name="password"
-        placeholder="Enter password"
+        placeholder={language === "ja" ? "パスワード" : "password"}
         icon={<LockClosedIcon className={styles.icon} />}
         required={true}
         showPassword={showPassword}
         onTogglePasswordVisibility={() => setShowPassword((prev) => !prev)}
         onChange={() => clearErrorMessage("message")}
+        language={language}
       />
 
       {/* Hidden input to send necessary data with form submission. */}
       <input type="hidden" name="userType" value={userType ?? ""} />
+      <input type="hidden" name="language" value={language ?? "en"} />
 
       <Link
         className={styles.resetLink}
         href={`/auth/forgot-password?type=${userType}`}
       >
-        Forgot Password?
+        {language === "ja" ? "パスワードを忘れた場合" : "Forgot Password?"}
       </Link>
 
       <div className={styles.buttonWrapper}>
-        <ActionButton btnText="Login" className="bookBtn" type="submit" />
+        <ActionButton
+          btnText={language === "ja" ? "ログイン" : "Login"}
+          className="bookBtn"
+          type="submit"
+        />
       </div>
 
       <div className={styles.errorWrapper}>
diff --git a/frontend/src/app/customers/login/page.module.scss b/frontend/src/app/customers/login/page.module.scss
index fd8834a1..8d378852 100644
--- a/frontend/src/app/customers/login/page.module.scss
+++ b/frontend/src/app/customers/login/page.module.scss
@@ -18,7 +18,7 @@
   display: flex;
   flex-direction: column;
   align-items: center;
-  max-width: 350px;
+  max-width: 360px;
   width: 100%;
 
   h2 {
diff --git a/frontend/src/app/customers/login/page.tsx b/frontend/src/app/customers/login/page.tsx
index 1e4e50f9..6a061907 100644
--- a/frontend/src/app/customers/login/page.tsx
+++ b/frontend/src/app/customers/login/page.tsx
@@ -1,10 +1,15 @@
+"use client";
+
 import Image from "next/image";
 import Link from "next/link";
 import React from "react";
 import styles from "./page.module.scss";
 import LoginForm from "@/app/components/features/loginForm/LoginForm";
+import { useLanguage } from "@/app/contexts/LanguageContext";
 
 export default function LoginPage() {
+  const { language } = useLanguage();
+
   return (
     <main className={styles.outsideContainer}>
       <div className={styles.container}>
@@ -16,11 +21,16 @@ export default function LoginPage() {
           className={styles.logo}
           priority={true}
         />
-        <h2>Login</h2>
+        <h2>{language === "ja" ? "ログイン" : "Login"}</h2>
         <p>
-          Not a member yet? <Link href="/customers/register">Join us!</Link>
+          {language === "ja"
+            ? "アカウントをお持ちでないですか？"
+            : "Not a member yet?"}{" "}
+          <Link href="/customers/register">
+            {language === "ja" ? "登録する" : "Join us!"}
+          </Link>
         </p>
-        <LoginForm userType="customer" />
+        <LoginForm userType="customer" language={language} />
       </div>
     </main>
   );
diff --git a/frontend/src/app/globals.scss b/frontend/src/app/globals.scss
index 5256cfe6..11023f7a 100644
--- a/frontend/src/app/globals.scss
+++ b/frontend/src/app/globals.scss
@@ -1,13 +1,9 @@
 @import "./variables.module.scss";
 
-:root {
-}
-
 * {
   box-sizing: border-box;
   padding: 0;
   margin: 0;
-  font-family: inherit;
 }
 
 html,
diff --git a/frontend/src/app/helper/api/usersApi.ts b/frontend/src/app/helper/api/usersApi.ts
index ab26263c..c374ccbf 100644
--- a/frontend/src/app/helper/api/usersApi.ts
+++ b/frontend/src/app/helper/api/usersApi.ts
@@ -7,6 +7,7 @@ import {
   EMAIL_VERIFICATION_TOKEN_EXPIRED,
   EMAIL_VERIFICATION_UNEXPECTED_ERROR,
   GENERAL_ERROR_MESSAGE,
+  GENERAL_ERROR_MESSAGE_JA,
   LOGIN_FAILED_MESSAGE,
   PASSWORD_RESET_EMAIL_SEND_FAILURE,
   PASSWORD_RESET_EMAIL_SENT_MESSAGE,
@@ -24,15 +25,16 @@ export const authenticateUser = async (
   email: string,
   password: string,
   userType: UserType,
+  language: LanguageType,
 ): Promise<{ userId: number } | { errorMessage: string }> => {
   const apiUrl = `${BACKEND_ORIGIN}/users/authenticate`;
   const headers = { "Content-Type": "application/json" };
   const body = JSON.stringify({ email, password, userType });
 
   const statusErrorMessages: Record<number, string> = {
-    401: LOGIN_FAILED_MESSAGE,
-    503: CONFIRMATION_EMAIL_RESEND_FAILURE,
-    403: EMAIL_VERIFICATION_RESENT_NOTICE,
+    401: LOGIN_FAILED_MESSAGE[language],
+    503: CONFIRMATION_EMAIL_RESEND_FAILURE[language],
+    403: EMAIL_VERIFICATION_RESENT_NOTICE[language],
   };
 
   try {
@@ -55,7 +57,10 @@ export const authenticateUser = async (
     return { userId: data.id };
   } catch (error) {
     console.error("API error while authenticating[logging in] user:", error);
-    return { errorMessage: GENERAL_ERROR_MESSAGE };
+    return {
+      errorMessage:
+        language === "ja" ? GENERAL_ERROR_MESSAGE_JA : GENERAL_ERROR_MESSAGE,
+    };
   }
 };
 
diff --git a/frontend/src/app/helper/messages/customerDashboard.ts b/frontend/src/app/helper/messages/customerDashboard.ts
index e54fed9d..0497ac3b 100644
--- a/frontend/src/app/helper/messages/customerDashboard.ts
+++ b/frontend/src/app/helper/messages/customerDashboard.ts
@@ -1,17 +1,17 @@
 export const FAILED_TO_FETCH_BOOKABLE_CLASSES =
-  "We couldn't load the available classes. Please try again later. / 利用可能なクラスを読み込めませんでした。後ほどもう一度お試しください。";
+  "We couldn’t load your available classes to rebook. Please refresh the page or try again later. / 振替予約可能クラスの読み込みに失敗しました。ページを再読み込みするか、しばらくしてからもう一度お試しください。";
 
 export const INVALID_CUSTOMER_ID =
-  "We encountered an issue while processing the customer ID. Please try again later. / カスタマーIDの処理中に問題が発生しました。後ほどもう一度お試しください。";
+  "We encountered an issue while processing your ID. Please refresh the page or try again later. / カスタマーIDの処理中に問題が発生しました。ページを再読み込みするか、しばらくしてからもう一度お試しください。";
 
 export const FAILED_TO_FETCH_UPCOMING_CLASSES =
-  "We couldn't load the upcoming classes. Please try again later. / 予約済みクラスを読み込めませんでした。後ほどもう一度お試しください。";
+  "We couldn't load your upcoming classes. Please refresh the page or try again later. / 予約済みクラスの読み込みに失敗しました。ページを再読み込みするか、しばらくしてからもう一度お試しください。";
 
 export const FAILED_TO_FETCH_CUSTOMER_CLASSES =
-  "We couldn't load the classes. Please try again later. / クラスを読み込めませんでした。後ほどもう一度お試しください。";
+  "We couldn't load your classes. Please refresh the page or try again later. / クラスの読み込みに失敗しました。ページを再読み込みするか、しばらくしてからもう一度お試しください。";
 
 export const FAILED_TO_FETCH_CUSTOMER_PROFILE =
-  "We couldn't load the customer's profile. Please try again later. / プロフィールを読み込めませんでした。後ほどもう一度お試しください。";
+  "We couldn’t load your profile. Please refresh the page or try again later. / プロフィールの読み込みに失敗しました。ページを再読み込みするか、しばらくしてからもう一度お試しください。";
 
 export const CANCELATION_NOT_ALLOWED_MESSAGE = {
   ja: "日本時間を基準とし、クラスは予定日の当日以降、キャンセルできません。",
diff --git a/frontend/src/app/helper/messages/formValidation.ts b/frontend/src/app/helper/messages/formValidation.ts
index d3afe8de..705b8330 100644
--- a/frontend/src/app/helper/messages/formValidation.ts
+++ b/frontend/src/app/helper/messages/formValidation.ts
@@ -1,5 +1,7 @@
 export const GENERAL_ERROR_MESSAGE =
   "Something went wrong. Please try again shortly. If the problem persists, contact our staff. We apologize for the inconvenience.";
+export const GENERAL_ERROR_MESSAGE_JA =
+  "エラーが発生しました。しばらくしてから再度お試しください。問題が解決しない場合は、スタッフまでお問い合わせください。ご不便をおかけして申し訳ありません。";
 
 // RegisterForm
 export const EMAIL_ALREADY_REGISTERED_ERROR =
@@ -29,13 +31,20 @@ export const INSTRUCTOR_REGISTRATION_SUCCESS_MESSAGE =
   "The instructor account has been created successfully.";
 
 // LoginForm
-export const LOGIN_FAILED_MESSAGE = "Invalid email or password.";
+export const LOGIN_FAILED_MESSAGE = {
+  ja: "メールアドレスまたはパスワードが正しくありません。",
+  en: "Invalid email or password.",
+};
 
-export const CONFIRMATION_EMAIL_RESEND_FAILURE =
-  "Your email hasn't been verified yet. We tried to resend the verification link but failed. Please check your inbox for a previous link, or try logging in again later to resend it.";
+export const CONFIRMATION_EMAIL_RESEND_FAILURE = {
+  ja: "メールアドレスがまだ認証されていません。確認リンクの再送信を試みましたが、失敗しました。以前お送りしたリンクを受信トレイでご確認いただくか、後ほど再度ログインしてリンクの再送信をお試しください。",
+  en: "Your email hasn't been verified yet. We tried to resend the verification link but failed. Please check your inbox for a previous link, or try logging in again later to resend it.",
+};
 
-export const EMAIL_VERIFICATION_RESENT_NOTICE =
-  "Your email address is not verified yet. We have resent the verification link via email.";
+export const EMAIL_VERIFICATION_RESENT_NOTICE = {
+  ja: "メールアドレスがまだ認証されていません。確認リンクをメールで再送しましたのでご確認ください。",
+  en: "Your email address is not verified yet. We have resent the verification link via email.",
+};
 
 // EmailVerificationForm
 export const EMAIL_VERIFICATION_TOKEN_NOT_FOUND =
diff --git a/frontend/src/app/helper/utils/validationErrorUtils.ts b/frontend/src/app/helper/utils/validationErrorUtils.ts
index c638aef3..8746e99c 100644
--- a/frontend/src/app/helper/utils/validationErrorUtils.ts
+++ b/frontend/src/app/helper/utils/validationErrorUtils.ts
@@ -2,6 +2,7 @@ import { ZodFormattedError } from "zod";
 import { ZodIssue } from "zod";
 import {
   GENERAL_ERROR_MESSAGE,
+  GENERAL_ERROR_MESSAGE_JA,
   LOGIN_FAILED_MESSAGE,
   PASSWORD_RESET_TOKEN_OR_USER_TYPE_ERROR,
 } from "../messages/formValidation";
@@ -47,7 +48,10 @@ export function extractUpdateValidationErrors(
   return errors;
 }
 
-export function extractLoginValidationErrors(validationErrors: ZodIssue[]): {
+export function extractLoginValidationErrors(
+  validationErrors: ZodIssue[],
+  language: LanguageType,
+): {
   errorMessage: string;
 } {
   const unexpectedError = validationErrors.some(
@@ -55,9 +59,12 @@ export function extractLoginValidationErrors(validationErrors: ZodIssue[]): {
   );
 
   if (unexpectedError) {
-    return { errorMessage: GENERAL_ERROR_MESSAGE };
+    return {
+      errorMessage:
+        language === "ja" ? GENERAL_ERROR_MESSAGE_JA : GENERAL_ERROR_MESSAGE,
+    };
   }
-  return { errorMessage: LOGIN_FAILED_MESSAGE };
+  return { errorMessage: LOGIN_FAILED_MESSAGE[language] };
 }
 
 export function extractResetRequestValidationErrors(
diff --git a/frontend/src/app/instructors/login/page.module.scss b/frontend/src/app/instructors/login/page.module.scss
index 13aa4592..c7ecdaa2 100644
--- a/frontend/src/app/instructors/login/page.module.scss
+++ b/frontend/src/app/instructors/login/page.module.scss
@@ -18,11 +18,11 @@
   display: flex;
   flex-direction: column;
   align-items: center;
-  max-width: 350px;
+  max-width: 360px;
   width: 100%;
 
   h2 {
-    margin-bottom: 0.3rem;
+    margin-bottom: 2rem;
   }
 }
 
diff --git a/frontend/src/app/instructors/login/page.tsx b/frontend/src/app/instructors/login/page.tsx
index e79521a2..aa9e4e6f 100644
--- a/frontend/src/app/instructors/login/page.tsx
+++ b/frontend/src/app/instructors/login/page.tsx
@@ -16,7 +16,7 @@ export default function LoginPage() {
           priority={true}
         />
         <h2>Login for instructors</h2>
-        <LoginForm userType="instructor" />
+        <LoginForm userType="instructor" language="en" />
       </div>
     </main>
   );
diff --git a/frontend/src/app/layout.tsx b/frontend/src/app/layout.tsx
index 3c1bc65c..40f786f4 100644
--- a/frontend/src/app/layout.tsx
+++ b/frontend/src/app/layout.tsx
@@ -6,7 +6,6 @@ import { LanguageProvider } from "./contexts/LanguageContext";
 
 const poppins = Poppins({
   subsets: ["latin"],
-  variable: "--font-poppins",
   display: "swap",
   weight: [
     "100", // Thin


Reviews:
user: login: mtkksk1780
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-10T16:49:59Z
user: login: mtkksk1780
body: Thank you for the great work! Everything worked well as you instructed. I have left one comment. If you're happy to incorporate my suggestion, I will update the related files in future PRs as well!
state: APPROVED
author_association: MEMBER
submitted_at: 2025-05-10T16:50:08Z
user: login: Shingo023
state: COMMENTED
author_association: COLLABORATOR
submitted_at: 2025-05-11T01:08:39Z
user: login: mtkksk1780
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-05-12T15:52:16Z

Review comments:
diff_hunk: @@ -5,17 +5,21 @@ import { signIn, signOut } from "../../../auth.config";
 import { userLoginSchema } from "../schemas/authSchema";
 import { extractLoginValidationErrors } from "../helper/utils/validationErrorUtils";
 import { authenticateUser } from "../helper/api/usersApi";
-import { GENERAL_ERROR_MESSAGE } from "../helper/messages/formValidation";
+import {
+  GENERAL_ERROR_MESSAGE,
+  GENERAL_ERROR_MESSAGE_JA,
+} from "../helper/messages/formValidation";
 
 export async function authenticate(
   prevState: { errorMessage: string } | undefined,
   formData: FormData,
 ): Promise<{ errorMessage: string } | undefined> {
-  try {
-    const email = formData.get("email");
-    const password = formData.get("password");
-    const userType = formData.get("userType");
+  const email = formData.get("email");
+  const password = formData.get("password");
+  const userType = formData.get("userType");
+  const language = formData.get("language") as LanguageType;
path: frontend/src/app/actions/authActions.ts
user: login: mtkksk1780
body: It might be a good idea to set the type on line 19 to align the concept with `LanguageType`.

`const userType = formData.get("userType") as UserType;`
created_at: 2025-05-10T16:49:59Z
author_association: MEMBER
diff_hunk: @@ -5,17 +5,21 @@ import { signIn, signOut } from "../../../auth.config";
 import { userLoginSchema } from "../schemas/authSchema";
 import { extractLoginValidationErrors } from "../helper/utils/validationErrorUtils";
 import { authenticateUser } from "../helper/api/usersApi";
-import { GENERAL_ERROR_MESSAGE } from "../helper/messages/formValidation";
+import {
+  GENERAL_ERROR_MESSAGE,
+  GENERAL_ERROR_MESSAGE_JA,
+} from "../helper/messages/formValidation";
 
 export async function authenticate(
   prevState: { errorMessage: string } | undefined,
   formData: FormData,
 ): Promise<{ errorMessage: string } | undefined> {
-  try {
-    const email = formData.get("email");
-    const password = formData.get("password");
-    const userType = formData.get("userType");
+  const email = formData.get("email");
+  const password = formData.get("password");
+  const userType = formData.get("userType");
+  const language = formData.get("language") as LanguageType;
path: frontend/src/app/actions/authActions.ts
user: login: Shingo023
body: Unlike the `Language` type, the `userType` is checked and defined in the following section, so I don't think it's necessary to explicitly define it here. What do you think?

```
    const parsedForm = userLoginSchema.safeParse({
      email,
      password,
      userType,
    });
```
created_at: 2025-05-11T01:08:39Z
author_association: COLLABORATOR
diff_hunk: @@ -5,17 +5,21 @@ import { signIn, signOut } from "../../../auth.config";
 import { userLoginSchema } from "../schemas/authSchema";
 import { extractLoginValidationErrors } from "../helper/utils/validationErrorUtils";
 import { authenticateUser } from "../helper/api/usersApi";
-import { GENERAL_ERROR_MESSAGE } from "../helper/messages/formValidation";
+import {
+  GENERAL_ERROR_MESSAGE,
+  GENERAL_ERROR_MESSAGE_JA,
+} from "../helper/messages/formValidation";
 
 export async function authenticate(
   prevState: { errorMessage: string } | undefined,
   formData: FormData,
 ): Promise<{ errorMessage: string } | undefined> {
-  try {
-    const email = formData.get("email");
-    const password = formData.get("password");
-    const userType = formData.get("userType");
+  const email = formData.get("email");
+  const password = formData.get("password");
+  const userType = formData.get("userType");
+  const language = formData.get("language") as LanguageType;
path: frontend/src/app/actions/authActions.ts
user: login: mtkksk1780
body: I see... If my understanding below is correct, I also believe it is not a must-have requirement.

- `userLoginSchema` that you mentioned above is a validation function for all types of users 
- `LanguageType` is currently used only for customers

I thought it should be included in `userLoginSchema` based on your comment, but on second thought, that doesn’t seem appropriate for the reasons above.

In summary, I'm on your side now. Thank you for sharing your thoughts!
created_at: 2025-05-12T15:52:16Z
author_association: MEMBER

PR comments:
user: login: vercel[bot]
created_at: 2025-05-08T01:31:38Z
body: [vc]: #0TP+2MTxarQygH0+mY5LMvXrSiOc2tH+0w3trPgGRGw=:eyJpc01vbm9yZXBvIjp0cnVlLCJ0eXBlIjoiZ2l0aHViIiwicHJvamVjdHMiOlt7Im5hbWUiOiJhYWFzb2JvLW1hbmFnZW1lbnQtc3lzdGVtLWZyb250ZW5kIiwicm9vdERpcmVjdG9yeSI6ImZyb250ZW5kIiwibGl2ZUZlZWRiYWNrIjp7InJlc29sdmVkIjowLCJ1bnJlc29sdmVkIjowLCJ0b3RhbCI6MCwibGluayI6IiJ9LCJpbnNwZWN0b3JVcmwiOiJodHRwczovL3ZlcmNlbC5jb20va2l2c3lzdGVtYWRtaW5zLXByb2plY3RzL2FhYXNvYm8tbWFuYWdlbWVudC1zeXN0ZW0tZnJvbnRlbmQvRDF2NXpoYnpRNEJiaTlNVVBoVGhtN2YzR3pNRSIsIm5leHRDb21taXRTdGF0dXMiOiJJR05PUkVEIiwicHJldmlld1VybCI6ImFhYXNvYm8tbWFuYWdlbWVudC1zeXN0ZW0tZi1naXQtYjZkZGY3LWtpdnN5c3RlbWFkbWlucy1wcm9qZWN0cy52ZXJjZWwuYXBwIn0seyJuYW1lIjoiYWFhc29iby1tYW5hZ2VtZW50LXN5c3RlbS1iYWNrZW5kIiwicm9vdERpcmVjdG9yeSI6ImJhY2tlbmQiLCJsaXZlRmVlZGJhY2siOnsicmVzb2x2ZWQiOjAsInVucmVzb2x2ZWQiOjAsInRvdGFsIjowLCJsaW5rIjoiIn0sImluc3BlY3RvclVybCI6Imh0dHBzOi8vdmVyY2VsLmNvbS9raXZzeXN0ZW1hZG1pbnMtcHJvamVjdHMvYWFhc29iby1tYW5hZ2VtZW50LXN5c3RlbS1iYWNrZW5kL3F0THB2ZkhIWHBxTVV4OVNrNjJxUWpUQVdVRWEiLCJuZXh0Q29tbWl0U3RhdHVzIjoiSUdOT1JFRCIsInByZXZpZXdVcmwiOiJhYWFzb2JvLW1hbmFnZW1lbnQtc3lzdGVtLWItZ2l0LWEzYzQ2My1raXZzeXN0ZW1hZG1pbnMtcHJvamVjdHMudmVyY2VsLmFwcCJ9XX0=
**The latest updates on your projects**. Learn more about [Vercel for Git ↗︎](https://vercel.link/github-learn-more)


<details><summary>2 Skipped Deployments</summary>

| Name | Status | Preview | Comments | Updated (UTC) |
| :--- | :----- | :------ | :------- | :------ |
| **aaasobo-management-system-backend** | ⬜️ Ignored ([Inspect](https://vercel.com/kivsystemadmins-projects/aaasobo-management-system-backend/qtLpvfHHXpqMUx9Sk62qQjTAWUEa)) | [Visit Preview](https://aaasobo-management-system-b-git-a3c463-kivsystemadmins-projects.vercel.app) |  | May 11, 2025 1:37am |
| **aaasobo-management-system-frontend** | ⬜️ Ignored ([Inspect](https://vercel.com/kivsystemadmins-projects/aaasobo-management-system-frontend/D1v5zhbzQ4Bbi9MUPhThm7f3GzME)) | [Visit Preview](https://aaasobo-management-system-f-git-b6ddf7-kivsystemadmins-projects.vercel.app) |  | May 11, 2025 1:37am |
</details>



author_association: NONE
user: login: Shingo023
created_at: 2025-05-11T01:13:09Z
body: @mtkksk1780 

Thank you so much for reviewing my PR!
I shared my thoughts on the point you brought up—I'd love to hear your thoughts on it as well!
author_association: COLLABORATOR