diff --git a/.github/workflows/frontend-ci.yml b/.github/workflows/frontend-ci.yml index e69de29..4242d0d 100644 --- a/.github/workflows/frontend-ci.yml +++ b/.github/workflows/frontend-ci.yml @@ -0,0 +1,39 @@ +name: Frontend Tests + +on: + push: + pull_request: + +permissions: + contents: read + +jobs: + test: + runs-on: ubuntu-latest + + steps: + - name: Checkout source code + uses: actions/checkout@v4 + + - name: Setup Node + uses: actions/setup-node@v4 + with: + node-version: "24" + + + - name: Install dependencies + run: | + cd frontend + npm ci + + - name: check prettier formatting + working-directory: frontend + run: npm run format:check + + - name: Run ESling + working-directory: frontend + run: npm run lint + + - name: Build project + working-directory: frontend + run: npm run build diff --git a/frontend/eslint.config.js b/frontend/eslint.config.js index ea36dd3..0e20d43 100644 --- a/frontend/eslint.config.js +++ b/frontend/eslint.config.js @@ -1,13 +1,13 @@ -import js from '@eslint/js' -import globals from 'globals' -import reactHooks from 'eslint-plugin-react-hooks' -import reactRefresh from 'eslint-plugin-react-refresh' -import { defineConfig, globalIgnores } from 'eslint/config' +import js from "@eslint/js"; +import globals from "globals"; +import reactHooks from "eslint-plugin-react-hooks"; +import reactRefresh from "eslint-plugin-react-refresh"; +import { defineConfig, globalIgnores } from "eslint/config"; export default defineConfig([ - globalIgnores(['dist']), + globalIgnores(["dist"]), { - files: ['**/*.{js,jsx}'], + files: ["**/*.{js,jsx}"], extends: [ js.configs.recommended, reactHooks.configs.flat.recommended, @@ -18,4 +18,4 @@ export default defineConfig([ parserOptions: { ecmaFeatures: { jsx: true } }, }, }, -]) +]); diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 1f71994..2a95587 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -27,6 +27,7 @@ "eslint-plugin-react-hooks": "^7.1.1", "eslint-plugin-react-refresh": "^0.5.3", "globals": "^17.7.0", + "prettier": "^3.9.6", "vite": "^8.2.0" } }, @@ -2410,6 +2411,22 @@ "node": ">= 0.8.0" } }, + "node_modules/prettier": { + "version": "3.9.6", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.9.6.tgz", + "integrity": "sha512-OpN0zzVdiaiAhxpuuj5efpIS4sY9j7bY6uR5mnj5yPzGkdkjNKSJeUThPb60Jw29QuAZgA4o+/iB49kFiaBX6g==", + "dev": true, + "license": "MIT", + "bin": { + "prettier": "bin/prettier.cjs" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/prettier/prettier?sponsor=1" + } + }, "node_modules/proxy-from-env": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-2.1.0.tgz", diff --git a/frontend/package.json b/frontend/package.json index 64b4ab1..45f8760 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -7,7 +7,8 @@ "dev": "vite", "build": "vite build", "lint": "eslint .", - "preview": "vite preview" + "preview": "vite preview", + "format:check": "prettier --check \"src/**/*.{js,jsx,ts,tsx,css,md,json}\"" }, "dependencies": { "@reduxjs/toolkit": "^2.12.0", @@ -29,6 +30,7 @@ "eslint-plugin-react-hooks": "^7.1.1", "eslint-plugin-react-refresh": "^0.5.3", "globals": "^17.7.0", + "prettier": "^3.9.6", "vite": "^8.2.0" } } diff --git a/frontend/src/App.css b/frontend/src/App.css index f90339d..f460279 100644 --- a/frontend/src/App.css +++ b/frontend/src/App.css @@ -167,7 +167,7 @@ &::before, &::after { - content: ''; + content: ""; position: absolute; top: -4.5px; border: 5px solid transparent; diff --git a/frontend/src/App.jsx b/frontend/src/App.jsx index 4f03aa1..1bc2f8a 100644 --- a/frontend/src/App.jsx +++ b/frontend/src/App.jsx @@ -1,11 +1,11 @@ -import { useState } from 'react' -import reactLogo from './assets/react.svg' -import viteLogo from './assets/vite.svg' -import heroImg from './assets/hero.png' -import './App.css' +import { useState } from "react"; +import reactLogo from "./assets/react.svg"; +import viteLogo from "./assets/vite.svg"; +import heroImg from "./assets/hero.png"; +import "./App.css"; function App() { - const [count, setCount] = useState(0) + const [count, setCount] = useState(0); return ( <> @@ -116,7 +116,7 @@ function App() {
> - ) + ); } -export default App +export default App; diff --git a/frontend/src/index.css b/frontend/src/index.css index 2c84af0..de008e5 100644 --- a/frontend/src/index.css +++ b/frontend/src/index.css @@ -11,8 +11,8 @@ --shadow: rgba(0, 0, 0, 0.1) 0 10px 15px -3px, rgba(0, 0, 0, 0.05) 0 4px 6px -2px; - --sans: system-ui, 'Segoe UI', Roboto, sans-serif; - --heading: system-ui, 'Segoe UI', Roboto, sans-serif; + --sans: system-ui, "Segoe UI", Roboto, sans-serif; + --heading: system-ui, "Segoe UI", Roboto, sans-serif; --mono: ui-monospace, Consolas, monospace; font: 18px/145% var(--sans); diff --git a/frontend/src/main.jsx b/frontend/src/main.jsx index b9a1a6d..fdce256 100644 --- a/frontend/src/main.jsx +++ b/frontend/src/main.jsx @@ -1,10 +1,10 @@ -import { StrictMode } from 'react' -import { createRoot } from 'react-dom/client' -import './index.css' -import App from './App.jsx' +import { StrictMode } from "react"; +import { createRoot } from "react-dom/client"; +import "./index.css"; +import App from "./App.jsx"; -createRoot(document.getElementById('root')).render( +createRoot(document.getElementById("root")).render(