Repository navigation
Release: sync main with develop - #74
Merged
Merged
Conversation
Feature/ia 4 text atoms
Feature/ia 5 storybook
Feature/ia 6 setup i18n
Feature/ia 7 main menu dm
Fixed await error
Added tests for Main Menu component
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
Contributor
There was a problem hiding this comment.
Pull request overview
This PR syncs main with develop to establish the first real release branch, bringing in the current Go backend + Vite/React frontend implementation, along with supporting tooling (tests, Storybook, Playwright, deploy workflow).
Changes:
- Adds a Go workspace/module backend with Postgres migrations, auth/session handling, and invoice domain scaffolding.
- Replaces the prior Next.js scaffold with a Vite + React SPA (react-router), Tailwind v4 styling, i18n wiring, and UI primitives.
- Introduces unit/snapshot tests, Playwright e2e specs, Storybook config, and a backend deployment workflow.
Reviewed changes
Copilot reviewed 227 out of 243 changed files in this pull request and generated 11 comments.
Show a summary per file
| File | Description |
|---|---|
| go.work | Go workspace pointing to backend module |
| frontend/vitest.setup.ts | Vitest DOM matchers setup |
| frontend/vite.config.ts | Vite config (SVGR, Tailwind, Vitest) |
| frontend/vercel.json | SPA rewrite to index.html |
| frontend/tsconfig.json | TS config for Vite/React + tests |
| frontend/tailwind.config.ts | Tailwind theme/config updates |
| frontend/svgr.d.ts | Type declarations for SVG imports |
| frontend/src/styles/ui/text.css | Text utility classes layer |
| frontend/src/styles/ui/button.css | Button utility classes layer |
| frontend/src/styles/tailwind.css | Tailwind v4 import + legacy config bridge |
| frontend/src/styles/app.css | Global stylesheet composition + theme vars |
| frontend/src/stores/store.ts | Redux store factory (placeholder reducer) |
| frontend/src/stores/hooks.ts | Typed redux hooks |
| frontend/src/lib/welcome-modal.ts | Welcome modal localStorage helpers |
| frontend/src/lib/session-token.ts | Session token localStorage helpers |
| frontend/src/lib/session-token.test.ts | Tests for session token helpers |
| frontend/src/lib/i18n/routing.ts | Locale routing constants/types |
| frontend/src/lib/i18n/messages.ts | Message loader/scaffold |
| frontend/src/lib/api-client.ts | Fetch wrapper + auth/token handling |
| frontend/src/hooks/use-visibility-toggle.ts | Shared visibility toggle hook |
| frontend/src/hooks/use-dark-mode.ts | Theme toggle hook (hydration-safe) |
| frontend/src/features/invoices/utils/invoice-form-values.ts | Invoice form value mapping helpers |
| frontend/src/features/invoices/utils/invoice-form-values.test.ts | Tests for invoice form mappings |
| frontend/src/features/invoices/utils/invoice-date.ts | Display/input date conversion helpers |
| frontend/src/features/invoices/utils/invoice-date.test.ts | Tests for invoice date conversion |
| frontend/src/features/invoices/utils/get-line-item-total.ts | Line item total helper |
| frontend/src/features/invoices/utils/get-line-item-total.test.ts | Tests for line item totals |
| frontend/src/features/invoices/utils/get-invoice-status-styles.ts | Status-to-style mapping helper |
| frontend/src/features/invoices/utils/get-invoice-status-styles.test.ts | Tests for status style mapping |
| frontend/src/features/invoices/utils/format-invoice-amount.ts | Locale/currency formatting helpers |
| frontend/src/features/invoices/utils/format-invoice-amount.test.ts | Tests for amount formatting |
| frontend/src/features/invoices/types/invoice.ts | Invoice/shared invoice prop types |
| frontend/src/features/invoices/hooks/use-invoice-form-labels.ts | i18n-backed form label hook |
| frontend/src/features/invoices/components/invoices-empty-state/invoices-empty-state.types.ts | Empty state prop types |
| frontend/src/features/invoices/components/invoices-empty-state/invoices-empty-state.tsx | Empty state component |
| frontend/src/features/invoices/components/invoices-empty-state/invoices-empty-state.stories.tsx | Storybook story for empty state |
| frontend/src/features/invoices/components/invoice/mobile-view.tsx | Invoice list row (mobile layout) |
| frontend/src/features/invoices/components/invoice/invoice.tsx | Invoice wrapper (mobile+desktop) |
| frontend/src/features/invoices/components/invoice/invoice.test.tsx | Unit tests for Invoice wrapper |
| frontend/src/features/invoices/components/invoice/invoice.stories.tsx | Storybook story for Invoice |
| frontend/src/features/invoices/components/invoice/invoice.snapshot.test.tsx | Snapshot test for Invoice views |
| frontend/src/features/invoices/components/invoice/desktop-view.tsx | Invoice list row (desktop layout) |
| frontend/src/features/invoices/components/invoice/snapshots/invoice.snapshot.test.tsx.snap | Snapshot output for invoice |
| frontend/src/features/invoices/components/invoice-form-drawer/invoice-form-drawer.types.ts | Invoice drawer types |
| frontend/src/features/invoices/components/invoice-details/invoice-details.types.ts | Invoice details component types |
| frontend/src/features/invoices/components/invoice-details/invoice-details.stories.tsx | Storybook stories for invoice details |
| frontend/src/features/invoices/components/invoice-bar/invoice-bar.types.ts | Invoice list toolbar types |
| frontend/src/features/invoices/components/invoice-bar/invoice-bar.stories.tsx | Storybook story for invoice bar |
| frontend/src/features/invoices/components/invoice-bar/invoice-bar.snapshot.test.tsx | Snapshot test for invoice bar |
| frontend/src/features/invoices/components/invoice-bar/snapshots/invoice-bar.snapshot.test.tsx.snap | Snapshot output for invoice bar |
| frontend/src/features/invoices/components/delete-invoice-dialog/delete-invoice-dialog.types.ts | Delete dialog prop types |
| frontend/src/features/invoices/components/delete-invoice-dialog/delete-invoice-dialog.tsx | Delete confirmation dialog |
| frontend/src/features/invoices/components/delete-invoice-dialog/delete-invoice-dialog.stories.tsx | Storybook story for delete dialog |
| frontend/src/features/invoices/api/use-invoices.ts | Hook to fetch all invoices |
| frontend/src/features/invoices/api/use-invoices.test.ts | Tests for useInvoices |
| frontend/src/features/invoices/api/use-invoice.ts | Hook to fetch a single invoice |
| frontend/src/features/invoices/api/use-invoice.test.ts | Tests for useInvoice |
| frontend/src/features/invoices/api/update-invoice.ts | PUT invoice API client |
| frontend/src/features/invoices/api/update-invoice.test.ts | Tests for updateInvoice |
| frontend/src/features/invoices/api/set-invoice-status.ts | Status transition API client |
| frontend/src/features/invoices/api/set-invoice-status.test.ts | Tests for setInvoiceStatus |
| frontend/src/features/invoices/api/invoice-mapper.ts | API <-> UI invoice mapping |
| frontend/src/features/invoices/api/get-invoices.ts | GET invoices API client |
| frontend/src/features/invoices/api/get-invoices.test.ts | Tests for getInvoices |
| frontend/src/features/invoices/api/get-invoice.ts | GET invoice API client |
| frontend/src/features/invoices/api/get-invoice.test.ts | Tests for getInvoice |
| frontend/src/features/invoices/api/delete-invoice.ts | DELETE invoice API client |
| frontend/src/features/invoices/api/delete-invoice.test.ts | Tests for deleteInvoice |
| frontend/src/features/invoices/api/create-invoice.ts | POST invoice API client |
| frontend/src/features/invoices/api/create-invoice.test.ts | Tests for createInvoice |
| frontend/src/features/auth/hooks/use-session.ts | Session resolution + actions hook |
| frontend/src/features/auth/components/welcome-modal/welcome-modal.tsx | Welcome modal component |
| frontend/src/features/auth/components/welcome-modal/welcome-modal.test.tsx | Tests for welcome modal |
| frontend/src/features/auth/components/splash-screen/splash-screen.types.ts | Splash screen prop types |
| frontend/src/features/auth/components/splash-screen/splash-screen.tsx | Splash screen component |
| frontend/src/features/auth/api/logout.ts | Logout API client |
| frontend/src/features/auth/api/google-login-url.ts | Google login redirect URL helper |
| frontend/src/features/auth/api/get-me.ts | /auth/me API client + types |
| frontend/src/features/auth/api/continue-as-guest.ts | Guest session API client + types |
| frontend/src/config/constants.ts | Frontend runtime constants |
| frontend/src/components/ui/text/text.types.ts | Text component prop types |
| frontend/src/components/ui/text/text.tsx | Text primitive component |
| frontend/src/components/ui/text/text.test.tsx | Unit tests for Text |
| frontend/src/components/ui/text/text.stories.tsx | Storybook for Text |
| frontend/src/components/ui/text/text.snapshot.test.tsx | Snapshot tests for Text |
| frontend/src/components/ui/text/snapshots/text.snapshot.test.tsx.snap | Snapshot output for Text |
| frontend/src/components/ui/rich-text/rich-text.types.ts | RichText prop types |
| frontend/src/components/ui/rich-text/rich-text.tsx | RichText primitive |
| frontend/src/components/ui/rich-text/rich-text.test.tsx | Unit tests for RichText |
| frontend/src/components/ui/rich-text/rich-text.stories.tsx | Storybook for RichText |
| frontend/src/components/ui/rich-text/rich-text.snapshot.test.tsx | Snapshot tests for RichText |
| frontend/src/components/ui/rich-text/snapshots/rich-text.snapshot.test.tsx.snap | Snapshot output for RichText |
| frontend/src/components/ui/icon/icon.types.ts | Icon prop types |
| frontend/src/components/ui/icon/icon.tsx | Icon component (SVGR switch) |
| frontend/src/components/ui/icon/icon.test.tsx | Unit tests for Icon |
| frontend/src/components/ui/icon/icon.stories.tsx | Storybook for Icon |
| frontend/src/components/ui/icon/icon.snapshot.test.tsx | Snapshot test for Icon |
| frontend/src/components/ui/icon/assets/trash.svg | Trash icon asset |
| frontend/src/components/ui/icon/assets/menu-logo-btn.svg | Menu logo icon asset |
| frontend/src/components/ui/icon/assets/google.svg | Google icon asset |
| frontend/src/components/ui/icon/assets/dm-sun.svg | Dark mode sun icon asset |
| frontend/src/components/ui/icon/assets/dm-moon.svg | Dark mode moon icon asset |
| frontend/src/components/ui/icon/assets/circle-plus.svg | Plus icon asset |
| frontend/src/components/ui/icon/assets/chevron-right.svg | Chevron right icon asset |
| frontend/src/components/ui/icon/assets/chevron-down.svg | Chevron down icon asset |
| frontend/src/components/ui/icon/snapshots/icon.snapshot.test.tsx.snap | Snapshot output for Icon |
| frontend/src/components/ui/grid/grid.types.ts | Grid primitive prop types |
| frontend/src/components/ui/grid/grid.test.tsx | Unit tests for Grid |
| frontend/src/components/ui/grid/grid.stories.tsx | Storybook for Grid |
| frontend/src/components/ui/grid/grid.snapshot.test.tsx | Snapshot test for Grid |
| frontend/src/components/ui/grid/snapshots/grid.snapshot.test.tsx.snap | Snapshot output for Grid |
| frontend/src/components/ui/flex/flex.types.ts | Flex primitive prop types |
| frontend/src/components/ui/flex/flex.test.tsx | Unit tests for Flex |
| frontend/src/components/ui/flex/flex.snapshot.test.tsx | Snapshot test for Flex |
| frontend/src/components/ui/flex/snapshots/flex.snapshot.test.tsx.snap | Snapshot output for Flex |
| frontend/src/components/ui/container/container.types.ts | Container primitive prop types |
| frontend/src/components/ui/container/container.tsx | Container primitive |
| frontend/src/components/ui/container/container.test.tsx | Unit tests for Container |
| frontend/src/components/ui/container/container.stories.tsx | Storybook for Container |
| frontend/src/components/ui/container/container.snapshot.test.tsx | Snapshot test for Container |
| frontend/src/components/ui/container/snapshots/container.snapshot.test.tsx.snap | Snapshot output for Container |
| frontend/src/components/ui/checkbox/checkbox.types.ts | Checkbox prop types |
| frontend/src/components/ui/checkbox/checkbox.tsx | Checkbox primitive |
| frontend/src/components/ui/checkbox/checkbox.test.tsx | Unit tests for Checkbox |
| frontend/src/components/ui/checkbox/checkbox.stories.tsx | Storybook for Checkbox |
| frontend/src/components/ui/checkbox/checkbox.snapshot.test.tsx | Snapshot tests for Checkbox |
| frontend/src/components/ui/button/button.types.ts | Button prop types (button/anchor union) |
| frontend/src/components/ui/button/button.tsx | Button primitive |
| frontend/src/components/ui/button/button.test.tsx | Unit tests for Button |
| frontend/src/components/ui/button/button.stories.tsx | Storybook for Button |
| frontend/src/components/ui/button/button.snapshot.test.tsx | Snapshot test file for Button |
| frontend/src/components/ui/button/snapshots/button.snapshot.test.tsx.snap | Snapshot output for Button |
| frontend/src/components/layouts/main-menu/main-menu.types.ts | Main menu prop types |
| frontend/src/components/layouts/main-menu/main-menu.stories.tsx | Storybook for main menu |
| frontend/src/components/layouts/main-menu/main-menu.snapshot.test.tsx | Snapshot test for main menu |
| frontend/src/components/layouts/app-shell/app-shell.tsx | App shell layout |
| frontend/src/app/session-gate.tsx | Session gate routing/layout wrapper |
| frontend/src/app/routes/not-found.tsx | Not found route |
| frontend/src/app/routes/invoice-detail.tsx | Invoice detail route |
| frontend/src/app/routes/auth-callback.tsx | OAuth callback token capture route |
| frontend/src/app/routes/auth-callback.test.tsx | Tests for auth callback route |
| frontend/src/app/router.tsx | Browser router definition |
| frontend/src/app/root-layout.tsx | App-wide providers root |
| frontend/src/app/provider.tsx | Theme + Redux provider composition |
| frontend/src/app/page.tsx | Removed Next.js page scaffold |
| frontend/src/app/main.tsx | Vite app entrypoint |
| frontend/src/app/layout.tsx | Removed Next.js root layout |
| frontend/src/app/globals.css | Removed Next.js global tailwind scaffold |
| frontend/src/tests/page.tsx | Removed Next.js page test scaffold |
| frontend/README.md | Updated frontend docs (stack/commands) |
| frontend/postcss.config.mjs | Removed PostCSS config (Tailwind v4) |
| frontend/playwright.config.ts | Playwright config for real API/db |
| frontend/next.config.ts | Removed Next.js config |
| frontend/jest.config.ts | Removed Jest config (Vitest used) |
| frontend/index.html | Vite HTML entry + theme prepaint |
| frontend/e2e/splash-screen.spec.ts | Splash screen e2e coverage |
| frontend/e2e/mark-as-paid.spec.ts | Status transition e2e coverage |
| frontend/e2e/invoice-list.spec.ts | Invoice list e2e coverage |
| frontend/e2e/edit-invoice.spec.ts | Edit flow e2e coverage |
| frontend/e2e/delete-invoice.spec.ts | Delete flow e2e coverage |
| frontend/e2e/create-invoice.spec.ts | Create flow e2e coverage |
| frontend/.storybook/preview.tsx | Storybook preview decorators/themes |
| frontend/.storybook/manager-head.html | Storybook favicon config |
| frontend/.storybook/main.ts | Storybook Vite builder config |
| frontend/.lintstagedrc | Lint-staged configuration update |
| frontend/.gitignore | Frontend ignores (dist, playwright, etc.) |
| frontend/.env.example | Frontend env example |
| backend/README.md | Backend docs (stack/api/deploy/testing) |
| backend/migrations/migrations.go | Embedded migrations FS |
| backend/migrations/000006_add_user_picture.up.sql | Add users.picture column |
| backend/migrations/000006_add_user_picture.down.sql | Drop users.picture column |
| backend/migrations/000005_remove_unowned_seed_invoices.up.sql | Remove now-invisible seed invoices |
| backend/migrations/000005_remove_unowned_seed_invoices.down.sql | Recreate seed invoices/items |
| backend/migrations/000004_add_users_and_sessions.up.sql | Add users/sessions + ownership columns |
| backend/migrations/000004_add_users_and_sessions.down.sql | Roll back ownership/users/sessions |
| backend/migrations/000003_backfill_seed_draft_dates.up.sql | Seed draft date backfill |
| backend/migrations/000003_backfill_seed_draft_dates.down.sql | Revert draft backfill |
| backend/migrations/000002_seed_invoices.up.sql | Seed example invoices/items |
| backend/migrations/000002_seed_invoices.down.sql | Remove seeded invoices |
| backend/migrations/000001_create_invoices.up.sql | Create invoice schema + triggers |
| backend/migrations/000001_create_invoices.down.sql | Drop invoice schema + trigger fn |
| backend/main.go | Backend composition root + CORS + sweeper |
| backend/internal/invoice/invoice.go | Invoice domain model + Total() |
| backend/internal/invoice/invoice_test.go | Tests for domain helpers |
| backend/internal/database/migrate.go | Migration runner using embedded FS |
| backend/internal/database/database.go | DB connect w/ retry |
| backend/internal/config/config.go | Env config loading/validation |
| backend/internal/auth/middleware.go | Session middleware + owner context |
| backend/internal/auth/auth.go | Auth domain types |
| backend/go.mod | Backend module deps + go version |
| backend/deploy/invoice-api.service | systemd unit for backend binary |
| backend/deploy/docker-compose.yml | Production-ish Postgres compose |
| backend/deploy/Caddyfile.snippet | Caddy reverse-proxy snippet |
| backend/deploy/.env.example | Production env example |
| backend/compose.yaml | Local Postgres compose |
| backend/.gitignore | Ignore backend env/bootstrap |
| backend/.env.example | Local backend env example |
| .gitignore | Root ignore changes |
| .github/workflows/deploy-backend.yml | Backend deploy workflow |
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+21
to
+45
| <Flex align="center" className="gap-x-3.25"> | ||
| <input | ||
| className="relative peer shrink-0 appearance-none w-5 h-5 bg-gray-05 dark:bg-blue-03 border-2 border-blue-01 rounded-sm checked:bg-blue-01 dark:checked:bg-blue-01 checked:border-0 cursor-pointer" | ||
| id={labelId} | ||
| type="checkbox" | ||
| {...rest} | ||
| /> | ||
| <Text | ||
| className="cursor-pointer font-bold select-none dark:text-white" | ||
| htmlFor={labelId} | ||
| tag={'label'} | ||
| > | ||
| {label} | ||
| </Text> | ||
| <svg | ||
| fill="none" | ||
| height="9" | ||
| viewBox="0 0 10 9" | ||
| width="10" | ||
| xmlns="http://www.w3.org/2000/svg" | ||
| className=" | ||
| absolute | ||
| w-3.5 h-3.5 ml-0.5 | ||
| hidden peer-checked:block pointer-events-none" | ||
| > |
Comment on lines
+27
to
+30
| const [isMounted, setIsMounted] = useState(open); | ||
| if (open && !isMounted) { | ||
| setIsMounted(true); | ||
| } |
Comment on lines
+24
to
+31
| const Invoice = (props: IInvoiceProps): JSX.Element => { | ||
| return ( | ||
| <Container> | ||
| <MobileView {...props} /> | ||
| <DesktopView {...props} /> | ||
| </Container> | ||
| ); | ||
| }; |
| ); | ||
| const element = screen.getByTestId(testId); | ||
| expect(element).toBeInTheDocument(); | ||
| expect(element).toHaveTextContent(/\€1 800\,90/); |
Comment on lines
+1
to
+9
| import { render } from '@testing-library/react'; | ||
| import Icon from '@/components/ui/icon/icon'; | ||
|
|
||
| describe('Icon Component', () => { | ||
| it('renders correctly with an icon name passed', () => { | ||
| const { container } = render(<Icon name="dm-moon" />); | ||
| expect(container).toMatchSnapshot(); | ||
| }); | ||
| }); |
Comment on lines
+35
to
+38
| required := []string{ | ||
| "POSTGRES_USER", "POSTGRES_PASSWORD", "POSTGRES_DB", "POSTGRES_HOST", "POSTGRES_PORT", | ||
| "GOOGLE_CLIENT_ID", "GOOGLE_CLIENT_SECRET", | ||
| } |
Comment on lines
+29
to
+36
| const response = await fetch(`${API_URL}${path}`, { | ||
| ...init, | ||
| headers: { | ||
| 'Content-Type': 'application/json', | ||
| ...(token ? { Authorization: `Bearer ${token}` } : {}), | ||
| ...init?.headers, | ||
| }, | ||
| }); |
Comment on lines
+1
to
+25
| interface deviceText { | ||
| desktop: string; | ||
| mobile: string; | ||
| } | ||
|
|
||
| export interface FilterState { | ||
| draft: boolean; | ||
| pending: boolean; | ||
| paid: boolean; | ||
| } | ||
|
|
||
| export interface IInvoiceBarProps { | ||
| invoiceBarTitle: string; | ||
| totalInvoicesText: deviceText; | ||
| filterStatusBtn: deviceText; | ||
| newInvoiceBtn: deviceText; | ||
| newInvoiceHandler: () => void; | ||
| filterStatusText: { | ||
| draft: string; | ||
| pending: string; | ||
| paid: string; | ||
| }; | ||
| filters: FilterState; | ||
| setFilters: (updatedFilters: FilterState) => void; | ||
| } |
Comment on lines
+1
to
+10
| import { ElementType, ReactNode } from 'react'; | ||
|
|
||
| type TextVariants = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'body' | 'body-alt' | 'kicker' | 'custom'; | ||
| export interface ITextProps { | ||
| children: ReactNode; | ||
| className?: string; | ||
| tag?: ElementType; | ||
| variant?: TextVariants; | ||
| htmlFor?: string; | ||
| } |
Comment on lines
+1
to
+13
| export interface IIconProps { | ||
| className?: string; | ||
| name: | ||
| | 'dm-moon' | ||
| | 'dm-sun' | ||
| | 'menu-logo-btn' | ||
| | 'chevron-right' | ||
| | 'chevron-down' | ||
| | 'circle-plus' | ||
| | 'trash' | ||
| | 'google'; | ||
| fill?: string; | ||
| } |
This branch was successfully deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
main has been stale since the very early project scaffolding (Dec 2024, 167 commits behind), never used as a real branch since. This brings it up to date with everything currently on develop, as the first real release.
Going forward: develop stays the working/integration branch, main becomes the release branch. To ship a release, open a PR from develop into main (same as this one) and merge it, same required checks (Lint, Test, Build, Storybook build) apply here as on develop.
Not merging this myself, since cutting main over to become the live Vercel production branch is worth you confirming first.