Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
name: CI

on:
pull_request:
branches: [main]
push:
branches: [main]

# Cancel outdated runs on the same branch to save runner time and energy.
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true

jobs:
checks:
runs-on: self-hosted
steps:
- uses: actions/checkout@v4

- uses: actions/setup-node@v4
with:
node-version: 22
cache: npm

# npm ci installs exactly what package-lock.json says, so CI matches
# what we run locally.
- run: npm ci
- run: npm run lint
- run: npm run format:check
- run: npm test
- run: npm run build
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"semi": false,
"singleQuote": true
}
}
22 changes: 13 additions & 9 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# AGENTS.md

## Project overview

- **Name:** UFOund it
Expand All @@ -9,15 +10,15 @@

## Tech stack

| Area | Choice |
| --- | --- |
| Frontend | React, TypeScript, Vite, React Router |
| API | GraphQL (custom backend, Node + TypeScript, Apollo Server) |
| GraphQL client | Apollo Client |
| Database | MySQL (leaning, not final), run directly on the VM |
| Testing | Vitest + React Testing Library (components), e2e tool and API testing TBD |
| Linting / formatting | ESLint, Prettier |
| UI libraries | Leaflet with react-leaflet (OpenStreetMap tiles, no API key) |
| Area | Choice |
| -------------------- | ------------------------------------------------------------------------- |
| Frontend | React, TypeScript, Vite, React Router |
| API | GraphQL (custom backend, Node + TypeScript, Apollo Server) |
| GraphQL client | Apollo Client |
| Database | MySQL (leaning, not final), run directly on the VM |
| Testing | Vitest + React Testing Library (components), e2e tool and API testing TBD |
| Linting / formatting | ESLint, Prettier |
| UI libraries | Leaflet with react-leaflet (OpenStreetMap tiles, no API key) |

## Commands

Expand Down Expand Up @@ -101,15 +102,18 @@ frontend/
## Boundaries

Always:

- Run lint and tests before proposing a change is done.
- Ask before making large or cross-cutting changes.

Ask first:

- Adding or upgrading dependencies.
- Changing the database schema or GraphQL schema.
- Changing project structure or tooling.

Never:

- Commit secrets, credentials or `.env` files.
- Use Docker for the database or backend (course requirement).
- Edit generated files or lock files by hand.
Expand Down
18 changes: 9 additions & 9 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,16 +29,17 @@ Always run `npm install` again after pulling changes that touch `package.json`.
- Write issues concrete enough to be resolved with a single PR. Split large tasks into several issues rather than making one giant one.

## Commits

**Format**

```
<Type>: <Short, capitalized subject line (≤50 chars)>
[Optional body explaining what and why, wrapped at 72 chars]
```

**Rules**

- Separate subject from body with a blank line
- Limit the subject line to 50 characters
- Capitalize the subject line
Expand All @@ -48,9 +49,8 @@ Always run `npm install` again after pulling changes that touch `package.json`.
- Use the body to explain what and why, not how
- Reference the issue the commit belongs to, e.g. `#12`, and use `Closes #12` in the final commit or the PR description to auto-close it on merge


**Types**

- `Feat`: new feature
- `Fix`: bug fix
- `Docs`: documentation
Expand All @@ -59,11 +59,11 @@ Always run `npm install` again after pulling changes that touch `package.json`.
- `Test`: adding or fixing tests
- `Chore`: build or maintenance tasks
- `Wip`: work in progress
**Example**
**Example**

```
Feat: add favorite button to resource card
Adds a star icon on each resource card that toggles a favorite
state stored in localStorage, so favorites persist across
browser restarts as required by the assignment.
Expand Down
20 changes: 10 additions & 10 deletions frontend/eslint.config.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import js from "@eslint/js";
import globals from "globals";
import reactHooks from "eslint-plugin-react-hooks";
import reactRefresh from "eslint-plugin-react-refresh";
import tseslint from "typescript-eslint";
import { defineConfig, globalIgnores } from "eslint/config";
import eslintConfigPrettier from "eslint-config-prettier/flat";
import js from '@eslint/js'
import globals from 'globals'
import reactHooks from 'eslint-plugin-react-hooks'
import reactRefresh from 'eslint-plugin-react-refresh'
import tseslint from 'typescript-eslint'
import { defineConfig, globalIgnores } from 'eslint/config'
import eslintConfigPrettier from 'eslint-config-prettier/flat'

export default defineConfig([
globalIgnores(["dist"]),
globalIgnores(['dist']),
{
files: ["**/*.{ts,tsx}"],
files: ['**/*.{ts,tsx}'],
extends: [
js.configs.recommended,
tseslint.configs.recommended,
Expand All @@ -21,4 +21,4 @@ export default defineConfig([
globals: globals.browser,
},
},
]);
])
4 changes: 3 additions & 1 deletion frontend/src/components/Banner.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,9 @@ function Banner() {
<Link className="banner__title" to="/">
<span className="banner__ufo">UFO</span>und it
</Link>
<Link className="banner__submit" to="/submit">Report a sighting</Link>
<Link className="banner__submit" to="/submit">
Report a sighting
</Link>
</div>
</header>
)
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/components/LocationPicker.css
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,4 @@
.location-picker {
height: 280px;
}
}
}
11 changes: 8 additions & 3 deletions frontend/src/components/LocationPicker.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ interface LocationPickerProps {
onPositionChange: (position: [number, number]) => void
}

function MapClickHandler({ onPositionChange }: Pick<LocationPickerProps, 'onPositionChange'>) {
function MapClickHandler({
onPositionChange,
}: Pick<LocationPickerProps, 'onPositionChange'>) {
useMapEvents({
click: (event) => onPositionChange([event.latlng.lat, event.latlng.lng]),
})
Expand All @@ -30,7 +32,10 @@ function MapClickHandler({ onPositionChange }: Pick<LocationPickerProps, 'onPosi

function LocationPicker({ position, onPositionChange }: LocationPickerProps) {
return (
<div className="location-picker" aria-label="Choose sighting location on map">
<div
className="location-picker"
aria-label="Choose sighting location on map"
>
<MapContainer
center={[20, 0]}
zoom={2}
Expand All @@ -49,4 +54,4 @@ function LocationPicker({ position, onPositionChange }: LocationPickerProps) {
)
}

export default LocationPicker
export default LocationPicker
2 changes: 1 addition & 1 deletion frontend/src/data/sighting-store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,4 +22,4 @@ export function addSighting(sighting: Omit<UfoSighting, 'id' | 'datePosted'>) {
sightings = [newSighting, ...sightings]
listeners.forEach((listener) => listener())
return newSighting
}
}
2 changes: 1 addition & 1 deletion frontend/src/hooks/use-sightings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ import { getSightings, subscribeToSightings } from '../data/sighting-store'

export function useSightings() {
return useSyncExternalStore(subscribeToSightings, getSightings, getSightings)
}
}
4 changes: 2 additions & 2 deletions frontend/src/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion frontend/src/pages/SubmitSightingPage.css
Original file line number Diff line number Diff line change
Expand Up @@ -117,4 +117,4 @@
.submit-sighting__row {
grid-template-columns: 1fr;
}
}
}
Loading