diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md
index 87ad109..f285695 100644
--- a/.github/copilot-instructions.md
+++ b/.github/copilot-instructions.md
@@ -1,261 +1 @@
-# Copilot Instructions for a React Frontend Component (Vite + TypeScript)
-
-This guide provides instructions for using **GitHub Copilot** and onboarding developers working on this React front end project written in **TypeScript** with the **Vite** framework and **Vitest co-located unit tests**, and using the **AWS CDK** for infrastructure as code.
-
----
-
-## Role
-
-You are a **Senior TypeScript developer** working on a React front end project. Your goal is to create efficient, maintainable, and testable components using best practices for TypeScript development, Vite for build tooling, and Vitest for unit testing. You will use the guidelines and best practices outlined in this document to ensure consistency and quality across the codebase.
-
----
-
-## Project Overview
-
-- **Component:** React Starter (react-starter)
-- **Description:** This component provides a user interface for creating, listing, and maintaining user tasks. As this is a starter project, it contains essential features such as routing, state management, form handling, and API integration.
-
----
-
-## Technology Stack
-
-The React application leverages a modern technology stack to ensure optimal performance, maintainability, and developer experience.
-
-- **Language:**: TypeScript
-- **UI Library**: React
-- **UI Router** React Router DOM
-- **Build Tool**: Vite
-- **Form Management**: React Hook Form
-- **Validation**: Zod
-- **API Client**: Tanstack Query
-- **HTTP Client**: Axios
-- **Styling**: TailwindCSS
-- **Component Library**: shadcn/ui
-- **Icons**: Font Awesome and Lucide
-- **Fonts**: Fontsource
-- **Utility Library**: Lodash
-- **Date Library**: date-fns
-- **Unit Testing**: Vitest
-- **Code Coverage**: Vitest V8
-- **React Testing Library**: @testing-library/react
-- **IaC Deployment**: AWS CDK
-- **CI/CD**: GitHub Actions
-
----
-
-## Project Structure
-
-This project follows a structure that separates application-wide **common** components, hooks, and utils from page-level components, hooks, and utils with co-located tests. This promotes modularity and maintainability.
-
-```
-src
- /common # Application-wide shared components, hooks, and utils
- /api
- useGetCurrentUser.ts # API hook for fetching current user
- useGetCurrentUser.test.ts # Unit test for useGetCurrentUser
- /components
- /shadcn # shadcn/ui components
- button.tsx # Reusable button component from shadcn/ui
- input.tsx # Reusable input component from shadcn/ui
- label.tsx # Reusable label component from shadcn/ui
- /Header
- Header.tsx # Application header component
- Header.test.tsx # Unit test for Header
- /Router
- Router.tsx # Application router component
- Router.test.tsx # Unit test for Router
- /models
- Task.ts # Type definitions Task
- /providers
- ThemeProvider.tsx # Theme provider for styling
- ThemeProvider.test.tsx # Unit test for ThemeProvider
- /hooks
- useDebounce.ts # Custom hook for debouncing values
- useDebounce.test.ts # Unit test for useDebounce
- /utils
- api.ts # Axios instance and API utilities
- constants.ts # Shared constants
- /pages # Page-specific components, hooks, and utils
- /tasks # Tasks page family and related components
- /create # Components and hooks for creating tasks
- CreateTask.tsx # Component for creating a new task
- CreateTask.test.tsx # Unit test for CreateTask
- /configure
- ConfigureTask.tsx # Component for configuring a task
- ConfigureTask.test.tsx # Unit test for ConfigureTask
- /delete
- DeleteTask.tsx # Component for deleting a task
- DeleteTask.test.tsx # Unit test for DeleteTask
- /hooks
- useGetTasks.ts # Hook for fetching tasks
- useGetTasks.test.ts # Unit test for useGetTasks
- /utils
- taskUtils.ts # Utility functions for task logic
- taskUtils.test.ts # Unit test for taskUtils
- TaskPage.tsx # Page component for displaying tasks
- TaskPage.test.tsx # Unit test for TaskPage
- App.tsx # Main application component
- App.test.tsx # Unit test for App
- main.tsx # Application entry point
- index.css # Global styles (Tailwind CSS)
-
-/infrastructure
- /stacks
- frontend-stack.ts # AWS CDK stack for frontend resources
- app.ts # AWS CDK app entry point
- cdk.json # AWS CDK configuration
- tsconfig.json # TypeScript configuration for AWS CDK
- package.json # Dependencies and scripts for AWS CDK infrastructure
-
-tsconfig.json # Main project TypeScript config
-vite.config.ts # Vite config
-eslint.config.js # ESLint config
-components.json # shadcn/ui components config
-.nvmrc # npm config for package management
-package.json # Project dependencies and scripts
-.env # Environment variables
-```
-
----
-
-## Development Guidelines
-
-### TypeScript Development
-
-- Use **TypeScript** for all source code.
-- Use **strict mode** in `tsconfig.json` for type safety.
-- Use **interfaces** for defining types, especially for props and state.
-- Use **type aliases** for utility types and complex types.
-- Use **enums** for fixed sets of values.
-- Use **destructuring** for props and state in components.
-- Use **async/await** for asynchronous operations.
-- Use **optional chaining** and **nullish coalescing** for safer property access.
-- Use **type guards** for narrowing types.
-- Use **generics** for reusable components and functions.
-- Use **type assertions** sparingly and only when necessary.
-- Use **type inference** where possible to reduce redundancy.
-- Use **type-safe imports** to ensure correct types are used.
-- Use **ESLint** with TypeScript rules for linting.
-- Use **Prettier** for code formatting.
-- Do not use barrel files (index.ts).
-
-### React Component Development
-
-- Use **functional components** with hooks.
-- Use **TypeScript** for type safety.
-- Use arrow functions for components.
-- Return JSX or `null` from components.
-- Use the `data-testid` attribute to assist with testing.
-- Use default exports for components.
-- Use a **testId** prop for components that need to be tested, defaulting to the component name in kebab-case.
-
-### Performance and Optimization
-
-- Split code via route-level `lazy()` and `Suspense` for code splitting.
-
-### Styling Guidelines
-
-- Use **Tailwind CSS** for styling.
-- Apply base styles in `src/index.css`
-- Use CSS variables for theming (index.css).
-- Use class-variance-authority (CVA) for reusable component styles and variants, see: `src/common/utils/css.ts`.
-
-### Configuration
-
-- Use **.env** for environment variables prefixed with `VITE_` for Vite compatibility.
-
-### Maintainability
-
-- Keep components small and focused on a single responsibility.
-- Use comments to explain complex logic, but avoid obvious comments.
-- Organize imports logically: external libraries first, then internal components, hooks, and utils.
-
----
-
-## Testing Guidelines
-
-- Use **Vitest**.
-- Place test files adjacent to the source file, with `.test.ts` suffix.
-- Use Arrange - Act - Assert (AAA) pattern for test structure:
- - **Arrange:** Set up the test environment and inputs.
- - **Act:** Call the function being tested.
- - **Assert:** Verify the output and side effects.
-- Use `test-utils` for common test functions and helpers.
-- Use `describe` and `it` blocks for organization.
-- Mock dependencies using `vi.mock` or similar.
-- Use `beforeEach` for setup and `afterEach` for cleanup as needed.
-- Use `expect` assertions for results.
-- Use the `data-testid` attribute for selecting elements in tests.
-- Use `screen` from `@testing-library/react` for querying elements.
-- Use `userEvent` from `@testing-library/user-event` for simulating user interactions.
-- Prefer unit tests over integration tests in this repo.
-- 80% code coverage is the minimum requirement for all components and features.
-
----
-
-## UI Component Setup (shadcn/ui)
-
-After installing shadcn/ui:
-
-- Reusable UI components like ``, ``, `` live in `src/common/components/shadcn/`
-- DO override and customize each component’s styles with Tailwind and variants.
-- DO NOT modify shadcn/ui underlying component logic or structure, as this will make it difficult to maintain and update in the future. Instead create wrapper components if you need to add additional functionality or logic.
-- Recommended: use the CLI to scaffold new components:
-
- ```bash
- npx shadcn@latest add button input label
- ```
-
----
-
-## AWS CDK Guidelines
-
-- Self-contained infrastructure code in the `infrastructure` directory.
-- Define one CDK stack per major grouping of resources (e.g., CDN).
-- Use **.env** for environment variables prefixed with `CDK_`, but avoid committing this file.
-- Use Zod for schema validation of configuration values.
-- Tag all CDK resources appropriately (`App`, `Env`, `OU`, `Owner`).
-- Deploy separate environments (dev/qa/prd) using configuration values.
-
-### Example: S3 Bucket and CloudFront Distribution
-
-```ts
-// S3 bucket for the application
-const bucket = new s3.Bucket(this, 'CloudFrontSpaBucket', {
- removalPolicy: cdk.RemovalPolicy.DESTROY,
- autoDeleteObjects: true,
-});
-
-// S3 bucket deployment
-const deployment = new s3_deployment.BucketDeployment(this, 'CloudFrontSpaDeployment', {
- sources: [s3_deployment.Source.asset('../dist')],
- destinationBucket: bucket,
-});
-
-// CloudFront distribution
-const distribution = new cloudfront.Distribution(this, 'CloudFrontSpaDistribution', {
- certificate: certificate,
- comment: 'CDK Playground CloudFront SPA',
- defaultBehavior: {
- origin: cloudfront_origins.S3BucketOrigin.withOriginAccessControl(bucket),
- viewerProtocolPolicy: cloudfront.ViewerProtocolPolicy.REDIRECT_TO_HTTPS,
- },
- defaultRootObject: 'index.html',
- domainNames: ['cdk-playground.dev.leanstacks.net'],
- errorResponses: [
- {
- httpStatus: 403,
- responsePagePath: '/index.html',
- ttl: cdk.Duration.seconds(0),
- responseHttpStatus: 200,
- },
- {
- httpStatus: 404,
- responsePagePath: '/index.html',
- ttl: cdk.Duration.seconds(0),
- responseHttpStatus: 200,
- },
- ],
- priceClass: cloudfront.PriceClass.PRICE_CLASS_100,
-});
-```
+Refer to [AGENTS.md](../AGENTS.md) for all repository instructions, build commands, and coding standards.
diff --git a/.github/prompts/implement_issue.prompt.md b/.github/prompts/implement_issue.prompt.md
new file mode 100644
index 0000000..f31c44f
--- /dev/null
+++ b/.github/prompts/implement_issue.prompt.md
@@ -0,0 +1,43 @@
+---
+agent: 'agent'
+description: 'Implement an issue.'
+---
+
+Implement GitHub Issue #${input:issueNumber:Issue number} following the steps below. If you encounter any ambiguity, ask for clarification before proceeding. Follow overall project conventions specified in `AGENTS.md`.
+
+---
+
+**Step 1 — Read & Plan** _(stop here until I respond)_
+
+1. Fetch the issue body, comments, and any linked PRs via the GitHub MCP server.
+2. Read the affected source files to understand existing conventions (naming, structure, error handling, test style).
+3. Identify all changes required: source, tests, docs.
+4. Present a numbered implementation plan.
+5. Flag any ambiguity or architectural decision the ticket doesn't resolve — ask before assuming.
+6. Ask: **A) Autonomous** (implement fully, report when done) or **B) Step-by-step** (pause after each step for confirmation)?
+
+---
+
+**Step 2 — Implement**
+
+Execute the approved plan:
+
+- **Code**: Match existing conventions. Flag deviations before introducing them.
+- **Tests**: Cover happy path, edge cases, and failure paths using the existing test framework.
+- **Docs**: Update README if behavior changes; add inline comments for non-obvious logic; update `/docs` if affected.
+
+If you encounter scope not covered in the plan, stop and report before continuing.
+
+---
+
+**Step 3 — Done Criteria**
+
+Confirm before closing:
+
+- [ ] Lint passes, no new warnings
+- [ ] All tests pass, no unjustified skips
+- [ ] New tests cover happy path, edge cases, failure paths
+- [ ] No debug code, commented-out blocks, or unresolved TODOs
+- [ ] Docs reflect post-change behavior
+
+Provide a brief summary: what changed, what was tested, any follow-up items worth filing.
diff --git a/.github/prompts/plan_and_implement.prompt.md b/.github/prompts/plan_and_implement.prompt.md
new file mode 100644
index 0000000..fd786dd
--- /dev/null
+++ b/.github/prompts/plan_and_implement.prompt.md
@@ -0,0 +1,42 @@
+---
+agent: 'agent'
+description: 'Plan and implement a change.'
+---
+
+Plan and implement a change to the codebase following the steps below. If you encounter any ambiguity, ask for clarification before proceeding. Follow overall project conventions specified in `AGENTS.md`.
+
+---
+
+**Step 1 — Read & Plan** _(stop here until I respond)_
+
+1. Read the affected source files to understand existing conventions (naming, structure, error handling, test style).
+2. Identify all changes required: source, tests, docs.
+3. Present a numbered implementation plan.
+4. Flag any ambiguity or architectural decisions to resolve — ask before assuming.
+5. Ask: **A) Autonomous** (implement fully, report when done) or **B) Step-by-step** (pause after each step for confirmation)?
+
+---
+
+**Step 2 — Implement**
+
+Execute the approved plan:
+
+- **Code**: Match existing conventions. Flag deviations before introducing them. See AGENTS.md
+- **Tests**: Cover happy path, edge cases, and failure paths using the existing test framework.
+- **Docs**: Update README if behavior changes; add inline comments for non-obvious logic; update `/docs` if affected.
+
+If you encounter scope not covered in the plan, stop and report before continuing.
+
+---
+
+**Step 3 — Done Criteria**
+
+Confirm before closing:
+
+- [ ] Lint passes, no new warnings
+- [ ] All tests pass, no unjustified skips
+- [ ] New tests cover happy path, edge cases, failure paths
+- [ ] No debug code, commented-out blocks, or unresolved TODOs
+- [ ] Docs reflect post-change behavior
+
+Provide a brief summary: what changed, what was tested, any follow-up items worth filing.
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..07be5fa
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,134 @@
+# AGENTS.md - Autonomous Agent Operational Instructions
+
+This document defines the operational boundaries, structural constraints, and execution workflows for Autonomous AI Agents interacting with the **React Starter (react-starter)** repository. Read this file completely before planning or executing any tasks.
+
+---
+
+## 1. Agent Persona & Core Capabilities
+
+You are a **Senior TypeScript, React, and AWS CDK Developer Agent**. You possess complete mastery over modern frontend architectures, automated testing strategies, and Infrastructure-as-Code (IaC) deployment.
+
+### Authorized Capabilities
+
+- Code generation, modification, and refactoring across the front end and infrastructure codebases.
+- Executing local shell commands for linting, testing, formatting, and building.
+- Analyzing test coverage metrics and generating co-located unit tests.
+
+---
+
+## 2. Operational Workflow (The Agentic Loop)
+
+For every task or issue assigned to you, you **MUST** strictly follow this sequence. Do not skip steps.
+
+```
+
+[1. DISCOVER] --> [2. PLAN] --> [3. EXECUTE]
+(Read files & logs) (Draft architecture) (Modify/Write code)
+^ |
+| v
+[5. CONCLUDE] <-- [4. VERIFY] <-- [TEST/LINT]
+(Update docs/DoD) (Review Coverage) (Run local scripts)
+
+```
+
+1. **Discover & Analyze:** Read the relevant components, types, and existing tests. Do not guess the structure of existing code.
+2. **Plan & Confirm:** Formulate your implementation strategy. Explicitly state which files will be modified or created. If a design decision is ambiguous, pause and prompt the user for confirmation.
+3. **Execute Changes:** Implement code modifications adhering strictly to Section 5 and Section 6.
+4. **Test & Validate:** Execute the exact project test and lint commands. If tests fail or lint issues arise, self-correct immediately.
+5. **Verify Coverage:** Check that your changes maintain or exceed the project's code coverage requirements.
+6. **Conclude (Definition of Done):** Provide a concise summary of changes and validation outputs.
+
+---
+
+## 3. Workspace Architecture & Restrictions
+
+### Directory Map
+
+```
+
+src/
+├── common/ # App-wide shared assets
+│ ├── api/ # Global API hooks (e.g., useGetCurrentUser.ts)
+│ ├── components/ # Shared components
+│ │ └── shadcn/ # Atomic shadcn/ui components (DO NOT modify internals)
+│ ├── hooks/ # App-wide utilities hooks (e.g., useDebounce.ts)
+│ ├── models/ # Type and Interface definitions (e.g., Task.ts)
+│ ├── providers/ # Context/Theme providers
+│ └── utils/ # Global Axios instances and constants
+└── pages/ # Page-specific domains
+└── tasks/ # Feature group folder
+├── create/ # Feature-scoped components & tests
+├── configure/
+├── delete/
+├── hooks/ # Feature-isolated API/State hooks (e.g., useGetTasks.ts)
+└── utils/ # Feature-isolated pure utility logic
+infrastructure/ # AWS CDK Infrastructure (Self-contained)
+
+```
+
+### Critical Architecture Rules
+
+- **No Barrel Files:** Never create or maintain `index.ts` files for re-exporting. Import directly from the exact file path.
+- **Co-location Principle:** Always place unit tests (`*.test.ts`, `*.test.tsx`) in the exact same directory as the module or component they are testing.
+- **Coding Principles:** All source code should follow the Single Responsibility Principle (SRP) and Don't Repeat Yourself (DRY). Do not add unnecessary or unrequested source members, You Aint Gonna Need It (YAGNI).
+
+---
+
+## 4. Permitted Tooling & Command Index
+
+You are authorized to execute the following shell commands to validate your work. Do not use unlisted tools or invent flags.
+
+| Task | Command | Scope |
+| :----------------------- | :--------------------------------------- | :------------------------- |
+| **Install Dependencies** | `npm install` | Root Project |
+| **Run Unit Tests** | `npm run test` | Front End |
+| **Check Code Coverage** | `npm run test:coverage` | Front End |
+| **Lint Codebase** | `npm run lint` | Front End / Infrastructure |
+| **Format Code** | `npm run format` | Global |
+| **Add shadcn Component** | `npx shadcn@latest add [component]` | Front End Component Setup |
+| **CDK Synthesize** | `cd infrastructure && npm run cdk synth` | Infrastructure Validation |
+
+---
+
+## 5. Code Generation Guardrails
+
+### TypeScript Standards
+
+- **Strict Typing:** Set type safety to maximum. Avoid using `any` or `ts-ignore`.
+- **Typing Mechanics:** Prefer `interface` for structural object definitions (props, state) and `type` for complex intersections, unions, or utility modifications.
+- **Value Handling:** Use optional chaining (`?.`) and nullish coalescing (`??`) over manual falsy checks. Avoid forceful type assertions (`as Type`) unless interfacing with raw external boundaries.
+
+### React Component Layout
+
+- Write components as **Arrow Functions** using explicit functional component patterns.
+- Always use **Default Exports** for page components and standard components.
+- Enforce code splitting by leveraging route-level `lazy()` and `Suspense` operations.
+
+### Component Testing Hooks
+
+- Always inject a `data-testid` attribute or accept a `testId` prop on components to ensure reliable test selection.
+- The `testId` prop must default to the component's name written in `kebab-case`.
+
+### Styling & UI Systems (shadcn/ui & Tailwind)
+
+- Use **Tailwind CSS** classes natively. Apply thematic alterations through CSS variables via `src/index.css`.
+- Use `class-variance-authority` (CVA) within `src/common/utils/css.ts` when handling multi-variant components.
+- **shadcn Rule:** Never modify underlying code files inside `src/common/components/shadcn/` by hand. If behavior adjustments are required, write a wrapper component around them. Scaffold new ones using the authorized CLI command.
+
+### Infrastructure (AWS CDK)
+
+- Keep the `infrastructure/` directory entirely decoupled from front-end runtime mechanics.
+- Use **Zod** to rigorously validate environment configurations and configurations prefixed with `CDK_`.
+- Ensure every cloud resource contains the minimum required resource tags: `App`, `Env`, `OU`, and `Owner`.
+
+---
+
+## 6. Quality Gates & Definition of Done (DoD)
+
+Your task cannot be marked as complete until it passes the following strict criteria:
+
+1. **Zero Lint/Type Regressions:** The execution of `npm run lint` and TypeScript compilation returns a `0` exit code.
+2. **Co-located Test Presence:** Every new or modified source file (`.ts`, `.tsx`) has a corresponding partner `.test.ts(x)` file sitting directly next to it.
+3. **AAA Structure enforced:** Tests must visually segregate actions using comments or structural layout into `Arrange`, `Act`, and `Assert`.
+4. **Testing Library Best Practices:** Tests must utilize `screen` from `@testing-library/react` and interactions must be evaluated via `@testing-library/user-event`.
+5. **Coverage Floor Met:** The global and feature-scoped test coverage must remain at or above a strict **80% minimum requirement** across all updated lines of code.
diff --git a/src/common/components/Header/AppMenu.tsx b/src/common/components/Header/AppMenu.tsx
index faffbc0..3a214fc 100644
--- a/src/common/components/Header/AppMenu.tsx
+++ b/src/common/components/Header/AppMenu.tsx
@@ -54,6 +54,9 @@ const AppMenu = ({ side = 'right', testId = 'menu-app', ...props }: AppMenuProps
{t('tasks', { ns: 'tasks' })}
+
+ About
+
>
) : (
<>
@@ -67,6 +70,9 @@ const AppMenu = ({ side = 'right', testId = 'menu-app', ...props }: AppMenuProps
Components
+
+ About
+
>
)}
diff --git a/src/common/components/Router/Router.tsx b/src/common/components/Router/Router.tsx
index 7f01028..c25cf7a 100644
--- a/src/common/components/Router/Router.tsx
+++ b/src/common/components/Router/Router.tsx
@@ -53,6 +53,9 @@ const TextareaComponents = lazy(() => import('pages/Components/components/Textar
const ToastComponents = lazy(() => import('pages/Components/components/ToastComponents'));
const ToggleComponents = lazy(() => import('pages/Components/components/ToggleComponents'));
+// About Page Family
+const AboutPage = lazy(() => import('pages/About/AboutPage'));
+
// Tasks Page Family
const TasksPage = lazy(() => import('pages/Tasks/TasksPage'));
const TaskListLayout = lazy(() => import('pages/Tasks/components/TaskListLayout'));
@@ -230,6 +233,10 @@ export const routes: RouteObject[] = [
},
],
},
+ {
+ path: 'about',
+ element: withSuspense(),
+ },
],
},
{
diff --git a/src/common/utils/i18n/locales/en/common.json b/src/common/utils/i18n/locales/en/common.json
index 2c3c737..192a946 100644
--- a/src/common/utils/i18n/locales/en/common.json
+++ b/src/common/utils/i18n/locales/en/common.json
@@ -1,4 +1,13 @@
{
+ "about": "About the React Starter Kit",
+ "aboutDescription": "The React Starter Kit is designed to help you quickly set up and develop React applications. It provides a solid foundation with pre-configured tools and best practices.",
+ "attribute": "Attribute",
+ "buildDate": "Build date",
+ "buildInformation": "Build Information",
+ "buildTime": "Build time",
+ "buildTimestamp": "Build timestamp",
+ "commitSha": "Commit SHA",
+ "environment": "Environment",
"creatingReactApps": "Creating React apps just got a lot simpler",
"errors": {
"generic": "Uh oh",
@@ -21,5 +30,9 @@
"max_other": "Must be at most {{count}} characters. ",
"required": "Required. "
},
- "welcome": "Welcome"
+ "value": "Value",
+ "welcome": "Welcome",
+ "workflowName": "Workflow name",
+ "workflowRunNumber": "Workflow run number",
+ "workflowRunAttempt": "Workflow run attempt"
}
diff --git a/src/pages/About/AboutPage.test.tsx b/src/pages/About/AboutPage.test.tsx
new file mode 100644
index 0000000..44bcb81
--- /dev/null
+++ b/src/pages/About/AboutPage.test.tsx
@@ -0,0 +1,146 @@
+import { beforeEach, describe, expect, it, vi } from 'vitest';
+import { render, screen } from 'test/test-utils';
+
+import AboutPage from './AboutPage';
+
+// Mock the config module
+vi.mock('common/utils/config', () => ({
+ config: {
+ VITE_BUILD_DATE: '2026-07-22',
+ VITE_BUILD_TIME: '12:00:00',
+ VITE_BUILD_TS: '2026-07-22T12:00:00Z',
+ VITE_BUILD_COMMIT_SHA: 'abc123def456',
+ VITE_BUILD_ENV_CODE: 'test',
+ VITE_BUILD_WORKFLOW_NAME: 'CI/CD Pipeline',
+ VITE_BUILD_WORKFLOW_RUN_NUMBER: 42,
+ VITE_BUILD_WORKFLOW_RUN_ATTEMPT: 1,
+ },
+}));
+
+describe('AboutPage', () => {
+ beforeEach(() => {
+ vi.clearAllMocks();
+ });
+
+ it('should render successfully', async () => {
+ // ARRANGE
+ render();
+
+ // ACT
+ await screen.findByTestId('page-about');
+
+ // ASSERT
+ expect(screen.getByTestId('page-about')).toBeDefined();
+ });
+
+ it('should display the page heading', async () => {
+ // ARRANGE
+ render();
+
+ // ACT
+ await screen.findByTestId('page-about');
+
+ // ASSERT
+ expect(screen.getByRole('heading', { level: 1 })).toBeDefined();
+ });
+
+ it('should display the build information section heading', async () => {
+ // ARRANGE
+ render();
+
+ // ACT
+ await screen.findByTestId('page-about');
+
+ // ASSERT
+ const headings = screen.getAllByRole('heading', { level: 2 });
+ expect(headings.length).toBeGreaterThan(0);
+ });
+
+ it('should display the build info table', async () => {
+ // ARRANGE
+ render();
+
+ // ACT
+ await screen.findByTestId('table-build-info');
+
+ // ASSERT
+ expect(screen.getByTestId('table-build-info')).toBeDefined();
+ });
+
+ it('should display build date in the table', async () => {
+ // ARRANGE
+ render();
+
+ // ACT
+ await screen.findByTestId('table-build-info');
+
+ // ASSERT
+ expect(screen.getByText('07/22/2026')).toBeDefined();
+ });
+
+ it('should display build time in the table', async () => {
+ // ARRANGE
+ render();
+
+ // ACT
+ await screen.findByTestId('table-build-info');
+
+ // ASSERT
+ expect(screen.getByText('12:00:00')).toBeDefined();
+ });
+
+ it('should display commit SHA in the table', async () => {
+ // ARRANGE
+ render();
+
+ // ACT
+ await screen.findByTestId('table-build-info');
+
+ // ASSERT
+ expect(screen.getByText('abc123def456')).toBeDefined();
+ });
+
+ it('should display environment code in the table', async () => {
+ // ARRANGE
+ render();
+
+ // ACT
+ await screen.findByTestId('table-build-info');
+
+ // ASSERT
+ expect(screen.getByText('test')).toBeDefined();
+ });
+
+ it('should display workflow name in the table', async () => {
+ // ARRANGE
+ render();
+
+ // ACT
+ await screen.findByTestId('table-build-info');
+
+ // ASSERT
+ expect(screen.getByText('CI/CD Pipeline')).toBeDefined();
+ });
+
+ it('should display workflow run number in the table', async () => {
+ // ARRANGE
+ render();
+
+ // ACT
+ await screen.findByTestId('table-build-info');
+
+ // ASSERT
+ expect(screen.getByText('42')).toBeDefined();
+ });
+
+ it('should display workflow run attempt in the table', async () => {
+ // ARRANGE
+ render();
+
+ // ACT
+ await screen.findByTestId('table-build-info');
+
+ // ASSERT
+ expect(screen.getByText('1')).toBeDefined();
+ });
+});
diff --git a/src/pages/About/AboutPage.tsx b/src/pages/About/AboutPage.tsx
new file mode 100644
index 0000000..ef2c5ff
--- /dev/null
+++ b/src/pages/About/AboutPage.tsx
@@ -0,0 +1,107 @@
+import { ColumnDef } from '@tanstack/react-table';
+import { useTranslation } from 'react-i18next';
+import dayjs from 'dayjs';
+
+import { config } from 'common/utils/config';
+import Page from 'common/components/Content/Page';
+import Container from 'common/components/Content/Container';
+import Heading from 'common/components/Text/Heading';
+import Card from 'common/components/Card/Card';
+import Table from 'common/components/Table/Table';
+import { DateFormat } from 'common/utils/constants';
+
+/**
+ * Represents a build info attribute entry.
+ */
+interface BuildInfoAttribute {
+ label: string;
+ value: string;
+}
+
+/**
+ * The `AboutPage` component renders the About page which displays information
+ * about the application, including a description and build attributes.
+ *
+ * This page is publicly available and does not require authentication.
+ */
+const AboutPage = () => {
+ const { t } = useTranslation();
+
+ // Build info data
+ const buildInfoData: BuildInfoAttribute[] = [
+ {
+ label: t('buildDate', { ns: 'common' }),
+ value: dayjs(config.VITE_BUILD_DATE).format(DateFormat.DATE),
+ },
+ {
+ label: t('buildTime', { ns: 'common' }),
+ value: config.VITE_BUILD_TIME,
+ },
+ {
+ label: t('buildTimestamp', { ns: 'common' }),
+ value: dayjs(config.VITE_BUILD_TS).format(DateFormat.TIMESTAMP),
+ },
+ {
+ label: t('commitSha', { ns: 'common' }),
+ value: config.VITE_BUILD_COMMIT_SHA,
+ },
+ {
+ label: t('environment', { ns: 'common' }),
+ value: config.VITE_BUILD_ENV_CODE,
+ },
+ {
+ label: t('workflowName', { ns: 'common' }),
+ value: config.VITE_BUILD_WORKFLOW_NAME,
+ },
+ {
+ label: t('workflowRunNumber', { ns: 'common' }),
+ value: config.VITE_BUILD_WORKFLOW_RUN_NUMBER.toString(),
+ },
+ {
+ label: t('workflowRunAttempt', { ns: 'common' }),
+ value: config.VITE_BUILD_WORKFLOW_RUN_ATTEMPT.toString(),
+ },
+ ];
+
+ // Define table columns
+ const columns: ColumnDef[] = [
+ {
+ accessorKey: 'label',
+ header: t('attribute', { ns: 'common' }),
+ },
+ {
+ accessorKey: 'value',
+ header: t('value', { ns: 'common' }),
+ },
+ ];
+
+ return (
+
+
+