fix(frontend): use useId() for input IDs

This commit is contained in:
tigattack
2025-09-24 22:54:28 +01:00
parent a11f180d23
commit 15902da87c
4 changed files with 61 additions and 37 deletions

View File

@@ -14,6 +14,12 @@ import { useAuth } from "../contexts/AuthContext";
import { authAPI } from "../utils/api";
const Login = () => {
const usernameId = useId();
const firstNameId = useId();
const lastNameId = useId();
const emailId = useId();
const passwordId = useId();
const tokenId = useId();
const [isSignupMode, setIsSignupMode] = useState(false);
const [formData, setFormData] = useState({
username: "",
@@ -212,14 +218,14 @@ const Login = () => {
<div className="space-y-4">
<div>
<label
htmlFor="username"
htmlFor={usernameId}
className="block text-sm font-medium text-secondary-700"
>
{isSignupMode ? "Username" : "Username or Email"}
</label>
<div className="mt-1 relative">
<input
id="username"
id={usernameId}
name="username"
type="text"
required
@@ -243,7 +249,7 @@ const Login = () => {
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
<div>
<label
htmlFor="firstName"
htmlFor={firstNameId}
className="block text-sm font-medium text-secondary-700"
>
First Name
@@ -253,7 +259,7 @@ const Login = () => {
<User className="h-5 w-5 text-secondary-400" />
</div>
<input
id="firstName"
id={firstNameId}
name="firstName"
type="text"
required
@@ -266,7 +272,7 @@ const Login = () => {
</div>
<div>
<label
htmlFor="lastName"
htmlFor={lastNameId}
className="block text-sm font-medium text-secondary-700"
>
Last Name
@@ -276,7 +282,7 @@ const Login = () => {
<User className="h-5 w-5 text-secondary-400" />
</div>
<input
id="lastName"
id={lastNameId}
name="lastName"
type="text"
required
@@ -290,14 +296,14 @@ const Login = () => {
</div>
<div>
<label
htmlFor="email"
htmlFor={emailId}
className="block text-sm font-medium text-secondary-700"
>
Email
</label>
<div className="mt-1 relative">
<input
id="email"
id={emailId}
name="email"
type="email"
required
@@ -316,14 +322,14 @@ const Login = () => {
<div>
<label
htmlFor="password"
htmlFor={passwordId}
className="block text-sm font-medium text-secondary-700"
>
Password
</label>
<div className="mt-1 relative">
<input
id="password"
id={passwordId}
name="password"
type={showPassword ? "text" : "password"}
required
@@ -415,14 +421,14 @@ const Login = () => {
<div>
<label
htmlFor="token"
htmlFor={tokenId}
className="block text-sm font-medium text-secondary-700"
>
Verification Code
</label>
<div className="mt-1">
<input
id="token"
id={tokenId}
name="token"
type="text"
required

View File

@@ -25,6 +25,13 @@ import { useTheme } from "../contexts/ThemeContext";
import { tfaAPI } from "../utils/api";
const Profile = () => {
const usernameId = useId();
const emailId = useId();
const firstNameId = useId();
const lastNameId = useId();
const currentPasswordId = useId();
const newPasswordId = useId();
const confirmPasswordId = useId();
const { user, updateProfile, changePassword } = useAuth();
const { theme, toggleTheme, isDark } = useTheme();
const [activeTab, setActiveTab] = useState("profile");
@@ -250,7 +257,7 @@ const Profile = () => {
<div className="grid grid-cols-1 gap-6 sm:grid-cols-2">
<div>
<label
htmlFor="username"
htmlFor={usernameId}
className="block text-sm font-medium text-secondary-700 dark:text-secondary-200"
>
Username
@@ -259,7 +266,7 @@ const Profile = () => {
<input
type="text"
name="username"
id="username"
id={usernameId}
value={profileData.username}
onChange={handleInputChange}
className="block w-full border-secondary-300 dark:border-secondary-600 rounded-md shadow-sm focus:ring-primary-500 focus:border-primary-500 pl-10 bg-white dark:bg-secondary-700 text-secondary-900 dark:text-white"
@@ -271,7 +278,7 @@ const Profile = () => {
<div>
<label
htmlFor="email"
htmlFor={emailId}
className="block text-sm font-medium text-secondary-700 dark:text-secondary-200"
>
Email Address
@@ -280,7 +287,7 @@ const Profile = () => {
<input
type="email"
name="email"
id="email"
id={emailId}
value={profileData.email}
onChange={handleInputChange}
className="block w-full border-secondary-300 dark:border-secondary-600 rounded-md shadow-sm focus:ring-primary-500 focus:border-primary-500 pl-10 bg-white dark:bg-secondary-700 text-secondary-900 dark:text-white"
@@ -292,7 +299,7 @@ const Profile = () => {
<div>
<label
htmlFor="first_name"
htmlFor={firstNameId}
className="block text-sm font-medium text-secondary-700 dark:text-secondary-200"
>
First Name
@@ -301,7 +308,7 @@ const Profile = () => {
<input
type="text"
name="first_name"
id="first_name"
id={firstNameId}
value={profileData.first_name}
onChange={handleInputChange}
className="block w-full border-secondary-300 dark:border-secondary-600 rounded-md shadow-sm focus:ring-primary-500 focus:border-primary-500 bg-white dark:bg-secondary-700 text-secondary-900 dark:text-white"
@@ -311,7 +318,7 @@ const Profile = () => {
<div>
<label
htmlFor="last_name"
htmlFor={lastNameId}
className="block text-sm font-medium text-secondary-700 dark:text-secondary-200"
>
Last Name
@@ -320,7 +327,7 @@ const Profile = () => {
<input
type="text"
name="last_name"
id="last_name"
id={lastNameId}
value={profileData.last_name}
onChange={handleInputChange}
className="block w-full border-secondary-300 dark:border-secondary-600 rounded-md shadow-sm focus:ring-primary-500 focus:border-primary-500 bg-white dark:bg-secondary-700 text-secondary-900 dark:text-white"
@@ -353,7 +360,7 @@ const Profile = () => {
<div className="space-y-4">
<div>
<label
htmlFor="currentPassword"
htmlFor={currentPasswordId}
className="block text-sm font-medium text-secondary-700 dark:text-secondary-200"
>
Current Password
@@ -362,7 +369,7 @@ const Profile = () => {
<input
type={showPasswords.current ? "text" : "password"}
name="currentPassword"
id="currentPassword"
id={currentPasswordId}
value={passwordData.currentPassword}
onChange={handleInputChange}
className="block w-full border-secondary-300 dark:border-secondary-600 rounded-md shadow-sm focus:ring-primary-500 focus:border-primary-500 pl-10 pr-10 bg-white dark:bg-secondary-700 text-secondary-900 dark:text-white"
@@ -385,7 +392,7 @@ const Profile = () => {
<div>
<label
htmlFor="newPassword"
htmlFor={newPasswordId}
className="block text-sm font-medium text-secondary-700 dark:text-secondary-200"
>
New Password
@@ -394,7 +401,7 @@ const Profile = () => {
<input
type={showPasswords.new ? "text" : "password"}
name="newPassword"
id="newPassword"
id={newPasswordId}
value={passwordData.newPassword}
onChange={handleInputChange}
className="block w-full border-secondary-300 dark:border-secondary-600 rounded-md shadow-sm focus:ring-primary-500 focus:border-primary-500 pl-10 pr-10 bg-white dark:bg-secondary-700 text-secondary-900 dark:text-white"
@@ -421,7 +428,7 @@ const Profile = () => {
<div>
<label
htmlFor="confirmPassword"
htmlFor={confirmPasswordId}
className="block text-sm font-medium text-secondary-700 dark:text-secondary-200"
>
Confirm New Password
@@ -430,7 +437,7 @@ const Profile = () => {
<input
type={showPasswords.confirm ? "text" : "password"}
name="confirmPassword"
id="confirmPassword"
id={confirmPasswordId}
value={passwordData.confirmPassword}
onChange={handleInputChange}
className="block w-full border-secondary-300 dark:border-secondary-600 rounded-md shadow-sm focus:ring-primary-500 focus:border-primary-500 pl-10 pr-10 bg-white dark:bg-secondary-700 text-secondary-900 dark:text-white"
@@ -986,7 +993,11 @@ const TfaTab = () => {
</div>
</div>
<div className="flex space-x-3">
<button type="button" onClick={downloadBackupCodes} className="btn-outline">
<button
type="button"
onClick={downloadBackupCodes}
className="btn-outline"
>
<Download className="h-4 w-4 mr-2" />
Download Codes
</button>

View File

@@ -18,6 +18,7 @@ import { Link, useParams } from "react-router-dom";
import { repositoryAPI } from "../utils/api";
const RepositoryDetail = () => {
const isActiveId = useId();
const { repositoryId } = useParams();
const queryClient = useQueryClient();
const [editMode, setEditMode] = useState(false);
@@ -241,7 +242,7 @@ const RepositoryDetail = () => {
<div className="flex items-center">
<input
type="checkbox"
id="is_active"
id={isActiveId}
checked={formData.is_active}
onChange={(e) =>
setFormData({ ...formData, is_active: e.target.checked })
@@ -249,7 +250,7 @@ const RepositoryDetail = () => {
className="h-4 w-4 text-primary-600 focus:ring-primary-500 border-secondary-300 rounded"
/>
<label
htmlFor="is_active"
htmlFor={isActiveId}
className="ml-2 block text-sm text-secondary-900 dark:text-white"
>
Repository is active

View File

@@ -1,4 +1,5 @@
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
import {
AlertCircle,
CheckCircle,
@@ -14,6 +15,7 @@ import {
Trash2,
X,
} from "lucide-react";
import React, { useEffect, useState } from "react";
import UpgradeNotificationIcon from "../components/UpgradeNotificationIcon";
import { useUpdateNotification } from "../contexts/UpdateNotificationContext";
@@ -25,6 +27,10 @@ import {
} from "../utils/api";
const Settings = () => {
const repoPublicId = useId();
const repoPrivateId = useId();
const useCustomSshKeyId = useId();
const isDefaultId = useId();
const [formData, setFormData] = useState({
serverProtocol: "http",
serverHost: "localhost",
@@ -992,7 +998,7 @@ const Settings = () => {
<div className="flex items-center">
<input
type="radio"
id="repo-public"
id={repoPublicId}
name="repositoryType"
value="public"
checked={formData.repositoryType === "public"}
@@ -1002,7 +1008,7 @@ const Settings = () => {
className="h-4 w-4 text-primary-600 focus:ring-primary-500 border-gray-300"
/>
<label
htmlFor="repo-public"
htmlFor={repoPublicId}
className="ml-2 text-sm text-secondary-700 dark:text-secondary-200"
>
Public Repository (uses GitHub API - no authentication
@@ -1012,7 +1018,7 @@ const Settings = () => {
<div className="flex items-center">
<input
type="radio"
id="repo-private"
id={repoPrivateId}
name="repositoryType"
value="private"
checked={formData.repositoryType === "private"}
@@ -1022,7 +1028,7 @@ const Settings = () => {
className="h-4 w-4 text-primary-600 focus:ring-primary-500 border-gray-300"
/>
<label
htmlFor="repo-private"
htmlFor={repoPrivateId}
className="ml-2 text-sm text-secondary-700 dark:text-secondary-200"
>
Private Repository (uses SSH with deploy key)
@@ -1058,7 +1064,7 @@ const Settings = () => {
<div className="flex items-center gap-3 mb-3">
<input
type="checkbox"
id="useCustomSshKey"
id={useCustomSshKeyId}
checked={formData.useCustomSshKey}
onChange={(e) => {
const checked = e.target.checked;
@@ -1070,7 +1076,7 @@ const Settings = () => {
className="h-4 w-4 text-primary-600 focus:ring-primary-500 border-gray-300 rounded"
/>
<label
htmlFor="useCustomSshKey"
htmlFor={useCustomSshKeyId}
className="text-sm font-medium text-secondary-700 dark:text-secondary-200"
>
Set custom SSH key path
@@ -1458,7 +1464,7 @@ const AgentVersionModal = ({ isOpen, onClose, onSubmit, isLoading }) => {
<div className="flex items-center">
<input
type="checkbox"
id="isDefault"
id={isDefaultId}
checked={formData.isDefault}
onChange={(e) =>
setFormData((prev) => ({
@@ -1469,7 +1475,7 @@ const AgentVersionModal = ({ isOpen, onClose, onSubmit, isLoading }) => {
className="h-4 w-4 text-primary-600 focus:ring-primary-500 border-secondary-300 dark:border-secondary-600 rounded"
/>
<label
htmlFor="isDefault"
htmlFor={isDefaultId}
className="ml-2 block text-sm text-secondary-700 dark:text-secondary-200"
>
Set as default version for new installations