From 3a10f038d77cb55508bd4d9fa5528da21d3fd818 Mon Sep 17 00:00:00 2001 From: kevalyq Date: Sat, 25 Oct 2025 21:20:47 +0200 Subject: [PATCH 1/3] feat: add initial repository structure with complete configuration - Add package.json with full metadata - Add REUSE.toml for license compliance - Add .gitignore for Node.js/React projects - Add Prettier and Markdownlint configurations - Add LICENSE (AGPL-3.0-or-later) - Add CHANGELOG.md - Add README.md with setup instructions - Add scripts/preflight.sh for pre-push validation - Add placeholder files for symlinks (to be created locally) BREAKING CHANGE: Initial repository setup --- .gitignore | 58 ++++++++++++++++++++++++++++++++++++++ .markdownlint.json | 6 ++++ .markdownlintignore | 3 ++ .prettierignore | 11 ++++++++ .prettierrc.json | 10 +++++++ CHANGELOG.md | 18 ++++++++++++ LICENSE | 5 ++++ REUSE.toml | 68 +++++++++++++++++++++++++++++++++++++++++++++ package.json | 62 +++++++++++++++++++++++++++++++++++++++++ 9 files changed, 241 insertions(+) create mode 100644 .gitignore create mode 100644 .markdownlint.json create mode 100644 .markdownlintignore create mode 100644 .prettierignore create mode 100644 .prettierrc.json create mode 100644 CHANGELOG.md create mode 100644 LICENSE create mode 100644 REUSE.toml create mode 100644 package.json diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..81d60b3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,58 @@ +# SPDX-FileCopyrightText: 2025 SecPal Contributors +# SPDX-License-Identifier: CC0-1.0 + +# Dependencies +node_modules/ + +# Build artifacts +dist/ +build/ +.vite/ +.turbo/ + +# Environment & Secrets +.env +.env.* +!.env.example +secrets/ +credentials/ +*.key +*.pem +*.p12 +*.pfx +*.keystore +*.jks +.npmrc +.yarnrc + +# Testing +coverage/ +.nyc_output/ + +# IDE +.idea/ +.vscode/ +*.swp +*.swo +*~ + +# OS +.DS_Store +Thumbs.db +Desktop.ini + +# Logs +*.log +npm-debug.log* +yarn-debug.log* +yarn-error.log* +pnpm-debug.log* +lerna-debug.log* + +# Temporary files +*.tmp +*.temp +.cache/ + +# Storybook +storybook-static/ diff --git a/.markdownlint.json b/.markdownlint.json new file mode 100644 index 0000000..1dd8622 --- /dev/null +++ b/.markdownlint.json @@ -0,0 +1,6 @@ +{ + "default": true, + "MD013": false, + "MD033": false, + "MD041": false +} diff --git a/.markdownlintignore b/.markdownlintignore new file mode 100644 index 0000000..4890ada --- /dev/null +++ b/.markdownlintignore @@ -0,0 +1,3 @@ +node_modules/ +LICENSES/ +CHANGELOG.md diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 0000000..d35af50 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,11 @@ +# SPDX-FileCopyrightText: 2025 SecPal +# SPDX-License-Identifier: CC0-1.0 + +node_modules/ +dist/ +build/ +coverage/ +package-lock.json +pnpm-lock.yaml +yarn.lock +.vite/ diff --git a/.prettierrc.json b/.prettierrc.json new file mode 100644 index 0000000..115ffb9 --- /dev/null +++ b/.prettierrc.json @@ -0,0 +1,10 @@ +{ + "semi": true, + "trailingComma": "es5", + "singleQuote": false, + "printWidth": 80, + "tabWidth": 2, + "useTabs": false, + "arrowParens": "always", + "endOfLine": "lf" +} diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..56a5e34 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,18 @@ +# Changelog + +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). + +## [Unreleased] + +### Added + +- Initial repository setup +- React + TypeScript + Vite configuration +- Testing setup with Vitest and React Testing Library +- REUSE 3.3 compliance +- Pre-commit and pre-push quality gates + +[unreleased]: https://github.com/SecPal/frontend/commits/main diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..132c2b6 --- /dev/null +++ b/LICENSE @@ -0,0 +1,5 @@ +This project is licensed under the GNU Affero General Public License v3.0 or later. + +See LICENSES/AGPL-3.0-or-later.txt for the full license text. + +For third-party licenses, see the LICENSES/ directory. diff --git a/REUSE.toml b/REUSE.toml new file mode 100644 index 0000000..abcaac8 --- /dev/null +++ b/REUSE.toml @@ -0,0 +1,68 @@ +# SPDX-FileCopyrightText: 2025 SecPal +# SPDX-License-Identifier: CC0-1.0 + +version = 1 +SPDX-FileCopyrightText = "SecPal Contributors" + +[[annotations]] +path = "src/**" +SPDX-License-Identifier = "AGPL-3.0-or-later" + +[[annotations]] +path = "public/**" +SPDX-License-Identifier = "AGPL-3.0-or-later" + +[[annotations]] +path = "package.json" +SPDX-License-Identifier = "CC0-1.0" + +[[annotations]] +path = "package-lock.json" +SPDX-License-Identifier = "CC0-1.0" + +[[annotations]] +path = "tsconfig*.json" +SPDX-License-Identifier = "CC0-1.0" + +[[annotations]] +path = "vite.config.ts" +SPDX-License-Identifier = "CC0-1.0" + +[[annotations]] +path = ".prettierrc.json" +SPDX-License-Identifier = "CC0-1.0" + +[[annotations]] +path = ".prettierignore" +SPDX-License-Identifier = "CC0-1.0" + +[[annotations]] +path = ".gitignore" +SPDX-License-Identifier = "CC0-1.0" + +[[annotations]] +path = "README.md" +SPDX-FileCopyrightText = "2025 SecPal" +SPDX-License-Identifier = "CC0-1.0" + +[[annotations]] +path = ".github/**" +SPDX-FileCopyrightText = "2025 SecPal" +SPDX-License-Identifier = "CC0-1.0" + +[[annotations]] +path = "CHANGELOG.md" +SPDX-License-Identifier = "CC0-1.0" + +[[annotations]] +path = ".markdownlint*.json" +SPDX-License-Identifier = "CC0-1.0" + +[[annotations]] +path = ".markdownlintignore" +SPDX-License-Identifier = "CC0-1.0" + +[[annotations]] +path = "scripts/**" +SPDX-FileCopyrightText = "2025 SecPal Contributors" +SPDX-License-Identifier = "MIT" diff --git a/package.json b/package.json new file mode 100644 index 0000000..e3bfd77 --- /dev/null +++ b/package.json @@ -0,0 +1,62 @@ +{ + "name": "@secpal/frontend", + "version": "0.0.1", + "description": "React/TypeScript frontend for SecPal platform", + "private": true, + "type": "module", + "author": "SecPal", + "license": "AGPL-3.0-or-later", + "repository": { + "type": "git", + "url": "https://github.com/SecPal/frontend.git" + }, + "homepage": "https://github.com/SecPal/frontend#readme", + "bugs": { + "url": "https://github.com/SecPal/frontend/issues" + }, + "keywords": [ + "secpal", + "frontend", + "react", + "typescript", + "vite" + ], + "scripts": { + "dev": "vite", + "build": "tsc && vite build", + "preview": "vite preview", + "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", + "typecheck": "tsc --noEmit", + "test": "vitest", + "test:ui": "vitest --ui", + "test:coverage": "vitest --coverage", + "format": "prettier --write '**/*.{md,yml,yaml,json,ts,tsx,js,jsx}'", + "format:check": "prettier --check '**/*.{md,yml,yaml,json,ts,tsx,js,jsx}'" + }, + "dependencies": { + "react": "^18.3.1", + "react-dom": "^18.3.1" + }, + "devDependencies": { + "@testing-library/react": "^16.1.0", + "@testing-library/user-event": "^14.5.2", + "@types/react": "^18.3.18", + "@types/react-dom": "^18.3.5", + "@typescript-eslint/eslint-plugin": "^8.26.0", + "@typescript-eslint/parser": "^8.26.0", + "@vitejs/plugin-react": "^4.3.4", + "@vitest/ui": "^3.0.5", + "eslint": "^9.18.0", + "eslint-plugin-react-hooks": "^5.1.0", + "eslint-plugin-react-refresh": "^0.4.18", + "jsdom": "^25.0.1", + "prettier": "^3.4.2", + "typescript": "^5.7.3", + "vite": "^6.0.6", + "vitest": "^3.0.5" + }, + "engines": { + "node": ">=20.0.0", + "npm": ">=10.0.0" + } +} From 857c05a2846177d99df857264dee63ba03c084a7 Mon Sep 17 00:00:00 2001 From: kevalyq Date: Sat, 25 Oct 2025 21:21:53 +0200 Subject: [PATCH 2/3] feat: add README, preflight script, and pre-commit setup - Add comprehensive README.md with setup instructions - Add scripts/preflight.sh for pre-push validation - Add scripts/setup-pre-commit.sh for git hooks configuration - Include symlink creation instructions (DRY principle) - Document development workflow and testing guidelines --- README.md | 210 +++++++++++++++++++++++++++++++++++- scripts/preflight.sh | 95 ++++++++++++++++ scripts/setup-pre-commit.sh | 69 ++++++++++++ 3 files changed, 372 insertions(+), 2 deletions(-) create mode 100644 scripts/preflight.sh create mode 100644 scripts/setup-pre-commit.sh diff --git a/README.md b/README.md index 0c9bf2b..0cc5a18 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,208 @@ -# frontend -React/TypeScript frontend for SecPal platform + + +# SecPal Frontend + +[![REUSE Compliance](https://github.com/SecPal/frontend/actions/workflows/reuse.yml/badge.svg)](https://github.com/SecPal/frontend/actions/workflows/reuse.yml) +[![License Check](https://github.com/SecPal/frontend/actions/workflows/license-compatibility.yml/badge.svg)](https://github.com/SecPal/frontend/actions/workflows/license-compatibility.yml) +[![Quality Gates](https://github.com/SecPal/frontend/actions/workflows/quality.yml/badge.svg)](https://github.com/SecPal/frontend/actions/workflows/quality.yml) + +React/TypeScript frontend for the SecPal platform. + +## ๐Ÿ“‹ Prerequisites + +- Node.js >= 20.0.0 +- npm >= 10.0.0 +- Git with GPG signing configured + +## ๐Ÿš€ Getting Started + +### Clone Repository + +```bash +cd ~/code/SecPal +git clone https://github.com/SecPal/frontend.git +cd frontend +``` + +### โš ๏ธ IMPORTANT: Create Symlinks (DRY Principle) + +**Before installing dependencies**, you MUST create symlinks to avoid file duplication: + +```bash +# Navigate to frontend repository +cd ~/code/SecPal/frontend + +# Create symlinks to .github repository (governance files) +ln -sf ../.github/CONTRIBUTING.md . +ln -sf ../.github/SECURITY.md . +ln -sf ../.github/CODE_OF_CONDUCT.md . +ln -sf ../.github/CODEOWNERS . +ln -sf ../.github/.editorconfig .editorconfig +ln -sf ../.github/.gitattributes .gitattributes + +# Verify symlinks were created correctly +file CONTRIBUTING.md # Should show: symbolic link to ../.github/CONTRIBUTING.md +``` + +**Why symlinks?** To maintain DRY (Don't Repeat Yourself) principle across repositories. All governance files are centralized in the `.github` repository. + +### Install Dependencies + +```bash +npm install +``` + +### Setup Pre-Commit Hooks + +```bash +./scripts/setup-pre-commit.sh +``` + +## ๐Ÿ› ๏ธ Development + +### Start Development Server + +```bash +npm run dev +``` + +### Build for Production + +```bash +npm run build +``` + +### Run Tests + +```bash +# Run all tests +npm test + +# Run tests in watch mode +npm run test:ui + +# Generate coverage report +npm run test:coverage +``` + +### Code Quality + +```bash +# Lint code +npm run lint + +# Type checking +npm run typecheck + +# Format code +npm run format + +# Check formatting +npm run format:check +``` + +### Pre-Push Validation + +**Before every push**, run the preflight script: + +```bash +./scripts/preflight.sh +``` + +This runs: + +- โœ… Prettier formatting check +- โœ… Markdownlint +- โœ… REUSE compliance +- โœ… ESLint +- โœ… TypeScript type checking +- โœ… Vitest test suite +- โœ… PR size validation (โ‰ค600 lines) + +## ๐Ÿ“ Project Structure + +``` +frontend/ +โ”œโ”€โ”€ src/ +โ”‚ โ”œโ”€โ”€ components/ # React components +โ”‚ โ”œโ”€โ”€ hooks/ # Custom hooks +โ”‚ โ”œโ”€โ”€ pages/ # Page components +โ”‚ โ”œโ”€โ”€ services/ # API services +โ”‚ โ”œโ”€โ”€ types/ # TypeScript types +โ”‚ โ”œโ”€โ”€ utils/ # Utility functions +โ”‚ โ”œโ”€โ”€ App.tsx # Root component +โ”‚ โ””โ”€โ”€ main.tsx # Entry point +โ”œโ”€โ”€ public/ # Static assets +โ”œโ”€โ”€ tests/ # Test files +โ”œโ”€โ”€ .github/ # GitHub workflows and templates +โ”œโ”€โ”€ scripts/ # Build and utility scripts +โ””โ”€โ”€ package.json # Dependencies and scripts +``` + +## ๐Ÿงช Testing Guidelines + +- **Coverage target:** 80%+ for new code, 100% for critical paths +- **TDD mandatory:** Write failing test first, implement, refactor +- Use `@testing-library/react` for component testing +- Mock API calls with MSW (Mock Service Worker) +- Test user-visible behavior, not implementation + +## ๐Ÿ”’ Security + +- **Secret scanning:** Enabled with push protection +- **Dependabot:** Daily security updates (04:00 CET) +- **SAST:** CodeQL analysis on pull requests +- **Never commit:** API keys, passwords, tokens, `.env` files + +See [SECURITY.md](SECURITY.md) for reporting vulnerabilities. + +## ๐Ÿ“ Contributing + +See [CONTRIBUTING.md](CONTRIBUTING.md) for guidelines. + +### Branch Naming Convention + +- `feature/` - New features +- `fix/` - Bug fixes +- `docs/` - Documentation +- `refactor/` - Code refactoring +- `test/` - Test additions/fixes +- `chore/` - Maintenance +- `spike/` - Exploration (no TDD required, cannot merge to main) + +### Commit Messages + +Follow [Conventional Commits](https://www.conventionalcommits.org/): + +``` +feat: add user authentication +fix: resolve memory leak in dashboard +docs: update API integration guide +test: add tests for login form +``` + +## ๐Ÿ“œ License + +**AGPL-3.0-or-later** - See [LICENSE](LICENSE) for details. + +This project is REUSE 3.3 compliant. All files contain SPDX license headers. + +## ๐Ÿ”— Related Repositories + +- [API](https://github.com/SecPal/api) - Laravel backend +- [Contracts](https://github.com/SecPal/contracts) - OpenAPI specifications +- [.github](https://github.com/SecPal/.github) - Organization defaults + +## ๐Ÿ“ž Support + +- **Issues:** [GitHub Issues](https://github.com/SecPal/frontend/issues) +- **Security:** See [SECURITY.md](SECURITY.md) +- **Code of Conduct:** [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) + +--- + +**Maintained by:** SecPal Team +**Last Updated:** October 2025 diff --git a/scripts/preflight.sh b/scripts/preflight.sh new file mode 100644 index 0000000..446aae9 --- /dev/null +++ b/scripts/preflight.sh @@ -0,0 +1,95 @@ +#!/usr/bin/env bash +# SPDX-FileCopyrightText: 2025 SecPal Contributors +# SPDX-License-Identifier: MIT + +set -euo pipefail + +ROOT_DIR="$(git rev-parse --show-toplevel)" +cd "$ROOT_DIR" + +# Auto-detect default branch (fallback to main) +BASE="$(git remote show origin 2>/dev/null | sed -n '/HEAD branch/s/.*: //p')" +[ -z "${BASE:-}" ] && BASE="main" + +echo "Using base branch: $BASE" + +# Fetch base branch for PR size check (failure is handled later) +git fetch origin "$BASE" 2>/dev/null || true + +# 0) Formatting & Compliance +FORMAT_EXIT=0 +if command -v npx >/dev/null 2>&1; then + npx --yes prettier --check '**/*.{md,yml,yaml,json,ts,tsx,js,jsx}' || FORMAT_EXIT=1 + npx --yes markdownlint-cli2 '**/*.md' || FORMAT_EXIT=1 +fi +# Workflow linting (part of documented gates) +if [ -d .github/workflows ]; then + if command -v actionlint >/dev/null 2>&1; then + actionlint || FORMAT_EXIT=1 + else + echo "Warning: .github/workflows found but actionlint not installed - skipping workflow lint" >&2 + fi +fi +if command -v reuse >/dev/null 2>&1; then + reuse lint || FORMAT_EXIT=1 +fi +if [ "$FORMAT_EXIT" -ne 0 ]; then + echo "Formatting/compliance checks failed. Fix issues above." >&2 + exit 1 +fi + +# 1) Node.js / React / TypeScript +if [ -f pnpm-lock.yaml ] && command -v pnpm >/dev/null 2>&1; then + pnpm install --frozen-lockfile + pnpm run --if-present lint + pnpm run --if-present typecheck + pnpm run --if-present test +elif [ -f package-lock.json ] && command -v npm >/dev/null 2>&1; then + npm ci + npm audit --audit-level=high || { + echo "High or critical severity vulnerabilities detected by npm audit. Please address the issues above before continuing." >&2 + exit 1 + } + npm run --if-present lint + npm run --if-present typecheck + npm run --if-present test +elif [ -f yarn.lock ] && command -v yarn >/dev/null 2>&1; then + yarn install --frozen-lockfile + if command -v jq >/dev/null 2>&1; then + jq -e '.scripts.lint' package.json >/dev/null 2>&1 && yarn lint + jq -e '.scripts.typecheck' package.json >/dev/null 2>&1 && yarn typecheck + jq -e '.scripts.test' package.json >/dev/null 2>&1 && yarn test + elif command -v node >/dev/null 2>&1; then + node -e "process.exit(require('./package.json').scripts?.lint ? 0 : 1)" && yarn lint + node -e "process.exit(require('./package.json').scripts?.typecheck ? 0 : 1)" && yarn typecheck + node -e "process.exit(require('./package.json').scripts?.test ? 0 : 1)" && yarn test + else + echo "Warning: jq and node not found - attempting to run yarn scripts (failures will be ignored)" >&2 + yarn lint 2>/dev/null || true + yarn typecheck 2>/dev/null || true + yarn test 2>/dev/null || true + fi +fi + +# 2) Check PR size locally (against BASE) +if ! git rev-parse -q --verify "origin/$BASE" >/dev/null 2>&1; then + echo "Warning: Cannot verify base branch origin/$BASE - skipping PR size check." >&2 + echo "Tip: Run 'git fetch origin $BASE' to enable PR size checking." >&2 +else + MERGE_BASE=$(git merge-base "origin/$BASE" HEAD 2>/dev/null) + if [ -z "$MERGE_BASE" ]; then + echo "Warning: Cannot determine merge base with origin/$BASE. Skipping PR size check." >&2 + else + # Use --numstat for locale-independent parsing (sum insertions + deletions) + CHANGED=$(git diff --numstat "$MERGE_BASE"..HEAD 2>/dev/null | awk '{ins+=$1; del+=$2} END {print ins+del+0}') + [ -z "$CHANGED" ] && CHANGED=0 + if [ "$CHANGED" -gt 600 ]; then + echo "PR too large ($CHANGED > 600 lines). Please split into smaller slices." >&2 + exit 2 + fi + echo "Preflight OK ยท Changed lines: $CHANGED" + fi +fi + +# All checks passed +exit 0 diff --git a/scripts/setup-pre-commit.sh b/scripts/setup-pre-commit.sh new file mode 100644 index 0000000..038c425 --- /dev/null +++ b/scripts/setup-pre-commit.sh @@ -0,0 +1,69 @@ +#!/usr/bin/env bash +# SPDX-FileCopyrightText: 2025 SecPal Contributors +# SPDX-License-Identifier: MIT + +set -euo pipefail + +ROOT_DIR="$(git rev-parse --show-toplevel)" +GIT_HOOKS_DIR="$ROOT_DIR/.git/hooks" +PROJECT_HOOKS_DIR="$ROOT_DIR/.githooks" + +echo "Setting up pre-commit hooks..." + +# Create .githooks directory if it doesn't exist +mkdir -p "$PROJECT_HOOKS_DIR" + +# Create pre-push hook +cat > "$PROJECT_HOOKS_DIR/pre-push" << 'EOF' +#!/usr/bin/env bash +# SPDX-FileCopyrightText: 2025 SecPal Contributors +# SPDX-License-Identifier: MIT + +set -euo pipefail + +ROOT_DIR="$(git rev-parse --show-toplevel)" +cd "$ROOT_DIR" + +# Check if current branch is spike/* +BRANCH=$(git rev-parse --abbrev-ref HEAD) +if [[ "$BRANCH" == spike/* ]]; then + echo "Spike branch detected ($BRANCH) - running minimal checks (formatting + REUSE)" + + # Run only formatting and REUSE compliance + FORMAT_EXIT=0 + if command -v npx >/dev/null 2>&1; then + npx --yes prettier --check '**/*.{md,yml,yaml,json,ts,tsx,js,jsx}' || FORMAT_EXIT=1 + npx --yes markdownlint-cli2 '**/*.md' || FORMAT_EXIT=1 + fi + if command -v reuse >/dev/null 2>&1; then + reuse lint || FORMAT_EXIT=1 + fi + + if [ "$FORMAT_EXIT" -ne 0 ]; then + echo "Formatting/compliance checks failed. Fix issues above." >&2 + exit 1 + fi + + echo "Spike branch checks passed." + exit 0 +fi + +# For non-spike branches, run full preflight script +if [ -f "$ROOT_DIR/scripts/preflight.sh" ]; then + "$ROOT_DIR/scripts/preflight.sh" +else + echo "Warning: preflight.sh not found - skipping pre-push checks" >&2 +fi +EOF + +chmod +x "$PROJECT_HOOKS_DIR/pre-push" + +# Create symlink in .git/hooks +ln -sf "$PROJECT_HOOKS_DIR/pre-push" "$GIT_HOOKS_DIR/pre-push" + +echo "โœ… Pre-commit hooks configured successfully" +echo " - Pre-push hook: Runs preflight.sh before every push" +echo " - Spike branches: Only formatting + REUSE (tests skipped)" +echo "" +echo "To bypass (NOT RECOMMENDED):" +echo " git push --no-verify" From 9bd76f52a6da2391d56346a49962fa767b3f250f Mon Sep 17 00:00:00 2001 From: kevalyq Date: Sat, 25 Oct 2025 21:22:22 +0200 Subject: [PATCH 3/3] feat: add TypeScript, Vite config, and initial React app - Add tsconfig.json with strict mode and path aliases - Add tsconfig.node.json for build tools - Add vite.config.ts with Vitest configuration - Add src/main.tsx (entry point) - Add src/App.tsx (root component) - Add src/App.test.tsx (example test with TDD pattern) - Add src/index.css (basic styles) - Add index.html (HTML template) - Add tests/setup.ts (Vitest configuration) --- index.html | 13 +++++++++++++ src/App.test.tsx | 20 ++++++++++++++++++++ src/App.tsx | 17 +++++++++++++++++ src/index.css | 44 ++++++++++++++++++++++++++++++++++++++++++++ src/main.tsx | 18 ++++++++++++++++++ tests/setup.ts | 4 ++++ tsconfig.json | 33 +++++++++++++++++++++++++++++++++ tsconfig.node.json | 11 +++++++++++ vite.config.ts | 32 ++++++++++++++++++++++++++++++++ 9 files changed, 192 insertions(+) create mode 100644 index.html create mode 100644 src/App.test.tsx create mode 100644 src/App.tsx create mode 100644 src/index.css create mode 100644 src/main.tsx create mode 100644 tests/setup.ts create mode 100644 tsconfig.json create mode 100644 tsconfig.node.json create mode 100644 vite.config.ts diff --git a/index.html b/index.html new file mode 100644 index 0000000..764de3b --- /dev/null +++ b/index.html @@ -0,0 +1,13 @@ + + + + + + + SecPal + + +
+ + + diff --git a/src/App.test.tsx b/src/App.test.tsx new file mode 100644 index 0000000..fec8f7d --- /dev/null +++ b/src/App.test.tsx @@ -0,0 +1,20 @@ +// SPDX-FileCopyrightText: 2025 SecPal +// SPDX-License-Identifier: AGPL-3.0-or-later + +import { describe, it, expect } from "vitest"; +import { render, screen } from "@testing-library/react"; +import App from "./App"; + +describe("App", () => { + it("renders welcome message", () => { + render(); + expect(screen.getByText(/SecPal Frontend/i)).toBeInTheDocument(); + }); + + it("renders main content", () => { + render(); + expect( + screen.getByText(/Welcome to SecPal - Your secure platform/i) + ).toBeInTheDocument(); + }); +}); diff --git a/src/App.tsx b/src/App.tsx new file mode 100644 index 0000000..cf3fdc7 --- /dev/null +++ b/src/App.tsx @@ -0,0 +1,17 @@ +// SPDX-FileCopyrightText: 2025 SecPal +// SPDX-License-Identifier: AGPL-3.0-or-later + +function App() { + return ( +
+
+

SecPal Frontend

+
+
+

Welcome to SecPal - Your secure platform

+
+
+ ); +} + +export default App; diff --git a/src/index.css b/src/index.css new file mode 100644 index 0000000..2b1182d --- /dev/null +++ b/src/index.css @@ -0,0 +1,44 @@ +/* SPDX-FileCopyrightText: 2025 SecPal */ +/* SPDX-License-Identifier: AGPL-3.0-or-later */ + +:root { + font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif; + line-height: 1.5; + font-weight: 400; + + color-scheme: light dark; + color: rgba(255, 255, 255, 0.87); + background-color: #242424; + + font-synthesis: none; + text-rendering: optimizeLegibility; + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} + +body { + margin: 0; + display: flex; + place-items: center; + min-width: 320px; + min-height: 100vh; +} + +.app { + max-width: 1280px; + margin: 0 auto; + padding: 2rem; + text-align: center; +} + +header h1 { + font-size: 3.2em; + line-height: 1.1; +} + +@media (prefers-color-scheme: light) { + :root { + color: #213547; + background-color: #ffffff; + } +} diff --git a/src/main.tsx b/src/main.tsx new file mode 100644 index 0000000..f80f1af --- /dev/null +++ b/src/main.tsx @@ -0,0 +1,18 @@ +// SPDX-FileCopyrightText: 2025 SecPal +// SPDX-License-Identifier: AGPL-3.0-or-later + +import { StrictMode } from "react"; +import { createRoot } from "react-dom/client"; +import App from "./App"; +import "./index.css"; + +const rootElement = document.getElementById("root"); +if (!rootElement) { + throw new Error("Root element not found"); +} + +createRoot(rootElement).render( + + + +); diff --git a/tests/setup.ts b/tests/setup.ts new file mode 100644 index 0000000..eb9431c --- /dev/null +++ b/tests/setup.ts @@ -0,0 +1,4 @@ +// SPDX-FileCopyrightText: 2025 SecPal +// SPDX-License-Identifier: AGPL-3.0-or-later + +import "@testing-library/jest-dom"; diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..76baccb --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,33 @@ +{ + "compilerOptions": { + "target": "ES2020", + "useDefineForClassFields": true, + "lib": ["ES2020", "DOM", "DOM.Iterable"], + "module": "ESNext", + "skipLibCheck": true, + + /* Bundler mode */ + "moduleResolution": "bundler", + "allowImportingTsExtensions": true, + "resolveJsonModule": true, + "isolatedModules": true, + "noEmit": true, + "jsx": "react-jsx", + + /* Path aliases */ + "baseUrl": ".", + "paths": { + "@/*": ["src/*"] + }, + + /* Linting */ + "strict": true, + "noUnusedLocals": true, + "noUnusedParameters": true, + "noFallthroughCasesInSwitch": true, + "noUncheckedIndexedAccess": true, + "forceConsistentCasingInFileNames": true + }, + "include": ["src"], + "references": [{ "path": "./tsconfig.node.json" }] +} diff --git a/tsconfig.node.json b/tsconfig.node.json new file mode 100644 index 0000000..97ede7e --- /dev/null +++ b/tsconfig.node.json @@ -0,0 +1,11 @@ +{ + "compilerOptions": { + "composite": true, + "skipLibCheck": true, + "module": "ESNext", + "moduleResolution": "bundler", + "allowSyntheticDefaultImports": true, + "strict": true + }, + "include": ["vite.config.ts"] +} diff --git a/vite.config.ts b/vite.config.ts new file mode 100644 index 0000000..c06bc61 --- /dev/null +++ b/vite.config.ts @@ -0,0 +1,32 @@ +// SPDX-FileCopyrightText: 2025 SecPal +// SPDX-License-Identifier: CC0-1.0 + +import { defineConfig } from "vite"; +import react from "@vitejs/plugin-react"; +import path from "path"; + +// https://vite.dev/config/ +export default defineConfig({ + plugins: [react()], + resolve: { + alias: { + "@": path.resolve(__dirname, "src"), + }, + }, + test: { + globals: true, + environment: "jsdom", + setupFiles: "./tests/setup.ts", + coverage: { + provider: "v8", + reporter: ["text", "json", "html"], + exclude: [ + "node_modules/", + "tests/", + "**/*.config.ts", + "**/*.d.ts", + "**/index.ts", + ], + }, + }, +});