Add frontend input validation for User username and Product name
This commit is contained in:
parent
9de4f0b64c
commit
9956c22cce
2 changed files with 99 additions and 10 deletions
|
@ -40,6 +40,10 @@ export default function ProductsPage() {
|
|||
name: '',
|
||||
description: '',
|
||||
});
|
||||
const [errors, setErrors] = useState({
|
||||
name: '',
|
||||
description: '',
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
loadProducts();
|
||||
|
@ -54,8 +58,29 @@ export default function ProductsPage() {
|
|||
}
|
||||
};
|
||||
|
||||
const validateForm = () => {
|
||||
const newErrors = {
|
||||
name: '',
|
||||
description: '',
|
||||
};
|
||||
|
||||
// Product name cannot be empty
|
||||
if (!formData.name.trim()) {
|
||||
newErrors.name = 'Product name is required';
|
||||
}
|
||||
|
||||
// Description can be empty, no validation needed
|
||||
setErrors(newErrors);
|
||||
return !newErrors.name;
|
||||
};
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!validateForm()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (editingProduct) {
|
||||
await productApi.update(editingProduct.id, formData);
|
||||
|
@ -65,6 +90,7 @@ export default function ProductsPage() {
|
|||
setIsDialogOpen(false);
|
||||
setEditingProduct(null);
|
||||
setFormData({ name: '', description: '' });
|
||||
setErrors({ name: '', description: '' });
|
||||
loadProducts();
|
||||
} catch (error) {
|
||||
console.error('Error saving product:', error);
|
||||
|
@ -77,6 +103,7 @@ export default function ProductsPage() {
|
|||
name: product.name,
|
||||
description: product.description,
|
||||
});
|
||||
setErrors({ name: '', description: '' });
|
||||
setIsDialogOpen(true);
|
||||
};
|
||||
|
||||
|
@ -91,6 +118,14 @@ export default function ProductsPage() {
|
|||
}
|
||||
};
|
||||
|
||||
const handleInputChange = (field: 'name' | 'description', value: string) => {
|
||||
setFormData({ ...formData, [field]: value });
|
||||
// Clear error when user starts typing
|
||||
if (errors[field]) {
|
||||
setErrors({ ...errors, [field]: '' });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between items-center">
|
||||
|
@ -100,6 +135,7 @@ export default function ProductsPage() {
|
|||
<Button onClick={() => {
|
||||
setEditingProduct(null);
|
||||
setFormData({ name: '', description: '' });
|
||||
setErrors({ name: '', description: '' });
|
||||
}}>
|
||||
Add Product
|
||||
</Button>
|
||||
|
@ -110,21 +146,23 @@ export default function ProductsPage() {
|
|||
</DialogHeader>
|
||||
<form onSubmit={handleSubmit} className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="name">Name</Label>
|
||||
<Label htmlFor="name">Name *</Label>
|
||||
<Input
|
||||
id="name"
|
||||
value={formData.name}
|
||||
onChange={(e) => setFormData({ ...formData, name: e.target.value })}
|
||||
required
|
||||
onChange={(e) => handleInputChange('name', e.target.value)}
|
||||
className={errors.name ? 'border-red-500' : ''}
|
||||
/>
|
||||
{errors.name && (
|
||||
<p className="text-red-500 text-sm">{errors.name}</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="description">Description</Label>
|
||||
<Input
|
||||
id="description"
|
||||
value={formData.description}
|
||||
onChange={(e) => setFormData({ ...formData, description: e.target.value })}
|
||||
required
|
||||
onChange={(e) => handleInputChange('description', e.target.value)}
|
||||
/>
|
||||
</div>
|
||||
<Button type="submit">{editingProduct ? 'Update' : 'Create'}</Button>
|
||||
|
|
|
@ -40,6 +40,10 @@ export default function UsersPage() {
|
|||
username: '',
|
||||
email: '',
|
||||
});
|
||||
const [errors, setErrors] = useState({
|
||||
username: '',
|
||||
email: '',
|
||||
});
|
||||
|
||||
useEffect(() => {
|
||||
loadUsers();
|
||||
|
@ -54,8 +58,38 @@ export default function UsersPage() {
|
|||
}
|
||||
};
|
||||
|
||||
const validateForm = () => {
|
||||
const newErrors = {
|
||||
username: '',
|
||||
email: '',
|
||||
};
|
||||
|
||||
// Username cannot be empty
|
||||
if (!formData.username.trim()) {
|
||||
newErrors.username = 'Username is required';
|
||||
}
|
||||
|
||||
// Email can be empty, but if provided, should be valid
|
||||
if (formData.email.trim() && !isValidEmail(formData.email)) {
|
||||
newErrors.email = 'Please enter a valid email address';
|
||||
}
|
||||
|
||||
setErrors(newErrors);
|
||||
return !newErrors.username && !newErrors.email;
|
||||
};
|
||||
|
||||
const isValidEmail = (email: string) => {
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
return emailRegex.test(email);
|
||||
};
|
||||
|
||||
const handleSubmit = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!validateForm()) {
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
if (editingUser) {
|
||||
await userApi.update(editingUser.id, formData);
|
||||
|
@ -65,6 +99,7 @@ export default function UsersPage() {
|
|||
setIsDialogOpen(false);
|
||||
setEditingUser(null);
|
||||
setFormData({ username: '', email: '' });
|
||||
setErrors({ username: '', email: '' });
|
||||
loadUsers();
|
||||
} catch (error) {
|
||||
console.error('Error saving user:', error);
|
||||
|
@ -74,6 +109,7 @@ export default function UsersPage() {
|
|||
const handleEdit = (user: User) => {
|
||||
setEditingUser(user);
|
||||
setFormData({ username: user.username, email: user.email });
|
||||
setErrors({ username: '', email: '' });
|
||||
setIsDialogOpen(true);
|
||||
};
|
||||
|
||||
|
@ -88,6 +124,14 @@ export default function UsersPage() {
|
|||
}
|
||||
};
|
||||
|
||||
const handleInputChange = (field: 'username' | 'email', value: string) => {
|
||||
setFormData({ ...formData, [field]: value });
|
||||
// Clear error when user starts typing
|
||||
if (errors[field]) {
|
||||
setErrors({ ...errors, [field]: '' });
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="space-y-4">
|
||||
<div className="flex justify-between items-center">
|
||||
|
@ -97,6 +141,7 @@ export default function UsersPage() {
|
|||
<Button onClick={() => {
|
||||
setEditingUser(null);
|
||||
setFormData({ username: '', email: '' });
|
||||
setErrors({ username: '', email: '' });
|
||||
}}>
|
||||
Add User
|
||||
</Button>
|
||||
|
@ -107,13 +152,16 @@ export default function UsersPage() {
|
|||
</DialogHeader>
|
||||
<form onSubmit={handleSubmit} className="space-y-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="username">Username</Label>
|
||||
<Label htmlFor="username">Username *</Label>
|
||||
<Input
|
||||
id="username"
|
||||
value={formData.username}
|
||||
onChange={(e) => setFormData({ ...formData, username: e.target.value })}
|
||||
required
|
||||
onChange={(e) => handleInputChange('username', e.target.value)}
|
||||
className={errors.username ? 'border-red-500' : ''}
|
||||
/>
|
||||
{errors.username && (
|
||||
<p className="text-red-500 text-sm">{errors.username}</p>
|
||||
)}
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="email">Email</Label>
|
||||
|
@ -121,9 +169,12 @@ export default function UsersPage() {
|
|||
id="email"
|
||||
type="email"
|
||||
value={formData.email}
|
||||
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
|
||||
required
|
||||
onChange={(e) => handleInputChange('email', e.target.value)}
|
||||
className={errors.email ? 'border-red-500' : ''}
|
||||
/>
|
||||
{errors.email && (
|
||||
<p className="text-red-500 text-sm">{errors.email}</p>
|
||||
)}
|
||||
</div>
|
||||
<Button type="submit">{editingUser ? 'Update' : 'Create'}</Button>
|
||||
</form>
|
||||
|
|
Loading…
Add table
Reference in a new issue