docs: add ACCESSIBILITY_AUDIT, SECURITY_PRIVACY_AUDIT, PRODUCT_BRIEF with file-specific actions; a11y: add skip link, lang+hreflang, ARIA for menu/carousel/dialog/form; noValidate+honeypot

This commit is contained in:
2025-08-08 23:00:09 +02:00
parent 910253c8f4
commit 3c74d71e22
16 changed files with 501 additions and 43 deletions

View File

@@ -11,6 +11,7 @@ export default function ContactForm() {
const [errors, setErrors] = useState({});
const [isSubmitting, setIsSubmitting] = useState(false);
const [submitMessage, setSubmitMessage] = useState(null);
const [hp, setHp] = useState('');
const validate = () => {
let newErrors = {};
@@ -61,7 +62,11 @@ export default function ContactForm() {
};
return (
<form onSubmit={handleSubmit} className="bg-white p-8 rounded-xl shadow-lg border border-gray-200 max-w-2xl mx-auto">
<form onSubmit={handleSubmit} className="bg-white p-8 rounded-xl shadow-lg border border-gray-200 max-w-2xl mx-auto" noValidate>
<div className="hidden" aria-hidden="true">
<label htmlFor="website">Website</label>
<input id="website" name="website" value={hp} onChange={(e)=>setHp(e.target.value)} tabIndex={-1} autoComplete="off" />
</div>
<h2 className="text-3xl font-bold text-center text-nigerian-green-700 mb-8">Send Us a Message</h2>
{submitMessage && (
@@ -78,10 +83,12 @@ export default function ContactForm() {
name="name"
value={formData.name}
onChange={handleChange}
aria-invalid={Boolean(errors.name)}
aria-describedby={errors.name ? 'name-error' : undefined}
className={`shadow appearance-none border rounded-lg w-full py-3 px-4 text-gray-700 leading-tight focus:outline-none focus:ring-2 focus:ring-nigerian-green-500 ${errors.name ? 'border-red-500' : 'border-gray-300'}`}
placeholder="Your Name"
/>
{errors.name && <p className="text-red-500 text-xs italic mt-2">{errors.name}</p>}
{errors.name && <p id="name-error" className="text-red-500 text-xs italic mt-2">{errors.name}</p>}
</div>
<div className="mb-5">