arise.space
subversive resistance ARt
app structure
end-user
main page
you are here
places
browse all places
place detail
view single place
send a place
submission form
CRM
strapi (coming soon)
admin
project architecture
overview
arise.space is a Next.js 15 application built with TypeScript, Tailwind CSS, and shadcn/ui components. it's designed as a v1 prototype with a clean architecture that allows for easy extension - particularly integration with Strapi CMS.
tech stack
- framework: Next.js 15 (App Router)
- language: TypeScript
- styling: Tailwind CSS v4 + shadcn/ui
- forms: react-hook-form + zod validation
- fonts: Space Grotesk + Space Mono
- hosting: Cloudflare Pages
- testing: Vitest + Testing Library
- analytics: Plausible (ready for activation)
file structure
arise-space/
├── app/ # Next.js App Router pages
│ ├── layout.tsx # root layout (header, footer, fonts)
│ ├── page.tsx # main page (you are here)
│ ├── error.tsx # error boundary
│ ├── not-found.tsx # 404 page
│ ├── places/
│ │ ├── page.tsx # places list
│ │ └── [id]/page.tsx # individual place detail
│ └── submit-place/
│ └── page.tsx # submission form
│
├── components/
│ ├── ui/ # shadcn/ui components (button, card, etc.)
│ ├── layout/
│ │ └── header.tsx # navigation header
│ ├── places/
│ │ ├── place-card.tsx # card component for place
│ │ └── place-list.tsx # grid of place cards
│ ├── diagram/
│ │ └── app-diagram.tsx # this block scheme above
│ ├── forms/
│ │ └── submit-place-form.tsx
│ ├── analytics/
│ │ └── plausible.tsx # analytics (activate via env var)
│ └── docs/
│ └── architecture-docs.tsx # this documentation
│
├── services/
│ └── places.ts # data layer abstraction
│
├── types/
│ └── place.ts # TypeScript interfaces
│
├── data/
│ └── mock-places.ts # mock data (9 placeholder places)
│
├── __tests__/ # test files
│ ├── services/ # service layer tests
│ ├── types/ # type definition tests
│ └── data/ # mock data tests
│
└── lib/
└── utils.ts # utility functions (cn helper)data layer abstraction
the services/places.ts file provides a clean abstraction layer. components never call APIs directly - they use these functions:
// services/places.ts getPlaces() → returns all places getPlaceById(id) → returns single place or null submitPlace(data) → submits new place proposal
currently returns mock data. when integrating Strapi, only this file changes - components stay untouched.
future: strapi integration
to connect Strapi CMS:
- set up Strapi with a "Place" content type matching the
Placeinterface - add
STRAPI_URLandSTRAPI_API_TOKENto.env.local - update
services/places.tsto fetch from Strapi API instead of mock data - form submissions will POST to Strapi's content API
analytics setup
Plausible analytics is pre-configured but inactive. to enable:
- create account at plausible.io
- add your domain to Plausible dashboard
- create
.env.localwith:NEXT_PUBLIC_PLAUSIBLE_DOMAIN=arise.space - restart dev server - analytics now active
testing
tests are located in __tests__/ and cover services, types, and data integrity:
npm run test # run all tests npm run test:watch # watch mode npm run test:coverage # with coverage report
available commands
npm run dev # start dev server npm run build # production build npm run lint # run ESLint npm run format # format with Prettier npm run test # run tests npm run pages:build # build for Cloudflare Pages npm run deploy # deploy to Cloudflare Pages