fix: react-doctor a11y improvements (skeletons, icons, social links, toggles)
This commit is contained in:
@@ -398,7 +398,7 @@ export default function BillingClientPage({ overview }: Props) {
|
|||||||
<td key={tier} className="py-3 px-4 text-center">
|
<td key={tier} className="py-3 px-4 text-center">
|
||||||
{typeof t[tier] === "boolean" ? (
|
{typeof t[tier] === "boolean" ? (
|
||||||
t[tier] ? (
|
t[tier] ? (
|
||||||
<svg className="w-5 h-5 text-[var(--admin-success)] mx-auto" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
<svg aria-hidden="true" className="w-5 h-5 text-[var(--admin-success)] mx-auto" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" d="M4.5 12.75l6 6 9-13.5" />
|
<path strokeLinecap="round" strokeLinejoin="round" d="M4.5 12.75l6 6 9-13.5" />
|
||||||
</svg>
|
</svg>
|
||||||
) : (
|
) : (
|
||||||
@@ -420,7 +420,7 @@ export default function BillingClientPage({ overview }: Props) {
|
|||||||
<td key={tier} className="pt-4 px-4 text-center">
|
<td key={tier} className="pt-4 px-4 text-center">
|
||||||
{isCurrent ? (
|
{isCurrent ? (
|
||||||
<span className="inline-flex items-center gap-1.5 rounded-lg bg-[var(--admin-success)]/10 px-3 py-1.5 text-sm font-medium text-[var(--admin-success)]">
|
<span className="inline-flex items-center gap-1.5 rounded-lg bg-[var(--admin-success)]/10 px-3 py-1.5 text-sm font-medium text-[var(--admin-success)]">
|
||||||
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
<svg aria-hidden="true" className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth={2}>
|
||||||
<path strokeLinecap="round" strokeLinejoin="round" d="M4.5 12.75l6 6 9-13.5" />
|
<path strokeLinecap="round" strokeLinejoin="round" d="M4.5 12.75l6 6 9-13.5" />
|
||||||
</svg>
|
</svg>
|
||||||
Current
|
Current
|
||||||
|
|||||||
@@ -59,12 +59,12 @@ export default function MaintenancePage() {
|
|||||||
<div className="pt-6 border-t border-[#e5e5e5]">
|
<div className="pt-6 border-t border-[#e5e5e5]">
|
||||||
<p className="text-xs text-[#888] mb-4">Follow for updates:</p>
|
<p className="text-xs text-[#888] mb-4">Follow for updates:</p>
|
||||||
<div className="flex justify-center gap-4">
|
<div className="flex justify-center gap-4">
|
||||||
<a href="https://twitter.com" target="_blank" rel="noopener noreferrer" className="w-10 h-10 bg-white border border-[#e5e5e5] rounded-xl flex items-center justify-center text-[#1a1a1a] hover:border-[#1a4d2e] hover:text-[#1a4d2e] transition-colors">
|
<a href="https://twitter.com" aria-label="Follow us on Twitter" target="_blank" rel="noopener noreferrer" className="w-10 h-10 bg-white border border-[#e5e5e5] rounded-xl flex items-center justify-center text-[#1a1a1a] hover:border-[#1a4d2e] hover:text-[#1a4d2e] transition-colors">
|
||||||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
||||||
<path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/>
|
<path d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"/>
|
||||||
</svg>
|
</svg>
|
||||||
</a>
|
</a>
|
||||||
<a href="https://linkedin.com" target="_blank" rel="noopener noreferrer" className="w-10 h-10 bg-white border border-[#e5e5e5] rounded-xl flex items-center justify-center text-[#1a1a1a] hover:border-[#1a4d2e] hover:text-[#1a4d2e] transition-colors">
|
<a href="https://linkedin.com" aria-label="Follow us on LinkedIn" target="_blank" rel="noopener noreferrer" className="w-10 h-10 bg-white border border-[#e5e5e5] rounded-xl flex items-center justify-center text-[#1a1a1a] hover:border-[#1a4d2e] hover:text-[#1a4d2e] transition-colors">
|
||||||
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
<svg className="w-5 h-5" fill="currentColor" viewBox="0 0 24 24">
|
||||||
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>
|
<path d="M20.447 20.452h-3.554v-5.569c0-1.328-.027-3.037-1.852-3.037-1.853 0-2.136 1.445-2.136 2.939v5.667H9.351V9h3.414v1.561h.046c.477-.9 1.637-1.85 3.37-1.85 3.601 0 4.267 2.37 4.267 5.455v6.286zM5.337 7.433c-1.144 0-2.063-.926-2.063-2.065 0-1.138.92-2.063 2.063-2.063 1.14 0 2.064.925 2.064 2.063 0 1.139-.925 2.065-2.064 2.065zm1.782 13.019H3.555V9h3.564v11.452zM22.225 0H1.771C.792 0 0 .774 0 1.729v20.542C0 23.227.792 24 1.771 24h20.451C23.2 24 24 23.227 24 22.271V1.729C24 .774 23.2 0 22.222 0h.003z"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
@@ -712,6 +712,8 @@ function FeatureToggle({
|
|||||||
<div className="flex items-start gap-3">
|
<div className="flex items-start gap-3">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
|
aria-label={`Toggle ${label}`}
|
||||||
|
aria-pressed={checked}
|
||||||
onClick={() => onChange(!checked)}
|
onClick={() => onChange(!checked)}
|
||||||
className={`relative mt-0.5 inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full transition-colors ${
|
className={`relative mt-0.5 inline-flex h-5 w-9 shrink-0 cursor-pointer items-center rounded-full transition-colors ${
|
||||||
checked ? "bg-green-600" : "bg-zinc-600"
|
checked ? "bg-green-600" : "bg-zinc-600"
|
||||||
|
|||||||
@@ -289,6 +289,7 @@ export default function CampaignListPanel({ initialCampaigns, brandId = "6429430
|
|||||||
key={c.id}
|
key={c.id}
|
||||||
className="hover:bg-[var(--admin-card-hover)] cursor-pointer transition-colors"
|
className="hover:bg-[var(--admin-card-hover)] cursor-pointer transition-colors"
|
||||||
onClick={() => router.push(`/admin/communications/campaigns/${c.id}`)}
|
onClick={() => router.push(`/admin/communications/campaigns/${c.id}`)}
|
||||||
|
aria-label={`View campaign ${c.name}`}
|
||||||
>
|
>
|
||||||
<td className="px-3 sm:px-4 py-3 font-medium text-[var(--admin-text-primary)]">{c.name}</td>
|
<td className="px-3 sm:px-4 py-3 font-medium text-[var(--admin-text-primary)]">{c.name}</td>
|
||||||
<td className="px-3 sm:px-4 py-3">
|
<td className="px-3 sm:px-4 py-3">
|
||||||
|
|||||||
@@ -279,7 +279,7 @@ export default function ContactListPanel({
|
|||||||
<th className="text-left px-4 py-3 font-semibold text-stone-500 text-xs uppercase tracking-wider">Source</th>
|
<th className="text-left px-4 py-3 font-semibold text-stone-500 text-xs uppercase tracking-wider">Source</th>
|
||||||
<th className="text-left px-4 py-3 font-semibold text-stone-500 text-xs uppercase tracking-wider">Email Opt</th>
|
<th className="text-left px-4 py-3 font-semibold text-stone-500 text-xs uppercase tracking-wider">Email Opt</th>
|
||||||
<th className="text-left px-4 py-3 font-semibold text-stone-500 text-xs uppercase tracking-wider">Unsub</th>
|
<th className="text-left px-4 py-3 font-semibold text-stone-500 text-xs uppercase tracking-wider">Unsub</th>
|
||||||
<th className="text-right px-4 py-3"></th>
|
<th className="text-right px-4 py-3" aria-label="Actions"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="bg-white">
|
<tbody className="bg-white">
|
||||||
@@ -304,7 +304,7 @@ export default function ContactListPanel({
|
|||||||
<th className="text-left px-4 py-3.5 font-semibold text-stone-500 text-xs uppercase tracking-wider">Source</th>
|
<th className="text-left px-4 py-3.5 font-semibold text-stone-500 text-xs uppercase tracking-wider">Source</th>
|
||||||
<th className="text-left px-4 py-3.5 font-semibold text-stone-500 text-xs uppercase tracking-wider">Email Opt</th>
|
<th className="text-left px-4 py-3.5 font-semibold text-stone-500 text-xs uppercase tracking-wider">Email Opt</th>
|
||||||
<th className="text-left px-4 py-3.5 font-semibold text-stone-500 text-xs uppercase tracking-wider">Unsubscribed</th>
|
<th className="text-left px-4 py-3.5 font-semibold text-stone-500 text-xs uppercase tracking-wider">Unsubscribed</th>
|
||||||
<th className="text-right px-4 py-3.5"></th>
|
<th className="text-right px-4 py-3.5" aria-label="Actions"></th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody className="divide-y divide-[var(--admin-border)] bg-white">
|
<tbody className="divide-y divide-[var(--admin-border)] bg-white">
|
||||||
@@ -333,14 +333,14 @@ export default function ContactListPanel({
|
|||||||
<td className="px-4 py-3.5">
|
<td className="px-4 py-3.5">
|
||||||
{c.email_opt_in ? (
|
{c.email_opt_in ? (
|
||||||
<span className="inline-flex items-center gap-1 text-emerald-600 text-xs font-semibold">
|
<span className="inline-flex items-center gap-1 text-emerald-600 text-xs font-semibold">
|
||||||
<svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="2">
|
<svg aria-hidden="true" className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="2">
|
||||||
<polyline points="20 6 9 17 4 12"/>
|
<polyline points="20 6 9 17 4 12"/>
|
||||||
</svg>
|
</svg>
|
||||||
Opted in
|
Opted in
|
||||||
</span>
|
</span>
|
||||||
) : (
|
) : (
|
||||||
<span className="inline-flex items-center gap-1 text-red-500 text-xs font-semibold">
|
<span className="inline-flex items-center gap-1 text-red-500 text-xs font-semibold">
|
||||||
<svg className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="2">
|
<svg aria-hidden="true" className="w-3.5 h-3.5" fill="none" viewBox="0 0 24 24" stroke="currentColor" strokeWidth="2">
|
||||||
<line x1="18" y1="6" x2="6" y2="18"/>
|
<line x1="18" y1="6" x2="6" y2="18"/>
|
||||||
<line x1="6" y1="6" x2="18" y2="18"/>
|
<line x1="6" y1="6" x2="18" y2="18"/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|||||||
@@ -732,7 +732,7 @@ export default function WaterAdminClient() {
|
|||||||
<tbody>
|
<tbody>
|
||||||
{initialLoading ? (
|
{initialLoading ? (
|
||||||
Array.from({ length: 8 }).map((_, i) => (
|
Array.from({ length: 8 }).map((_, i) => (
|
||||||
<tr key={i}>
|
<tr key={i} aria-hidden="true">
|
||||||
<td className="py-3"><div className="h-3 w-20 bg-stone-100 rounded animate-pulse" /></td>
|
<td className="py-3"><div className="h-3 w-20 bg-stone-100 rounded animate-pulse" /></td>
|
||||||
<td className="py-3"><div className="h-3 w-16 bg-stone-100 rounded animate-pulse hidden sm:table-cell" /></td>
|
<td className="py-3"><div className="h-3 w-16 bg-stone-100 rounded animate-pulse hidden sm:table-cell" /></td>
|
||||||
<td className="py-3"><div className="h-3 w-14 bg-stone-100 rounded animate-pulse" /></td>
|
<td className="py-3"><div className="h-3 w-14 bg-stone-100 rounded animate-pulse" /></td>
|
||||||
|
|||||||
Reference in New Issue
Block a user