Skip to content

Commit 3feee60

Browse files
committed
feat: add MIT License and update README with project details
Introduced a new LICENSE file with the MIT License. Updated the README to reflect the project's purpose as a mosque finder app, including features, tech stack, and getting started instructions.
1 parent 05cced6 commit 3feee60

2 files changed

Lines changed: 338 additions & 10 deletions

File tree

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2026 Aqib
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 317 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,328 @@
1-
# shadcn/ui monorepo template
1+
<div align="center">
22

3-
This is a TanStack Start monorepo template with shadcn/ui.
3+
# Qibla
44

5-
## Adding components
5+
**Find your next *salah*, nearby.**
66

7-
To add components to your app, run the following command at the root of your `web` app:
7+
A production-grade mosque finder for iOS, Android, and the web — built as a Bun + Turborepo monorepo with Expo, TanStack Start, oRPC, Drizzle, and Better Auth.
8+
9+
</div>
10+
11+
<!--
12+
v2 additions planned for this hero section:
13+
- Logo / banner (SVG)
14+
- Badges: build status, license, Expo SDK, Node, Bun
15+
- App Store / Play Store / TestFlight links when published
16+
-->
17+
18+
---
19+
20+
## About
21+
22+
Qibla helps working professionals and travellers find a nearby mosque, see accurate prayer times, and get notified before each *salah*. Open the app, see mosques around you on a map, tap a pin for times + directions, or use the live compass to face the *qibla*. An admin panel on the web lets operators curate listings, moderate reviews, and manage mosque events.
23+
24+
Launch market: **Dhaka, Bangladesh**. The architecture works anywhere — prayer times come from the AlAdhan API and mosques are stored in Postgres.
25+
26+
## Features
27+
28+
- **Map-first discovery** — full-bleed Google Maps view with bottom-sheet detail, filters, and directions deep-link
29+
- **Prayer times** — AlAdhan-backed, cached server-side, with next-prayer pill always visible
30+
- **Qibla compass** — traditional rotating-dial UX with magnetometer smoothing and calibration overlay
31+
- **Saved mosques** — optimistic heart toggle with a dedicated grid view
32+
- **Reviews** — write, read, and moderate; ratings recompute server-side
33+
- **Search + filters** — recent searches (SecureStore), popular-nearby sort, 4-way filters (open now / women / parking / jummah)
34+
- **Prayer reminders** — daily local notifications per prayer, auto-rescheduled on open
35+
- **Admin panel** — mosques CRUD, review moderation, users list, dashboard stats
36+
- **Email + password auth** — Better Auth with an admin role plugin and Expo server plugin for native clients
37+
38+
<!--
39+
v2 additions planned for this section:
40+
- Animated GIF of the compass aligning to the qibla
41+
- Screenshot grid: map, mosque detail, prayer times, saved, admin dashboard
42+
- Short demo video link (YouTube / Loom)
43+
-->
44+
45+
## Tech stack
46+
47+
### Mobile (`apps/mobile`)
48+
49+
- **Expo SDK 54** + **Expo Router** (file-based routing)
50+
- **React Native 0.81** on React 19
51+
- **NativeWind v4** (Tailwind CSS for React Native)
52+
- **react-native-maps** (Google Maps on both platforms)
53+
- **@gorhom/bottom-sheet**, **expo-sensors**, **expo-location**, **expo-notifications**, **expo-secure-store**
54+
- **Better Auth** via `@better-auth/expo` + SecureStore session
55+
- **TanStack Query** (server state) + **Zustand** (UI state)
56+
- **oRPC** typed client
57+
58+
### Admin + backend (`apps/admin`)
59+
60+
- **TanStack Start** on **Cloudflare Workers** (Vite + server functions)
61+
- **oRPC** router (same router consumed by the mobile app over HTTP)
62+
- **Drizzle ORM** on **Neon Postgres** via `neon-http`
63+
- **Better Auth** + admin plugin (`admin` | `user` roles)
64+
- **shadcn/ui** components (radix-vega preset)
65+
- **TanStack Router**, **TanStack Table**, **TanStack Form**
66+
67+
### Monorepo tooling
68+
69+
- **Bun 1.3+** workspaces with `linker = "hoisted"` (required for Expo's Babel resolver)
70+
- **Turborepo** for task orchestration + caching
71+
- **Biome** for lint + format
72+
- **TypeScript 5.9** end-to-end
73+
74+
## Project structure
75+
76+
```
77+
qibla/
78+
├── apps/
79+
│ ├── admin/ # TanStack Start on Cloudflare Workers — admin UI + oRPC backend
80+
│ └── mobile/ # Expo app (iOS + Android)
81+
│ └── features/ # Co-located feature modules: components / hooks / lib / index.ts
82+
├── packages/
83+
│ ├── api/ # oRPC router (public / authed / admin procedures)
84+
│ ├── api-client/ # createQiblaClient({ baseURL }) — typed RouterClient
85+
│ ├── auth/ # Better Auth config + Drizzle adapter + admin plugin
86+
│ ├── db/ # Drizzle schema, Neon-HTTP client, Dhaka fixtures seed
87+
│ └── ui/ # shadcn components used by the admin app
88+
├── prd/ # Product docs (overview, architecture, scope, progress)
89+
├── biome.json
90+
├── turbo.json
91+
└── package.json
92+
```
93+
94+
## Prerequisites
95+
96+
| Requirement | Version | Notes |
97+
|---|---|---|
98+
| **Node.js** | `>= 24` | Enforced via `engines` field |
99+
| **Bun** | `>= 1.3` | Package manager + workspace runner |
100+
| **Neon account** || Free tier works; needs a Postgres database |
101+
| **Google Maps API key** || Required for Android; iOS optional (falls back to Apple Maps) |
102+
| **Cloudflare account** || Only needed for deploying the admin app + R2 uploads |
103+
| **EAS account** || Only needed for mobile dev-client / store builds |
104+
| **Mac + physical device on the same Wi-Fi** || Recommended for mobile development |
105+
106+
## Getting started
107+
108+
### 1. Clone and install
109+
110+
```bash
111+
git clone https://github.com/Aqib-Rime/qibla.git
112+
cd qibla
113+
bun install
114+
```
115+
116+
### 2. Configure environment variables
117+
118+
Copy the example file and fill in your own values:
119+
120+
```bash
121+
cp .env.example .env.local
122+
```
123+
124+
The root `.env.local` holds shared values. The admin app additionally reads server-only values from `apps/admin/.dev.vars` (used by Wrangler / Cloudflare Workers in dev).
125+
126+
Create `apps/admin/.dev.vars`:
127+
128+
```bash
129+
DATABASE_URL=postgresql://...
130+
BETTER_AUTH_SECRET=... # openssl rand -base64 32
131+
BETTER_AUTH_URL=http://<your-lan-ip>:3000
132+
```
133+
134+
Create `apps/mobile/.env.local`:
135+
136+
```bash
137+
EXPO_PUBLIC_API_URL=http://<your-lan-ip>:3000
138+
```
139+
140+
> **Why the LAN IP?** The Expo app on your phone talks to the admin Worker over your local network during dev. Find yours with `ipconfig getifaddr en0` on macOS. Better Auth will reject requests from untrusted origins, so this IP must also be in `BETTER_AUTH_TRUSTED_ORIGINS`.
141+
142+
### 3. Set up the database
143+
144+
```bash
145+
bun db:push # push Drizzle schema to Neon
146+
bun db:seed # seed Dhaka mosque fixtures
147+
bun db:studio # optional — browse data
148+
```
149+
150+
### 4. Run the apps
151+
152+
Two terminals:
153+
154+
```bash
155+
# Terminal 1 — admin Worker on http://<lan-ip>:3000
156+
bun run dev:admin
157+
158+
# Terminal 2 — Expo Metro with a dev client
159+
cd apps/mobile && bun run start --clear
160+
```
161+
162+
First time on mobile? You need a dev build before `bun run start` can attach. See **Building the mobile app** below. As a fallback for screens that don't need native plugins:
163+
164+
```bash
165+
cd apps/mobile && bun run start:go --clear
166+
```
167+
168+
> Expo Go does not support `expo-notifications` on SDK 53+ — notifications only work in a dev build.
169+
170+
### 5. Create the first admin
171+
172+
Open `http://<lan-ip>:3000/initial-setup` and create the bootstrap admin account. Subsequent users default to the `user` role and can be promoted from the admin panel.
173+
174+
## Environment variables
175+
176+
The canonical list lives in [`.env.example`](./.env.example). Summary:
177+
178+
| Variable | Used by | Required | Notes |
179+
|---|---|---|---|
180+
| `DATABASE_URL` | admin, db package | Yes | Neon Postgres connection string with `sslmode=require` |
181+
| `BETTER_AUTH_SECRET` | admin | Yes | `openssl rand -base64 32` |
182+
| `BETTER_AUTH_URL` | admin | Yes | Public URL of the admin app (LAN IP in dev) |
183+
| `BETTER_AUTH_TRUSTED_ORIGINS` | admin | Yes | Comma-separated list; include `qibla://` and your LAN IP |
184+
| `EXPO_PUBLIC_API_URL` | mobile | Yes | Same value as `BETTER_AUTH_URL` in dev |
185+
| `GOOGLE_MAPS_API_KEY_ANDROID` | mobile | Yes (Android) | From Google Cloud Console |
186+
| `GOOGLE_MAPS_API_KEY_IOS` | mobile | Optional | Only needed if you want Google Maps on iOS |
187+
| `CLOUDFLARE_ACCOUNT_ID` | admin deploy | Deploy only | `wrangler whoami` |
188+
| `CLOUDFLARE_API_TOKEN` | admin deploy | Deploy only | Scoped token for Workers + R2 |
189+
| `R2_*` | admin | V2 | Photo uploads (see Roadmap) |
190+
191+
## Scripts
192+
193+
Run from the repo root:
8194

9195
```bash
10-
pnpm dlx shadcn@latest add button -c apps/web
196+
bun run dev # run everything in parallel via Turbo
197+
bun run dev:admin # admin only (TanStack Start on Workers)
198+
bun run build # build every app
199+
bun run typecheck # tsc --noEmit across the workspace
200+
bun run lint # biome check
201+
bun run lint:fix # biome check --fix
202+
bun run format # biome format --write
203+
204+
bun db:push # push schema
205+
bun db:generate # generate migrations
206+
bun db:migrate # apply migrations
207+
bun db:studio # Drizzle Studio
208+
bun db:seed # seed Dhaka fixtures
11209
```
12210

13-
This will place the ui components in the `packages/ui/src/components` directory.
211+
Mobile-specific (from `apps/mobile/`):
212+
213+
```bash
214+
bun run start # Metro for dev client
215+
bun run start:go # Metro for Expo Go (limited)
216+
bun run ios # build + launch iOS simulator
217+
bun run android # build + launch Android emulator
218+
bun run prebuild # regenerate native folders
219+
bun run doctor # expo-doctor
220+
```
14221

15-
## Using components
222+
## Building the mobile app (EAS)
16223

17-
To use the components in your app, import them from the `ui` package.
224+
Log in once:
18225

19-
```tsx
20-
import { Button } from "@workspace/ui/components/button";
226+
```bash
227+
cd apps/mobile
228+
bunx eas-cli@latest login
229+
bunx eas-cli@latest init # writes projectId into app.config
21230
```
231+
232+
Available profiles (defined in [`apps/mobile/eas.json`](./apps/mobile/eas.json)):
233+
234+
```bash
235+
bun run build:dev:ios # iOS simulator dev client
236+
bun run build:dev:device # iOS physical device dev client
237+
bun run build:dev:android # Android APK dev client
238+
bun run build:preview # internal distribution build (both platforms)
239+
bun run build:prod # store-ready build (both platforms)
240+
```
241+
242+
Install the dev-client artifact on your device once, then every subsequent run is just `bun run start`.
243+
244+
## Deploying the admin app
245+
246+
The admin app runs on Cloudflare Workers via the TanStack Start Workers adapter.
247+
248+
```bash
249+
cd apps/admin
250+
bun run build
251+
bun run deploy # wraps `wrangler deploy`
252+
```
253+
254+
Before the first deploy:
255+
256+
1. `wrangler login`
257+
2. Create a D1-free Workers project (this app uses Neon, not D1)
258+
3. Mirror your `.dev.vars` into Worker secrets: `wrangler secret put DATABASE_URL`, `BETTER_AUTH_SECRET`, …
259+
4. Update `BETTER_AUTH_URL` + `EXPO_PUBLIC_API_URL` to the production Worker URL
260+
261+
## Roadmap
262+
263+
### Shipped in V1
264+
265+
- Mobile: map, mosque detail, prayer times, qibla compass, saved, reviews, search + filter, profile, settings, prayer reminders, onboarding, email + password auth
266+
- Admin: mosques CRUD, review moderation, users list, dashboard
267+
- Backend: oRPC with public / authed / admin procedures; Neon Postgres via Drizzle; Better Auth
268+
- EAS profiles for dev-client, preview, and production builds
269+
270+
### In progress / pending for V1
271+
272+
- `mosques.nearby` server-side distance filter
273+
- Events admin (`/_admin/events`)
274+
- Mosque photo upload to Cloudflare R2
275+
- Standalone `reviews.mine` endpoint for profile stats
276+
- Google Places search integration
277+
- GitHub Actions CI + first Cloudflare production deploy
278+
279+
### V2 (planned)
280+
281+
- User-submitted mosque listings (`mosque_owner` role)
282+
- Google / phone-OTP sign-in
283+
- Bengali / Arabic localization
284+
- Custom map tiles
285+
- Prayer calculation method settings (currently hardcoded to Karachi + Hanafi)
286+
- **README v2**: logo, screenshots, demo GIF, store links, build-status badges
287+
288+
See [`prd/v1-scope.md`](./prd/v1-scope.md) and [`prd/v2-scope.md`](./prd/v2-scope.md) for the full scope and [`prd/progress.md`](./prd/progress.md) for the live status snapshot.
289+
290+
## Gotchas
291+
292+
A few non-obvious things worth knowing before you dig in (full list in [`prd/progress.md`](./prd/progress.md)):
293+
294+
- **Bun isolated linker breaks Expo's Babel** — keep `linker = "hoisted"` in `bunfig.toml`.
295+
- **NativeWind v4 requires Tailwind v3** — pinned at the workspace root; admin's Tailwind v4 nests inside `apps/admin/node_modules`.
296+
- **NativeWind content glob must include `features/` + `lib/`** — otherwise classes used only inside feature folders silently stop rendering.
297+
- **SDK 54 in a monorepo** needs `autolinkingModuleResolution: true` in `app.config.ts`.
298+
- **Native clients don't send `Origin`** — Better Auth needs `trustedOrigins: ["qibla://", ...]` and the `expo()` server plugin.
299+
- **`vite dev` needs `--host`** for physical-device testing — already configured in `apps/admin/package.json`.
300+
- **`bunx expo install <pkg>` must run from `apps/mobile`** — the root has no Expo SDK.
301+
302+
## Contributing
303+
304+
Contributions are welcome. For anything non-trivial, please open an issue first so we can align on scope.
305+
306+
1. Fork and create a feature branch
307+
2. Run `bun install`
308+
3. Make your changes and keep `bun run typecheck` + `bun run lint` clean
309+
4. Open a PR against `main`
310+
311+
<!--
312+
v2 addition: CONTRIBUTING.md with coding conventions, PR checklist, and release process.
313+
-->
314+
315+
## License
316+
317+
Released under the [MIT License](./LICENSE). See the `LICENSE` file for the full text.
318+
319+
## Acknowledgments
320+
321+
- **AlAdhan API** — prayer time calculations
322+
- **Neon** — serverless Postgres
323+
- **Cloudflare** — Workers, KV, R2
324+
- **Expo** + **TanStack** + **Better Auth** + **oRPC** + **Drizzle** + **shadcn/ui** — the stack that makes this possible
325+
326+
---
327+
328+
Built by [@Aqib-Rime](https://github.com/Aqib-Rime).

0 commit comments

Comments
 (0)