Audit and fix accessibility issues across the portfolio to ensure WCAG 2.1 AA compliance.
The English summary is being prepared. Showing the original description.
Create new React components, API routes, SWR hooks, and context providers following repo patterns.
The English summary is being prepared. Showing the original description.
See how to installReview the instructions the agent will receive before you install.
Location: src/components/ui/
'use client';
import { useState } from 'react';
interface MyComponentProps {
title: string;
onAction: () => void;
}
export function MyComponent({ title, onAction }: Readonly<MyComponentProps>) {
const [state, setState] = useState('');
return (
<div className="rounded-xl border border-border-light dark:border-border-dark bg-white dark:bg-card-bg-dark p-5">
<h3 className="text-sm font-semibold text-text-primary-light dark:text-text-primary-dark">
{title}
</h3>
<button
type="button"
onClick={onAction}
className="mt-3 inline-flex items-center gap-2 rounded-lg bg-accent-pink px-4 py-2 text-sm font-medium text-white hover:bg-accent-pink-hover dark:hover:bg-accent-pink-hover-dark transition-colors"
>
Action
</button>
</div>
);
}
Component conventions:
PascalCase.tsx (e.g., MyComponent.tsx)export function MyComponent)interface with Readonly<> wrapper-light / -dark suffix pairsaria-label, role, semantic HTML'use client' at topLocation: src/components/sections/
'use client';
import { useCmsContent } from '@/hooks/useCmsContent';
export function MySection() {
const { profile } = useCmsContent();
return (
<section className="py-16 sm:py-20" id="my-section">
<div className="mx-auto max-w-6xl px-4 sm:px-6">
<h2 className="text-2xl font-bold text-text-primary-light dark:text-text-primary-dark">
Section Title
</h2>
{/* Content */}
</div>
</section>
);
}
Section conventions:
src/components/sections/id for navigationmax-w-6xl mx-auto px-4 sm:px-6 containerpy-16 sm:py-20useCmsContent() hookLocation: src/app/api/<route>/route.ts
import { NextRequest, NextResponse } from 'next/server';
export async function GET(request: NextRequest) {
try {
// Logic here
return NextResponse.json({ data: result });
} catch (error) {
console.error('[API Error]', error);
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}
export async function POST(request: NextRequest) {
try {
const body = await request.json();
// Validate body
// Process
return NextResponse.json({ success: true }, { status: 201 });
} catch (error) {
console.error('[API Error]', error);
return NextResponse.json(
{ error: 'Internal server error' },
{ status: 500 }
);
}
}
API route conventions:
route.ts (not page.ts)GET, POST, PUT, DELETE)[API Name] for easy filteringNextResponse.json()Location: src/hooks/
import useSWR from 'swr';
const fetcher = (url: string) => fetch(url).then((res) => res.json());
export function useMyData() {
const { data, error, isLoading } = useSWR('/api/my-data', fetcher, {
revalidateOnFocus: true,
revalidateOnReconnect: true,
dedupingInterval: 60000,
});
return {
data: data ?? null,
error: error ?? null,
isLoading,
};
}
SWR conventions:
use<Name>.ts (e.g., useProjects.ts)?? null)dedupingInterval to prevent excessive requestsSWRConfig in tests for isolationLocation: src/hooks/ (for small state) or src/contexts/ (for complex state)
'use client';
import { createContext, useCallback, useContext, useMemo, useState } from 'react';
type MyContextValue = {
value: string;
setValue: (v: string) => void;
};
const MyContext = createContext<MyContextValue | null>(null);
export function MyProvider({ children }: { children: React.ReactNode }) {
const [value, setValue] = useState('');
const contextValue = useMemo(() => ({ value, setValue }), [value]);
return (
<MyContext.Provider value={contextValue}>
{children}
</MyContext.Provider>
);
}
export function useMyContext() {
const context = useContext(MyContext);
if (!context) throw new Error('useMyContext must be used within MyProvider');
return context;
}
Location: src/components/ui/
Modals use the base <Modal> component:
'use client';
import { Modal } from './Modal';
interface MyModalProps {
open: boolean;
onClose: () => void;
}
export function MyModal({ open, onClose }: Readonly<MyModalProps>) {
return (
<Modal open={open} onClose={onClose} title="My Modal">
<div className="px-5 py-6">
{/* Modal content */}
</div>
</Modal>
);
}
Modal conventions:
src/hooks/useModal.tsx (add to ModalName type)ModalProvider componentfullScreen prop for content-heavy modalstitle for accessibilityLocation: src/app/<route>/page.tsx
import type { Metadata } from 'next';
export const metadata: Metadata = {
title: 'Page Title | PP Namias',
description: 'Page description',
};
export default function MyPage() {
return (
<main>
{/* Page content */}
</main>
);
}
Page conventions:
metadata for SEO<main> as root element'use client' or use dynamic importsrc/
components/
ui/ # Reusable UI components (Button, Modal, Card)
sections/ # Page sections (Hero, Projects, Contact)
layout/ # Layout components (Header, Footer, Navigation)
hooks/ # Custom React hooks
contexts/ # React context providers
lib/ # Utilities, constants, helpers
app/ # Next.js App Router pages and API routes
__tests__/ # Test files (mirrors src/ structure)
| Type | Convention | Example |
|---|---|---|
| Component file | PascalCase | ContactModal.tsx |
| Hook file | camelCase, use prefix | useCmsContent.ts |
| Utility file | camelCase | buildEmailLinks.ts |
| Constant file | camelCase | constants.ts |
| Type file | camelCase | types.ts |
| Test file | *.test.tsx | ContactModal.test.tsx |
| API route | route.ts | src/app/api/chat/route.ts |
'use client' on components that use hooks<div onClick> instead of <button onClick> (accessibility)Readonly<>useModal.tsxnpx tsc --noEmit)npm run lint)No reviews yet. Tell others what you thought.
No login needed. Share how it worked for you, ask a question, or note where it did not run.
No comments yet. Be the first to write one.
Audit and fix accessibility issues across the portfolio to ensure WCAG 2.1 AA compliance.
The English summary is being prepared. Showing the original description.
Creates a new blog post document in the Sanity studio. Use when the user wants to write a blog post, publish an article, or schedule a future post.
The English summary is being prepared. Showing the original description.
Creates a new certification document in the Sanity studio. Use when the user wants to add a credential, certificate, or professional accreditation to the Certifications collection.
The English summary is being prepared. Showing the original description.
Adds a new skill MD file to the studio's skills collection. Use when the user wants to author a new step-by-step recipe for the studio's in-app Skills tool or the .agents mirror.
The English summary is being prepared. Showing the original description.
Creates a new project document in the Sanity studio. Use when the user wants to add a new portfolio project, a case study, or a work sample to the Projects collection.
The English summary is being prepared. Showing the original description.
Creates a new experience document in the Sanity studio. Use when the user wants to add a job, role, internship, or work history entry to the Experience collection.
The English summary is being prepared. Showing the original description.