Rebrand from Casera/MyCrib to honeyDue
Total rebrand across Web project: - Package name: casera-web -> honeydue-web - Cookie: casera-token -> honeydue-token - Theme store: casera-theme -> honeydue-theme - File sharing: .casera -> .honeydue, component/function renames - casera-file-handler.tsx -> honeydue-file-handler.tsx - All UI text, metadata, OG tags updated - Domains: casera.treytartt.com -> honeyDue.treytartt.com - Demo data emails updated - All documentation updated Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
# Casera Web (`myCribAPI-Web`)
|
||||
# honeyDue Web (`honeyDueAPI-Web`)
|
||||
|
||||
Next.js web client for the Casera property management platform. Talks to the Go REST API backend.
|
||||
Next.js web client for the honeyDue property management platform. Talks to the Go REST API backend.
|
||||
|
||||
## Build & Run
|
||||
|
||||
@@ -32,10 +32,10 @@ npm run analyze # Bundle analysis
|
||||
```
|
||||
Browser → Next.js page (client component)
|
||||
→ apiFetch("/tasks/") → /api/proxy/tasks (Next.js route handler)
|
||||
→ Go API (reads casera-token httpOnly cookie, forwards as Authorization header)
|
||||
→ Go API (reads honeydue-token httpOnly cookie, forwards as Authorization header)
|
||||
```
|
||||
|
||||
Auth tokens are stored as httpOnly cookies (`casera-token`), never exposed to JS. The Next.js `/api/proxy/[...path]` catch-all route forwards requests to the Go API.
|
||||
Auth tokens are stored as httpOnly cookies (`honeydue-token`), never exposed to JS. The Next.js `/api/proxy/[...path]` catch-all route forwards requests to the Go API.
|
||||
|
||||
### Directory Structure
|
||||
|
||||
@@ -103,7 +103,7 @@ src/
|
||||
|
||||
**Kanban boards**: Tasks display in kanban columns (overdue, due_soon, in_progress, not_started, completed). Uses `@dnd-kit` for drag-and-drop. Column names match Go API: `overdue_tasks`, `due_soon_tasks`, `in_progress_tasks`, `not_started_tasks`, `completed_tasks`.
|
||||
|
||||
**Middleware** (`src/middleware.ts`): Checks `casera-token` cookie. Redirects unauthenticated users to `/login` for protected routes. Skips API routes, static files, and public paths.
|
||||
**Middleware** (`src/middleware.ts`): Checks `honeydue-token` cookie. Redirects unauthenticated users to `/login` for protected routes. Skips API routes, static files, and public paths.
|
||||
|
||||
## Conventions
|
||||
|
||||
@@ -123,7 +123,7 @@ src/
|
||||
|
||||
| Variable | Description | Default |
|
||||
|----------|-------------|---------|
|
||||
| `NEXT_PUBLIC_API_URL` | Go API URL (client-side) | `https://casera.treytartt.com/api` |
|
||||
| `NEXT_PUBLIC_API_URL` | Go API URL (client-side) | `https://honeyDue.treytartt.com/api` |
|
||||
| `API_URL` | Go API URL (server-side, no proxy) | Falls back to `NEXT_PUBLIC_API_URL` |
|
||||
| `NEXT_PUBLIC_POSTHOG_KEY` | PostHog analytics key | — |
|
||||
| `NEXT_PUBLIC_POSTHOG_HOST` | PostHog host | — |
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
# Casera Web App
|
||||
# honeyDue Web App
|
||||
|
||||
Next.js web client for the Casera property management platform. Connects to the [Go REST API](https://github.com/akatreyt/casera-api) backend.
|
||||
Next.js web client for the honeyDue property management platform. Connects to the [Go REST API](https://github.com/akatreyt/honeydue-api) backend.
|
||||
|
||||
## Features
|
||||
|
||||
@@ -50,7 +50,7 @@ Open [http://localhost:3000](http://localhost:3000).
|
||||
|
||||
| Variable | Description | Required |
|
||||
|----------|-------------|----------|
|
||||
| `NEXT_PUBLIC_API_URL` | Go API base URL (e.g. `https://casera.treytartt.com/api`) | Yes |
|
||||
| `NEXT_PUBLIC_API_URL` | Go API base URL (e.g. `https://honeyDue.treytartt.com/api`) | Yes |
|
||||
| `API_URL` | Server-side API URL (defaults to `NEXT_PUBLIC_API_URL`) | No |
|
||||
| `NEXT_PUBLIC_POSTHOG_KEY` | PostHog project API key | No |
|
||||
| `NEXT_PUBLIC_POSTHOG_HOST` | PostHog instance URL | No |
|
||||
|
||||
+5
-5
@@ -1,8 +1,8 @@
|
||||
# Casera Web App — Build Plan Overview
|
||||
# honeyDue Web App — Build Plan Overview
|
||||
|
||||
## What We're Building
|
||||
|
||||
Full parity web app for Casera: **46 screens**, **104 API operations**, **4 domains** (Residences, Tasks, Contractors, Documents), plus auth, onboarding, subscriptions, settings, and a **sandboxed demo mode** with mock data.
|
||||
Full parity web app for honeyDue: **46 screens**, **104 API operations**, **4 domains** (Residences, Tasks, Contractors, Documents), plus auth, onboarding, subscriptions, settings, and a **sandboxed demo mode** with mock data.
|
||||
|
||||
## Tech Stack
|
||||
|
||||
@@ -33,7 +33,7 @@ Full parity web app for Casera: **46 screens**, **104 API operations**, **4 doma
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
myCribAPI-Web/
|
||||
honeyDueAPI-Web/
|
||||
├── src/
|
||||
│ ├── app/ # Next.js App Router
|
||||
│ │ ├── (marketing)/ # Public pages (landing, pricing)
|
||||
@@ -86,7 +86,7 @@ myCribAPI-Web/
|
||||
|---|---|
|
||||
| Push notifications | Not needed (no push API for web in scope) |
|
||||
| Widgets | Not applicable |
|
||||
| .casera file import/export | File download (export) + drag-and-drop or file picker (import) |
|
||||
| .honeydue file import/export | File download (export) + drag-and-drop or file picker (import) |
|
||||
| Apple/Google Sign In | OAuth redirect flow (same backend endpoints) |
|
||||
| StoreKit subscription | Stripe Checkout or link to App Store (TBD) |
|
||||
| Camera capture | File upload input (no camera API needed) |
|
||||
@@ -112,4 +112,4 @@ myCribAPI-Web/
|
||||
| Demo mode data isolation | No backend calls, purely client-side, session-scoped store, no persistence |
|
||||
| API compatibility | 100% same endpoints, same token format (`Token <hex>`), same request/response shapes |
|
||||
| Mobile feature gaps | Push notifications and widgets explicitly excluded. Everything else covered. |
|
||||
| Deployment independence | Separate Dokku app, own domain (e.g., `app.casera.treytartt.com`), no coupling to Go API deployment |
|
||||
| Deployment independence | Separate Dokku app, own domain (e.g., `app.honeydue.treytartt.com`), no coupling to Go API deployment |
|
||||
|
||||
@@ -18,8 +18,8 @@ Scaffold the project, wire up auth, build the app shell, and establish the desig
|
||||
## 1. Project Scaffold
|
||||
|
||||
```bash
|
||||
npx create-next-app@latest myCribAPI-Web --typescript --tailwind --eslint --app --src-dir
|
||||
cd myCribAPI-Web
|
||||
npx create-next-app@latest honeyDueAPI-Web --typescript --tailwind --eslint --app --src-dir
|
||||
cd honeyDueAPI-Web
|
||||
npx shadcn@latest init
|
||||
```
|
||||
|
||||
@@ -33,9 +33,9 @@ npm install -D vitest @playwright/test
|
||||
## 2. TypeScript Types
|
||||
|
||||
Generate TypeScript types matching the Go API DTOs. Source from:
|
||||
- `myCribAPI-go/internal/dto/requests/` — request shapes
|
||||
- `myCribAPI-go/internal/dto/responses/` — response shapes
|
||||
- `myCribAPI-go/internal/models/` — entity shapes
|
||||
- `honeyDueAPI-go/internal/dto/requests/` — request shapes
|
||||
- `honeyDueAPI-go/internal/dto/responses/` — response shapes
|
||||
- `honeyDueAPI-go/internal/models/` — entity shapes
|
||||
|
||||
Key types to define in `src/lib/types/`:
|
||||
|
||||
@@ -73,7 +73,7 @@ api/
|
||||
|
||||
```typescript
|
||||
// src/lib/api/client.ts
|
||||
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'https://mycrib.treytartt.com/api';
|
||||
const API_BASE_URL = process.env.NEXT_PUBLIC_API_URL || 'https://honeyDue.treytartt.com/api';
|
||||
|
||||
async function apiFetch<T>(
|
||||
path: string,
|
||||
@@ -225,7 +225,7 @@ Match the mobile app's theme system:
|
||||
| Desert | TBD | TBD |
|
||||
| Mint | TBD | TBD |
|
||||
|
||||
Theme values sourced from `MyCribKMM/composeApp/src/commonMain/.../ui/theme/ThemeColors.kt`.
|
||||
Theme values sourced from `HoneyDueKMM/composeApp/src/commonMain/.../ui/theme/ThemeColors.kt`.
|
||||
|
||||
### Spacing
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ Build sharing, subscriptions, notifications, profile, onboarding, and summary me
|
||||
|
||||
## Checklist
|
||||
|
||||
- [ ] Residence sharing: generate/display share code, join residence, manage users, .casera file export/import
|
||||
- [ ] Contractor sharing: .casera file export/import
|
||||
- [ ] Residence sharing: generate/display share code, join residence, manage users, .honeydue file export/import
|
||||
- [ ] Contractor sharing: .honeydue file export/import
|
||||
- [ ] Subscription: status display, feature comparison, upgrade prompt, usage tracking
|
||||
- [ ] Notification preferences: toggle + time picker per notification type
|
||||
- [ ] Profile: edit name/email, change password, delete account
|
||||
@@ -22,7 +22,7 @@ Build sharing, subscriptions, notifications, profile, onboarding, and summary me
|
||||
| Route | Screen | Description |
|
||||
|-------|--------|-------------|
|
||||
| `/app/residences/[id]/share` | Share Residence | Generate/display share code, manage users |
|
||||
| `/app/residences/join` | Join Residence | Enter share code or import .casera file |
|
||||
| `/app/residences/join` | Join Residence | Enter share code or import .honeydue file |
|
||||
|
||||
### Share Code Flow
|
||||
|
||||
@@ -35,15 +35,15 @@ Owner opens Share screen
|
||||
|
||||
Invitee opens Join screen
|
||||
→ Enter share code manually, OR
|
||||
→ Upload .casera file (drag-and-drop zone)
|
||||
→ Upload .honeydue file (drag-and-drop zone)
|
||||
→ POST /api/residences/join/ { code: "ABC123" }
|
||||
→ On success: redirect to residence detail
|
||||
```
|
||||
|
||||
### .casera File Handling
|
||||
### .honeydue File Handling
|
||||
|
||||
**Export** (owner):
|
||||
- Button on residence detail: "Export as .casera"
|
||||
- Button on residence detail: "Export as .honeydue"
|
||||
- Generates JSON file with `{ type: "residence", code: "ABC123", ... }`
|
||||
- Browser downloads the file
|
||||
|
||||
@@ -73,7 +73,7 @@ Invitee opens Join screen
|
||||
|
||||
## 2. Contractor Sharing
|
||||
|
||||
### .casera File Export/Import
|
||||
### .honeydue File Export/Import
|
||||
|
||||
**Export**:
|
||||
- Button on contractor detail: "Share Contractor"
|
||||
@@ -82,7 +82,7 @@ Invitee opens Join screen
|
||||
|
||||
**Import**:
|
||||
- Button on contractor list: "Import Contractor"
|
||||
- File picker or drag-and-drop for .casera file
|
||||
- File picker or drag-and-drop for .honeydue file
|
||||
- Read JSON, show confirmation dialog, create contractor
|
||||
- `POST /api/contractors/import/`
|
||||
|
||||
@@ -123,7 +123,7 @@ Check tier limits before allowing creation:
|
||||
### Upgrade Path (Phase 1)
|
||||
|
||||
Web users are directed to the mobile app for purchases:
|
||||
- "Download Casera on the App Store to upgrade"
|
||||
- "Download honeyDue on the App Store to upgrade"
|
||||
- Link to App Store listing
|
||||
|
||||
### Upgrade Path (Future — Phase 2)
|
||||
@@ -215,7 +215,7 @@ Add Stripe Checkout for web-only subscription purchases. Requires backend work t
|
||||
|
||||
```
|
||||
Step 1: Welcome
|
||||
→ "Welcome to Casera! Let's set up your first property."
|
||||
→ "Welcome to honeyDue! Let's set up your first property."
|
||||
|
||||
Step 2: Choose Path
|
||||
→ "Create a new residence" OR "Join an existing residence"
|
||||
@@ -300,7 +300,7 @@ Data sources:
|
||||
|
||||
At the end of Phase 3, you should have:
|
||||
1. Residence sharing with code generation, join flow, and user management
|
||||
2. Contractor sharing via .casera files
|
||||
2. Contractor sharing via .honeydue files
|
||||
3. Subscription status with tier limits and upgrade prompts
|
||||
4. Notification preferences with toggles
|
||||
5. Profile editing (name, email, password, delete account)
|
||||
|
||||
@@ -261,7 +261,7 @@ Persistent banner at the top of the demo app:
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────────────────────────┐
|
||||
│ 🎯 You're exploring Casera in demo mode. [Sign Up Free] │
|
||||
│ 🎯 You're exploring honeyDue in demo mode. [Sign Up Free] │
|
||||
│ Changes aren't saved. Create an account to get started! │
|
||||
└─────────────────────────────────────────────────────────────────┘
|
||||
```
|
||||
@@ -282,7 +282,7 @@ Before entering the demo, show a brief preview page:
|
||||
```
|
||||
┌─────────────────────────────────────────────────────┐
|
||||
│ │
|
||||
│ 🏠 Try Casera — No Account Needed │
|
||||
│ 🏠 Try honeyDue — No Account Needed │
|
||||
│ │
|
||||
│ Manage your home maintenance, track tasks, │
|
||||
│ organize contractors, and store documents. │
|
||||
|
||||
+11
-11
@@ -162,7 +162,7 @@ const nextConfig = {
|
||||
output: 'standalone', // Required for Docker
|
||||
images: {
|
||||
remotePatterns: [
|
||||
{ protocol: 'https', hostname: 'mycrib.treytartt.com' }, // API media
|
||||
{ protocol: 'https', hostname: 'honeyDue.treytartt.com' }, // API media
|
||||
],
|
||||
},
|
||||
};
|
||||
@@ -171,14 +171,14 @@ const nextConfig = {
|
||||
### Dokku Deployment
|
||||
|
||||
```bash
|
||||
# On mycribDev server
|
||||
dokku apps:create casera-web
|
||||
dokku domains:add casera-web app.casera.treytartt.com
|
||||
dokku config:set casera-web NEXT_PUBLIC_API_URL=https://mycrib.treytartt.com/api
|
||||
dokku letsencrypt:enable casera-web
|
||||
# On honeyDueDev server
|
||||
dokku apps:create honeydue-web
|
||||
dokku domains:add honeydue-web app.honeyDue.treytartt.com
|
||||
dokku config:set honeydue-web NEXT_PUBLIC_API_URL=https://honeyDue.treytartt.com/api
|
||||
dokku letsencrypt:enable honeydue-web
|
||||
|
||||
# Deploy
|
||||
git remote add dokku-web dokku@mycribDev:casera-web
|
||||
git remote add dokku-web dokku@honeyDueDev:honeydue-web
|
||||
git push dokku-web main
|
||||
```
|
||||
|
||||
@@ -316,17 +316,17 @@ Marketing and demo pages need proper meta tags:
|
||||
```typescript
|
||||
// src/app/(marketing)/page.tsx
|
||||
export const metadata: Metadata = {
|
||||
title: 'Casera — Home Maintenance Made Simple',
|
||||
title: 'honeyDue — Home Maintenance Made Simple',
|
||||
description: 'Track tasks, organize contractors, store documents. Manage your home maintenance in one place.',
|
||||
openGraph: {
|
||||
title: 'Casera — Home Maintenance Made Simple',
|
||||
title: 'honeyDue — Home Maintenance Made Simple',
|
||||
description: 'Track tasks, organize contractors, store documents.',
|
||||
images: ['/og-image.png'],
|
||||
type: 'website',
|
||||
},
|
||||
twitter: {
|
||||
card: 'summary_large_image',
|
||||
title: 'Casera',
|
||||
title: 'honeyDue',
|
||||
description: 'Home Maintenance Made Simple',
|
||||
images: ['/og-image.png'],
|
||||
},
|
||||
@@ -391,7 +391,7 @@ Track same events as mobile app for consistent analytics.
|
||||
At the end of Phase 5, you should have:
|
||||
1. Fully responsive web app (mobile, tablet, desktop)
|
||||
2. Consistent loading, empty, and error states everywhere
|
||||
3. Deployed on Dokku at `app.casera.treytartt.com`
|
||||
3. Deployed on Dokku at `app.honeyDue.treytartt.com`
|
||||
4. E2E tests covering auth, CRUD, demo mode, and responsive viewports
|
||||
5. Optimized bundle with code splitting and image optimization
|
||||
6. SEO-ready marketing and demo pages
|
||||
|
||||
@@ -56,7 +56,7 @@ Task 6: Integration + Verification (sequential — cross-domain wiring)
|
||||
### Step 1: Install missing shadcn components and @dnd-kit
|
||||
|
||||
```bash
|
||||
cd myCribAPI-Web
|
||||
cd honeyDueAPI-Web
|
||||
npx shadcn@latest add dialog select textarea tabs skeleton tooltip popover calendar
|
||||
npm install @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities date-fns
|
||||
```
|
||||
@@ -688,7 +688,7 @@ export * from './use-documents';
|
||||
### Step 14: Verify build
|
||||
|
||||
```bash
|
||||
cd myCribAPI-Web && npm run build
|
||||
cd honeyDueAPI-Web && npm run build
|
||||
```
|
||||
|
||||
Expected: Build succeeds with no type errors.
|
||||
@@ -1253,7 +1253,7 @@ export default function EditResidencePage({
|
||||
### Step 9: Verify build
|
||||
|
||||
```bash
|
||||
cd myCribAPI-Web && npm run build
|
||||
cd honeyDueAPI-Web && npm run build
|
||||
```
|
||||
|
||||
Expected: Build succeeds. All 4 residence routes render.
|
||||
@@ -2198,7 +2198,7 @@ export default function TaskDetailPage({
|
||||
### Step 11: Verify build
|
||||
|
||||
```bash
|
||||
cd myCribAPI-Web && npm run build
|
||||
cd honeyDueAPI-Web && npm run build
|
||||
```
|
||||
|
||||
### Step 12: Commit
|
||||
@@ -2282,7 +2282,7 @@ Follow the same patterns as Residences (Task 2). Key differences:
|
||||
### Step 9: Verify build
|
||||
|
||||
```bash
|
||||
cd myCribAPI-Web && npm run build
|
||||
cd honeyDueAPI-Web && npm run build
|
||||
```
|
||||
|
||||
### Step 10: Commit
|
||||
@@ -2363,7 +2363,7 @@ Key differences from other domains:
|
||||
### Step 9: Verify build
|
||||
|
||||
```bash
|
||||
cd myCribAPI-Web && npm run build
|
||||
cd honeyDueAPI-Web && npm run build
|
||||
```
|
||||
|
||||
### Step 10: Commit
|
||||
@@ -2442,7 +2442,7 @@ export default function DashboardPage() {
|
||||
### Step 2: Full build verification
|
||||
|
||||
```bash
|
||||
cd myCribAPI-Web && npm run build
|
||||
cd honeyDueAPI-Web && npm run build
|
||||
```
|
||||
|
||||
Expected: Build succeeds. All routes compile. No type errors.
|
||||
|
||||
@@ -42,7 +42,7 @@ Task 7: Integration + Verification (sequential — cross-feature wiring)
|
||||
### Step 1: Install Recharts
|
||||
|
||||
```bash
|
||||
cd /Users/treyt/Desktop/code/MyCrib/myCribAPI-Web
|
||||
cd /Users/treyt/Desktop/code/HoneyDue/honeyDueAPI-Web
|
||||
npm install recharts
|
||||
```
|
||||
|
||||
@@ -282,7 +282,7 @@ export * from './use-subscription';
|
||||
### Step 9: Verify build
|
||||
|
||||
```bash
|
||||
cd /Users/treyt/Desktop/code/MyCrib/myCribAPI-Web && npm run build
|
||||
cd /Users/treyt/Desktop/code/HoneyDue/honeyDueAPI-Web && npm run build
|
||||
```
|
||||
|
||||
### Step 10: Commit
|
||||
@@ -302,7 +302,7 @@ git add -A && git commit -m "feat: add Phase 3 foundation — notification hooks
|
||||
- Create: `src/app/app/residences/join/page.tsx`
|
||||
- Create: `src/components/sharing/share-code-display.tsx`
|
||||
- Create: `src/components/sharing/user-management.tsx`
|
||||
- Create: `src/components/sharing/casera-file-handler.tsx`
|
||||
- Create: `src/components/sharing/honeydue-file-handler.tsx`
|
||||
- Create: `src/lib/hooks/use-sharing.ts`
|
||||
- Modify: `src/app/app/residences/[id]/page.tsx` (add Share button)
|
||||
- Modify: `src/app/app/contractors/[id]/page.tsx` (add Share/Export button)
|
||||
@@ -320,11 +320,11 @@ git add -A && git commit -m "feat: add Phase 3 foundation — notification hooks
|
||||
- Each user row: name, email, role badge (Owner/Member)
|
||||
- Owner can click "Remove" → ConfirmDialog → `residencesApi.removeResidenceUser(residenceId, userId)`
|
||||
|
||||
### .casera File Handler
|
||||
### .honeydue File Handler
|
||||
|
||||
**casera-file-handler.tsx** — Reusable component for both residence and contractor sharing:
|
||||
- **Export mode**: Takes data object, generates JSON `{ type: "residence"|"contractor", ... }`, triggers browser download as `.casera` file
|
||||
- **Import mode**: FileUpload drop zone accepting `.casera` files, reads JSON, validates type, calls callback with parsed data
|
||||
**honeydue-file-handler.tsx** — Reusable component for both residence and contractor sharing:
|
||||
- **Export mode**: Takes data object, generates JSON `{ type: "residence"|"contractor", ... }`, triggers browser download as `.honeydue` file
|
||||
- **Import mode**: FileUpload drop zone accepting `.honeydue` files, reads JSON, validates type, calls callback with parsed data
|
||||
- Uses `URL.createObjectURL` + anchor click for download
|
||||
- Uses `FileReader.readAsText` for import
|
||||
|
||||
@@ -332,19 +332,19 @@ git add -A && git commit -m "feat: add Phase 3 foundation — notification hooks
|
||||
|
||||
**Residence Share page** (`/app/residences/[id]/share`):
|
||||
- ShareCodeDisplay for generating/displaying share codes
|
||||
- .casera export button → downloads file with share code embedded
|
||||
- .honeydue export button → downloads file with share code embedded
|
||||
- UserManagement table
|
||||
- Only accessible to residence owner
|
||||
|
||||
**Residence Join page** (`/app/residences/join`):
|
||||
- Text input for manual code entry
|
||||
- .casera file import drop zone
|
||||
- .honeydue file import drop zone
|
||||
- On submit: calls `residencesApi.joinWithCode()` → redirect to residence detail
|
||||
|
||||
### Contractor Sharing
|
||||
|
||||
On contractor detail page, add "Share" button → generates .casera file with contractor data for download.
|
||||
On contractor list page, add "Import" button → opens import dialog → reads .casera file → creates contractor via API.
|
||||
On contractor detail page, add "Share" button → generates .honeydue file with contractor data for download.
|
||||
On contractor list page, add "Import" button → opens import dialog → reads .honeydue file → creates contractor via API.
|
||||
|
||||
### Query hooks
|
||||
|
||||
@@ -405,13 +405,13 @@ export function useJoinResidence() {
|
||||
### Verify build
|
||||
|
||||
```bash
|
||||
cd /Users/treyt/Desktop/code/MyCrib/myCribAPI-Web && npm run build
|
||||
cd /Users/treyt/Desktop/code/HoneyDue/honeyDueAPI-Web && npm run build
|
||||
```
|
||||
|
||||
### Commit
|
||||
|
||||
```bash
|
||||
git add -A && git commit -m "feat: add residence sharing (share code, join, user management) and contractor .casera export/import"
|
||||
git add -A && git commit -m "feat: add residence sharing (share code, join, user management) and contractor .honeydue export/import"
|
||||
```
|
||||
|
||||
---
|
||||
@@ -489,7 +489,7 @@ export async function deleteAccount(): Promise<MessageResponse> {
|
||||
### Verify build
|
||||
|
||||
```bash
|
||||
cd /Users/treyt/Desktop/code/MyCrib/myCribAPI-Web && npm run build
|
||||
cd /Users/treyt/Desktop/code/HoneyDue/honeyDueAPI-Web && npm run build
|
||||
```
|
||||
|
||||
### Commit
|
||||
@@ -560,7 +560,7 @@ npx shadcn@latest add switch
|
||||
### Verify build
|
||||
|
||||
```bash
|
||||
cd /Users/treyt/Desktop/code/MyCrib/myCribAPI-Web && npm run build
|
||||
cd /Users/treyt/Desktop/code/HoneyDue/honeyDueAPI-Web && npm run build
|
||||
```
|
||||
|
||||
### Commit
|
||||
@@ -623,11 +623,11 @@ export const useOnboardingStore = create<OnboardingState>()((set) => ({
|
||||
|
||||
- Clean, centered layout (no sidebar or app shell)
|
||||
- Progress indicator (step dots or progress bar)
|
||||
- Casera logo at top
|
||||
- honeyDue logo at top
|
||||
|
||||
### Steps
|
||||
|
||||
**Step 0: Welcome** — "Welcome to Casera!" message, illustration, "Get Started" button
|
||||
**Step 0: Welcome** — "Welcome to honeyDue!" message, illustration, "Get Started" button
|
||||
|
||||
**Step 1: Choose Path** — Two cards: "Create a new residence" (House icon) and "Join an existing residence" (Users icon). Clicking sets path and advances.
|
||||
|
||||
@@ -637,7 +637,7 @@ export const useOnboardingStore = create<OnboardingState>()((set) => ({
|
||||
- **Step 4a: Complete** — "You're all set!" Redirect to `/app/residences/${id}`
|
||||
|
||||
**Path B — Join:**
|
||||
- **Step 2b: Join Residence** — Code input (6-char) or .casera file import. On submit: joins via API, advances.
|
||||
- **Step 2b: Join Residence** — Code input (6-char) or .honeydue file import. On submit: joins via API, advances.
|
||||
- **Step 3b: Complete** — "Welcome to the residence!" Redirect to residence detail.
|
||||
|
||||
### Onboarding trigger
|
||||
@@ -649,7 +649,7 @@ For now, just mark `localStorage.setItem('onboarding_complete', 'true')` after c
|
||||
### Verify build
|
||||
|
||||
```bash
|
||||
cd /Users/treyt/Desktop/code/MyCrib/myCribAPI-Web && npm run build
|
||||
cd /Users/treyt/Desktop/code/HoneyDue/honeyDueAPI-Web && npm run build
|
||||
```
|
||||
|
||||
### Commit
|
||||
@@ -714,7 +714,7 @@ On residence detail page (`src/app/app/residences/[id]/page.tsx`), add a "Downlo
|
||||
### Verify build
|
||||
|
||||
```bash
|
||||
cd /Users/treyt/Desktop/code/MyCrib/myCribAPI-Web && npm run build
|
||||
cd /Users/treyt/Desktop/code/HoneyDue/honeyDueAPI-Web && npm run build
|
||||
```
|
||||
|
||||
### Commit
|
||||
@@ -732,7 +732,7 @@ git add -A && git commit -m "feat: add enhanced dashboard with charts and task r
|
||||
### Step 1: Full build verification
|
||||
|
||||
```bash
|
||||
cd /Users/treyt/Desktop/code/MyCrib/myCribAPI-Web && npm run build
|
||||
cd /Users/treyt/Desktop/code/HoneyDue/honeyDueAPI-Web && npm run build
|
||||
```
|
||||
|
||||
### Step 2: Route verification
|
||||
@@ -766,8 +766,8 @@ git add -A && git commit -m "feat: complete Phase 3 — advanced features integr
|
||||
At the end of Phase 3, verify:
|
||||
|
||||
- [ ] **Residence sharing**: generate share code, copy, join with code, manage users (list/remove)
|
||||
- [ ] **Contractor sharing**: .casera file export from detail, import on list page
|
||||
- [ ] **.casera files**: download as JSON, import via drag-and-drop
|
||||
- [ ] **Contractor sharing**: .honeydue file export from detail, import on list page
|
||||
- [ ] **.honeydue files**: download as JSON, import via drag-and-drop
|
||||
- [ ] **Subscription**: status display with usage bars, feature comparison table, upgrade CTA
|
||||
- [ ] **Feature gating**: upgrade prompt dialog available for tier limit enforcement
|
||||
- [ ] **Notification preferences**: toggle switches per notification type, saves immediately
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@ const nextConfig: NextConfig = {
|
||||
remotePatterns: [
|
||||
{
|
||||
protocol: "https",
|
||||
hostname: "casera.treytartt.com",
|
||||
hostname: "honeyDue.treytartt.com",
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
Generated
+2
-2
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "casera-web",
|
||||
"name": "honeydue-web",
|
||||
"version": "0.1.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "casera-web",
|
||||
"name": "honeydue-web",
|
||||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@dnd-kit/core": "^6.3.1",
|
||||
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"name": "casera-web",
|
||||
"name": "honeydue-web",
|
||||
"version": "0.1.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
|
||||
@@ -26,13 +26,13 @@ export default function AuthLayout({ children }: { children: React.ReactNode })
|
||||
<Link href="/" className="flex items-center gap-2.5">
|
||||
<Image
|
||||
src="/logo.png"
|
||||
alt="Casera"
|
||||
alt="honeyDue"
|
||||
width={36}
|
||||
height={36}
|
||||
className="rounded-lg"
|
||||
/>
|
||||
<span className="font-heading text-xl font-bold text-white">
|
||||
Casera
|
||||
honeyDue
|
||||
</span>
|
||||
</Link>
|
||||
</div>
|
||||
@@ -49,7 +49,7 @@ export default function AuthLayout({ children }: { children: React.ReactNode })
|
||||
</div>
|
||||
|
||||
<p className="relative text-xs text-[#8A8F87]">
|
||||
© {new Date().getFullYear()} Casera
|
||||
© {new Date().getFullYear()} honeyDue
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ export default function RegisterPage() {
|
||||
return (
|
||||
<AuthFormWrapper
|
||||
title="Create account"
|
||||
subtitle="Get started with Casera"
|
||||
subtitle="Get started with honeyDue"
|
||||
footer={
|
||||
<p>
|
||||
Already have an account?{" "}
|
||||
|
||||
@@ -11,9 +11,9 @@ import { NextRequest, NextResponse } from 'next/server';
|
||||
const API_BASE_URL =
|
||||
process.env.API_URL ||
|
||||
process.env.NEXT_PUBLIC_API_URL ||
|
||||
'https://casera.treytartt.com/api';
|
||||
'https://honeyDue.treytartt.com/api';
|
||||
|
||||
const COOKIE_NAME = 'casera-token';
|
||||
const COOKIE_NAME = 'honeydue-token';
|
||||
const COOKIE_MAX_AGE = 60 * 60 * 24 * 30; // 30 days
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
|
||||
@@ -11,9 +11,9 @@ import { NextRequest, NextResponse } from 'next/server';
|
||||
const API_BASE_URL =
|
||||
process.env.API_URL ||
|
||||
process.env.NEXT_PUBLIC_API_URL ||
|
||||
'https://casera.treytartt.com/api';
|
||||
'https://honeyDue.treytartt.com/api';
|
||||
|
||||
const COOKIE_NAME = 'casera-token';
|
||||
const COOKIE_NAME = 'honeydue-token';
|
||||
|
||||
export async function POST(request: NextRequest) {
|
||||
try {
|
||||
|
||||
@@ -11,9 +11,9 @@ import { NextRequest, NextResponse } from 'next/server';
|
||||
const API_BASE_URL =
|
||||
process.env.API_URL ||
|
||||
process.env.NEXT_PUBLIC_API_URL ||
|
||||
'https://casera.treytartt.com/api';
|
||||
'https://honeyDue.treytartt.com/api';
|
||||
|
||||
const COOKIE_NAME = 'casera-token';
|
||||
const COOKIE_NAME = 'honeydue-token';
|
||||
|
||||
export async function GET(_request: NextRequest) {
|
||||
try {
|
||||
|
||||
@@ -5,18 +5,18 @@ import { NextRequest, NextResponse } from 'next/server';
|
||||
// Catch-all proxy route handler
|
||||
// ---------------------------------------------------------------------------
|
||||
// Every authenticated client-side API call goes through this proxy.
|
||||
// It reads the `casera-token` httpOnly cookie and forwards the request to the
|
||||
// It reads the `honeydue-token` httpOnly cookie and forwards the request to the
|
||||
// Go API with an Authorization header.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const API_BASE_URL =
|
||||
process.env.API_URL ||
|
||||
process.env.NEXT_PUBLIC_API_URL ||
|
||||
'https://casera.treytartt.com/api';
|
||||
'https://honeyDue.treytartt.com/api';
|
||||
|
||||
/**
|
||||
* Build the target URL from the catch-all path segments.
|
||||
* e.g. /api/proxy/tasks/123/ -> https://casera.treytartt.com/api/tasks/123/
|
||||
* e.g. /api/proxy/tasks/123/ -> https://honeyDue.treytartt.com/api/tasks/123/
|
||||
*/
|
||||
function buildTargetUrl(request: NextRequest, pathSegments: string[]): string {
|
||||
const path = `/${pathSegments.join('/')}`;
|
||||
@@ -53,7 +53,7 @@ async function buildHeaders(request: NextRequest): Promise<Headers> {
|
||||
|
||||
// Attach auth token from httpOnly cookie
|
||||
const cookieStore = await cookies();
|
||||
const token = cookieStore.get('casera-token')?.value;
|
||||
const token = cookieStore.get('honeydue-token')?.value;
|
||||
if (token) {
|
||||
headers.set('Authorization', `Token ${token}`);
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import { LoadingSkeleton } from "@/components/shared/loading-skeleton";
|
||||
import { ErrorBanner } from "@/components/shared/error-banner";
|
||||
import { ConfirmDialog } from "@/components/shared/confirm-dialog";
|
||||
import { StarRating } from "@/components/shared/star-rating";
|
||||
import { downloadCaseraFile } from "@/components/sharing/casera-file-handler";
|
||||
import { downloadHoneyDueFile } from "@/components/sharing/honeydue-file-handler";
|
||||
import {
|
||||
useContractor,
|
||||
useContractorTasks,
|
||||
@@ -88,7 +88,7 @@ export default function ContractorDetailPage({
|
||||
size="sm"
|
||||
onClick={() => {
|
||||
const exportData = {
|
||||
type: "casera_contractor_share",
|
||||
type: "honeydue_contractor_share",
|
||||
version: 1,
|
||||
contractor: {
|
||||
name: contractor.name,
|
||||
@@ -107,7 +107,7 @@ export default function ContractorDetailPage({
|
||||
exported_at: new Date().toISOString(),
|
||||
};
|
||||
const safeName = contractor.name.replace(/[^a-zA-Z0-9_-]/g, "_").toLowerCase();
|
||||
downloadCaseraFile(exportData, `${safeName}-contractor`);
|
||||
downloadHoneyDueFile(exportData, `${safeName}-contractor`);
|
||||
}}
|
||||
>
|
||||
<FileDown className="size-4 mr-2" />
|
||||
|
||||
@@ -11,7 +11,7 @@ import { PageHeader } from "@/components/shared/page-header";
|
||||
import { LoadingSkeleton } from "@/components/shared/loading-skeleton";
|
||||
import { ErrorBanner } from "@/components/shared/error-banner";
|
||||
import { EmptyState } from "@/components/shared/empty-state";
|
||||
import { CaseraFileImport } from "@/components/sharing/casera-file-handler";
|
||||
import { HoneyDueFileImport } from "@/components/sharing/honeydue-file-handler";
|
||||
import { ContractorCard } from "@/components/contractors/contractor-card";
|
||||
import { ContractorFilters } from "@/components/contractors/contractor-filters";
|
||||
import { useContractors, useToggleFavorite, useCreateContractor } from "@/lib/hooks/use-contractors";
|
||||
@@ -66,7 +66,7 @@ export default function ContractorsPage() {
|
||||
typeof data === "object" &&
|
||||
data !== null &&
|
||||
"type" in data &&
|
||||
(data as Record<string, unknown>).type === "casera_contractor_share" &&
|
||||
(data as Record<string, unknown>).type === "honeydue_contractor_share" &&
|
||||
"contractor" in data
|
||||
) {
|
||||
const contractor = (data as Record<string, unknown>).contractor as Record<string, unknown>;
|
||||
@@ -97,7 +97,7 @@ export default function ContractorsPage() {
|
||||
},
|
||||
);
|
||||
} else {
|
||||
setImportError("Invalid .casera file. Expected a contractor share file.");
|
||||
setImportError("Invalid .honeydue file. Expected a contractor share file.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -118,7 +118,7 @@ export default function ContractorsPage() {
|
||||
}}
|
||||
>
|
||||
<Upload className="size-4 mr-2" />
|
||||
Import .casera
|
||||
Import .honeydue
|
||||
</Button>
|
||||
</PageHeader>
|
||||
|
||||
@@ -168,16 +168,16 @@ export default function ContractorsPage() {
|
||||
</>
|
||||
)}
|
||||
|
||||
{/* Import .casera dialog */}
|
||||
{/* Import .honeydue dialog */}
|
||||
<Dialog open={importOpen} onOpenChange={setImportOpen}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Import Contractor</DialogTitle>
|
||||
<DialogDescription>
|
||||
Import a contractor from a .casera file shared with you.
|
||||
Import a contractor from a .honeydue file shared with you.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<CaseraFileImport onImport={handleContractorImport} />
|
||||
<HoneyDueFileImport onImport={handleContractorImport} />
|
||||
{importError && (
|
||||
<p className="text-sm text-destructive">{importError}</p>
|
||||
)}
|
||||
|
||||
@@ -281,7 +281,7 @@ export default function DashboardPage() {
|
||||
<Home className="size-9 text-primary" />
|
||||
</div>
|
||||
<h1 className="font-heading text-3xl font-bold tracking-tight">
|
||||
Welcome to Casera{name ? `, ${name}` : ""}
|
||||
Welcome to honeyDue{name ? `, ${name}` : ""}
|
||||
</h1>
|
||||
<p className="text-muted-foreground mt-3 max-w-md text-base leading-relaxed">
|
||||
The easiest way to keep your home running smoothly.
|
||||
|
||||
@@ -9,7 +9,7 @@ import { LoadingSkeleton } from "@/components/shared/loading-skeleton";
|
||||
import { ErrorBanner } from "@/components/shared/error-banner";
|
||||
import { ShareCodeDisplay } from "@/components/sharing/share-code-display";
|
||||
import { UserManagement } from "@/components/sharing/user-management";
|
||||
import { CaseraFileExport } from "@/components/sharing/casera-file-handler";
|
||||
import { HoneyDueFileExport } from "@/components/sharing/honeydue-file-handler";
|
||||
import { useResidence } from "@/lib/hooks/use-residences";
|
||||
import { useDataProvider } from "@/lib/demo/data-provider-context";
|
||||
|
||||
@@ -46,7 +46,7 @@ export default function ResidenceSharePage({ params }: SharePageProps) {
|
||||
|
||||
// Build the exportable residence data
|
||||
const exportData = {
|
||||
type: "casera_residence_share",
|
||||
type: "honeydue_residence_share",
|
||||
version: 1,
|
||||
residence: {
|
||||
name: residence.name,
|
||||
@@ -87,16 +87,16 @@ export default function ResidenceSharePage({ params }: SharePageProps) {
|
||||
<ShareCodeDisplay residenceId={id} />
|
||||
)}
|
||||
|
||||
{/* Export .casera file */}
|
||||
{/* Export .honeydue file */}
|
||||
{residence.is_owner && (
|
||||
<div className="flex items-center gap-3">
|
||||
<CaseraFileExport
|
||||
<HoneyDueFileExport
|
||||
data={exportData}
|
||||
filename={`${safeFilename}-residence`}
|
||||
label="Export Residence (.casera)"
|
||||
label="Export Residence (.honeydue)"
|
||||
/>
|
||||
<p className="text-sm text-muted-foreground">
|
||||
Download residence data as a portable .casera file.
|
||||
Download residence data as a portable .honeydue file.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -11,7 +11,7 @@ import { Label } from "@/components/ui/label";
|
||||
import { Separator } from "@/components/ui/separator";
|
||||
import { PageHeader } from "@/components/shared/page-header";
|
||||
import { ErrorBanner } from "@/components/shared/error-banner";
|
||||
import { CaseraFileImport } from "@/components/sharing/casera-file-handler";
|
||||
import { HoneyDueFileImport } from "@/components/sharing/honeydue-file-handler";
|
||||
import { useJoinResidence } from "@/lib/hooks/use-sharing";
|
||||
import { useDataProvider } from "@/lib/demo/data-provider-context";
|
||||
|
||||
@@ -61,7 +61,7 @@ export default function JoinResidencePage() {
|
||||
});
|
||||
} else {
|
||||
setFileError(
|
||||
"Invalid .casera file. Expected a share package with a code field.",
|
||||
"Invalid .honeydue file. Expected a share package with a code field.",
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -126,13 +126,13 @@ export default function JoinResidencePage() {
|
||||
{/* File import */}
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Import .casera File</CardTitle>
|
||||
<CardTitle>Import .honeydue File</CardTitle>
|
||||
<CardDescription>
|
||||
If you received a .casera share package file, import it here.
|
||||
If you received a .honeydue share package file, import it here.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-3">
|
||||
<CaseraFileImport onImport={handleFileImport} />
|
||||
<HoneyDueFileImport onImport={handleFileImport} />
|
||||
{fileError && (
|
||||
<p className="text-sm text-destructive">{fileError}</p>
|
||||
)}
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
import type { Metadata } from "next";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Try Casera — Free Demo",
|
||||
title: "Try honeyDue — Free Demo",
|
||||
description:
|
||||
"Try Casera without an account. Manage tasks, contractors, and documents in a live demo.",
|
||||
"Try honeyDue without an account. Manage tasks, contractors, and documents in a live demo.",
|
||||
openGraph: {
|
||||
title: "Try Casera — Free Demo",
|
||||
title: "Try honeyDue — Free Demo",
|
||||
description:
|
||||
"Try Casera without an account. Manage tasks, contractors, and documents in a live demo.",
|
||||
"Try honeyDue without an account. Manage tasks, contractors, and documents in a live demo.",
|
||||
type: "website",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -16,19 +16,19 @@ export default function DemoLandingPage() {
|
||||
<Link href="/" className="inline-flex items-center gap-2.5 mb-10">
|
||||
<Image
|
||||
src="/logo.png"
|
||||
alt="Casera"
|
||||
alt="honeyDue"
|
||||
width={36}
|
||||
height={36}
|
||||
className="rounded-lg"
|
||||
/>
|
||||
<span className="font-heading text-2xl font-bold tracking-tight text-[#2D3436]">
|
||||
Casera
|
||||
honeyDue
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
{/* Hero */}
|
||||
<h1 className="font-heading text-4xl font-bold tracking-tight text-[#2D3436]">
|
||||
See Casera in action
|
||||
See honeyDue in action
|
||||
</h1>
|
||||
<p className="mt-4 text-lg text-[#8A8F87] leading-relaxed">
|
||||
Explore the full app with sample data. No account needed —
|
||||
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 1.6 KiB |
+5
-5
@@ -26,21 +26,21 @@ const geistMono = Geist_Mono({
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: {
|
||||
default: "Casera — Home Maintenance Made Simple",
|
||||
template: "%s | Casera",
|
||||
default: "honeyDue — Home Maintenance Made Simple",
|
||||
template: "%s | honeyDue",
|
||||
},
|
||||
description:
|
||||
"Track tasks, organize contractors, store documents. Manage your home maintenance in one place.",
|
||||
openGraph: {
|
||||
title: "Casera — Home Maintenance Made Simple",
|
||||
title: "honeyDue — Home Maintenance Made Simple",
|
||||
description:
|
||||
"Track tasks, organize contractors, store documents. Manage your home maintenance in one place.",
|
||||
type: "website",
|
||||
siteName: "Casera",
|
||||
siteName: "honeyDue",
|
||||
},
|
||||
twitter: {
|
||||
card: "summary_large_image",
|
||||
title: "Casera — Home Maintenance Made Simple",
|
||||
title: "honeyDue — Home Maintenance Made Simple",
|
||||
description: "Home Maintenance Made Simple",
|
||||
},
|
||||
};
|
||||
|
||||
@@ -41,7 +41,7 @@ export default function OnboardingLayout({
|
||||
{/* Logo */}
|
||||
<div className="mb-2">
|
||||
<h1 className="text-2xl font-bold tracking-tight text-primary">
|
||||
Casera
|
||||
honeyDue
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
|
||||
+6
-6
@@ -89,13 +89,13 @@ export default function HomePage() {
|
||||
<Link href="/" className="flex items-center gap-2.5">
|
||||
<Image
|
||||
src="/logo.png"
|
||||
alt="Casera"
|
||||
alt="honeyDue"
|
||||
width={32}
|
||||
height={32}
|
||||
className="rounded-lg"
|
||||
/>
|
||||
<span className="font-heading text-xl font-bold tracking-tight text-[#2D3436]">
|
||||
Casera
|
||||
honeyDue
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
@@ -272,7 +272,7 @@ export default function HomePage() {
|
||||
Everything your home needs, nothing it doesn't.
|
||||
</h2>
|
||||
<p className="mt-4 text-lg text-[#8A8F87] leading-relaxed">
|
||||
Casera brings all your home maintenance into one clear,
|
||||
honeyDue brings all your home maintenance into one clear,
|
||||
organized space. No bloat, no learning curve.
|
||||
</p>
|
||||
</div>
|
||||
@@ -406,13 +406,13 @@ export default function HomePage() {
|
||||
<Link href="/" className="flex items-center gap-2.5 mb-4">
|
||||
<Image
|
||||
src="/logo.png"
|
||||
alt="Casera"
|
||||
alt="honeyDue"
|
||||
width={28}
|
||||
height={28}
|
||||
className="rounded-md"
|
||||
/>
|
||||
<span className="font-heading text-lg font-bold text-white">
|
||||
Casera
|
||||
honeyDue
|
||||
</span>
|
||||
</Link>
|
||||
<p className="text-sm leading-relaxed">
|
||||
@@ -485,7 +485,7 @@ export default function HomePage() {
|
||||
|
||||
<div className="mt-16 pt-8 border-t border-white/5 flex flex-col sm:flex-row items-center justify-between gap-4">
|
||||
<p className="text-xs">
|
||||
© {new Date().getFullYear()} Casera. All rights reserved.
|
||||
© {new Date().getFullYear()} honeyDue. All rights reserved.
|
||||
</p>
|
||||
<p className="text-xs">
|
||||
Made for homeowners, by homeowners.
|
||||
|
||||
@@ -11,7 +11,7 @@ export default function SubscriptionSuccessPage() {
|
||||
<h2 className="text-lg font-semibold">Thank you!</h2>
|
||||
<p className="mt-2 text-muted-foreground text-center max-w-md">
|
||||
Your Pro subscription is now active. Enjoy unlimited access to all
|
||||
Casera features.
|
||||
honeyDue features.
|
||||
</p>
|
||||
<Button asChild className="mt-6">
|
||||
<Link href="/app/settings/subscription">Back to Settings</Link>
|
||||
|
||||
@@ -13,7 +13,7 @@ export function DemoBanner() {
|
||||
return (
|
||||
<div className="sticky top-0 z-50 flex items-center justify-center gap-3 border-b border-brand-clay/20 bg-brand-clay-light/80 px-4 py-2.5 text-sm text-[#92400E] backdrop-blur-xl">
|
||||
<p className="font-medium">
|
||||
You're exploring Casera in demo mode. Changes aren't saved.
|
||||
You're exploring honeyDue in demo mode. Changes aren't saved.
|
||||
</p>
|
||||
<Button size="xs" className="rounded-full" asChild>
|
||||
<Link href="/register">Sign Up Free</Link>
|
||||
|
||||
@@ -23,13 +23,13 @@ export function AuthFormWrapper({
|
||||
<Link href="/" className="flex items-center gap-2.5">
|
||||
<Image
|
||||
src="/logo.png"
|
||||
alt="Casera"
|
||||
alt="honeyDue"
|
||||
width={32}
|
||||
height={32}
|
||||
className="rounded-lg"
|
||||
/>
|
||||
<span className="font-heading text-xl font-bold text-foreground">
|
||||
Casera
|
||||
honeyDue
|
||||
</span>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -22,13 +22,13 @@ export function Sidebar() {
|
||||
<Link href={basePath} className="flex items-center gap-2.5 group">
|
||||
<Image
|
||||
src="/logo.png"
|
||||
alt="Casera"
|
||||
alt="honeyDue"
|
||||
width={32}
|
||||
height={32}
|
||||
className="rounded-lg transition-transform group-hover:scale-105"
|
||||
/>
|
||||
<span className="hidden lg:inline font-heading text-lg font-bold text-foreground tracking-tight">
|
||||
Casera
|
||||
honeyDue
|
||||
</span>
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
@@ -49,13 +49,13 @@ export function TopBar() {
|
||||
<Link href={basePath} className="flex items-center gap-2.5 shrink-0 group">
|
||||
<Image
|
||||
src="/logo.png"
|
||||
alt="Casera"
|
||||
alt="honeyDue"
|
||||
width={32}
|
||||
height={32}
|
||||
className="rounded-lg transition-transform group-hover:scale-105"
|
||||
/>
|
||||
<span className="font-heading text-xl font-bold text-foreground tracking-tight">
|
||||
Casera
|
||||
honeyDue
|
||||
</span>
|
||||
</Link>
|
||||
|
||||
|
||||
@@ -9,8 +9,8 @@ export function WelcomeStep() {
|
||||
const user = useAuthStore((s) => s.user);
|
||||
|
||||
const greeting = user?.first_name
|
||||
? `Welcome to Casera, ${user.first_name}!`
|
||||
: "Welcome to Casera!";
|
||||
? `Welcome to honeyDue, ${user.first_name}!`
|
||||
: "Welcome to honeyDue!";
|
||||
|
||||
return (
|
||||
<div className="flex flex-col items-center text-center space-y-6 py-12">
|
||||
|
||||
@@ -44,7 +44,7 @@ export function UpgradePrompt({ open, onOpenChange, feature, limitInfo }: Upgrad
|
||||
features.
|
||||
</p>
|
||||
<p>
|
||||
Subscriptions are managed through the Casera iOS or Android app.
|
||||
Subscriptions are managed through the honeyDue iOS or Android app.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
+10
-10
@@ -9,16 +9,16 @@ import { Button } from "@/components/ui/button";
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Generates a `.casera` file from the given data object and triggers a download.
|
||||
* Generates a `.honeydue` file from the given data object and triggers a download.
|
||||
*/
|
||||
export function downloadCaseraFile(data: object, filename: string) {
|
||||
export function downloadHoneyDueFile(data: object, filename: string) {
|
||||
const json = JSON.stringify(data, null, 2);
|
||||
const blob = new Blob([json], { type: "application/json" });
|
||||
const url = URL.createObjectURL(blob);
|
||||
|
||||
const anchor = document.createElement("a");
|
||||
anchor.href = url;
|
||||
anchor.download = filename.endsWith(".casera") ? filename : `${filename}.casera`;
|
||||
anchor.download = filename.endsWith(".honeydue") ? filename : `${filename}.honeydue`;
|
||||
document.body.appendChild(anchor);
|
||||
anchor.click();
|
||||
|
||||
@@ -31,12 +31,12 @@ export function downloadCaseraFile(data: object, filename: string) {
|
||||
// Import component
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
interface CaseraFileImportProps {
|
||||
interface HoneyDueFileImportProps {
|
||||
onImport: (data: unknown) => void;
|
||||
accept?: string;
|
||||
}
|
||||
|
||||
export function CaseraFileImport({ onImport, accept = ".casera" }: CaseraFileImportProps) {
|
||||
export function HoneyDueFileImport({ onImport, accept = ".honeydue" }: HoneyDueFileImportProps) {
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
const [dragActive, setDragActive] = useState(false);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
@@ -58,7 +58,7 @@ export function CaseraFileImport({ onImport, accept = ".casera" }: CaseraFileImp
|
||||
const parsed = JSON.parse(text);
|
||||
onImport(parsed);
|
||||
} catch {
|
||||
setError("Invalid .casera file. Could not parse contents.");
|
||||
setError("Invalid .honeydue file. Could not parse contents.");
|
||||
setFileName(null);
|
||||
}
|
||||
};
|
||||
@@ -109,7 +109,7 @@ export function CaseraFileImport({ onImport, accept = ".casera" }: CaseraFileImp
|
||||
<Upload className="size-8 text-muted-foreground" />
|
||||
<div className="text-center">
|
||||
<p className="text-sm font-medium">
|
||||
Drop a .casera file here or click to browse
|
||||
Drop a .honeydue file here or click to browse
|
||||
</p>
|
||||
{fileName && (
|
||||
<p className="text-xs text-muted-foreground mt-1">
|
||||
@@ -136,18 +136,18 @@ export function CaseraFileImport({ onImport, accept = ".casera" }: CaseraFileImp
|
||||
// Export button component (convenience wrapper)
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
interface CaseraFileExportProps {
|
||||
interface HoneyDueFileExportProps {
|
||||
data: object;
|
||||
filename: string;
|
||||
label?: string;
|
||||
}
|
||||
|
||||
export function CaseraFileExport({ data, filename, label = "Export .casera" }: CaseraFileExportProps) {
|
||||
export function HoneyDueFileExport({ data, filename, label = "Export .honeydue" }: HoneyDueFileExportProps) {
|
||||
return (
|
||||
<Button
|
||||
variant="outline"
|
||||
size="sm"
|
||||
onClick={() => downloadCaseraFile(data, filename)}
|
||||
onClick={() => downloadHoneyDueFile(data, filename)}
|
||||
>
|
||||
<FileDown className="size-4 mr-2" />
|
||||
{label}
|
||||
@@ -1,13 +1,13 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// Base API client for Casera web app
|
||||
// Base API client for honeyDue web app
|
||||
// ---------------------------------------------------------------------------
|
||||
// All client-side requests go through Next.js API route handlers (proxy).
|
||||
// The proxy reads the httpOnly `casera-token` cookie and forwards it to the
|
||||
// The proxy reads the httpOnly `honeydue-token` cookie and forwards it to the
|
||||
// Go API as an Authorization header. This avoids exposing the token to JS.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
const API_BASE_URL =
|
||||
process.env.NEXT_PUBLIC_API_URL || 'https://casera.treytartt.com/api';
|
||||
process.env.NEXT_PUBLIC_API_URL || 'https://honeyDue.treytartt.com/api';
|
||||
|
||||
/**
|
||||
* Server-only base URL. Falls back to the public one so that server
|
||||
@@ -86,7 +86,7 @@ export async function apiFetch<T>(
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Server-side fetch that reads the auth token from the `casera-token` cookie
|
||||
* Server-side fetch that reads the auth token from the `honeydue-token` cookie
|
||||
* and calls the Go API directly (no proxy hop).
|
||||
*
|
||||
* Only use this inside:
|
||||
@@ -102,7 +102,7 @@ export async function serverFetch<T>(
|
||||
// (the function itself should only be *called* on the server).
|
||||
const { cookies } = await import('next/headers');
|
||||
const cookieStore = await cookies();
|
||||
const token = cookieStore.get('casera-token')?.value;
|
||||
const token = cookieStore.get('honeydue-token')?.value;
|
||||
|
||||
const normalized = path.endsWith('/') ? path : `${path}/`;
|
||||
const url = `${SERVER_API_URL}${normalized}`;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// ---------------------------------------------------------------------------
|
||||
// Casera API Client - barrel export
|
||||
// honeyDue API Client - barrel export
|
||||
// ---------------------------------------------------------------------------
|
||||
// Usage:
|
||||
// import { auth, residences, tasks } from '@/lib/api';
|
||||
|
||||
@@ -258,7 +258,7 @@ export const demoProvider: DataProvider = {
|
||||
{
|
||||
id: 1,
|
||||
username: 'demo_user',
|
||||
email: 'demo@casera.app',
|
||||
email: 'demo@honeyDue.treytartt.com',
|
||||
first_name: 'Demo',
|
||||
last_name: 'User',
|
||||
is_owner: true,
|
||||
@@ -273,7 +273,7 @@ export const demoProvider: DataProvider = {
|
||||
return {
|
||||
message: 'Report generated (demo)',
|
||||
residence_name: r?.name ?? 'Demo Residence',
|
||||
recipient_email: 'demo@casera.app',
|
||||
recipient_email: 'demo@honeyDue.treytartt.com',
|
||||
pdf_generated: true,
|
||||
email_sent: false,
|
||||
report: {},
|
||||
|
||||
@@ -86,7 +86,7 @@ export const demoNotifications: NotificationResponse[] = [
|
||||
},
|
||||
{
|
||||
id: 9,
|
||||
title: 'Welcome to Casera!',
|
||||
title: 'Welcome to honeyDue!',
|
||||
body: 'Start by adding your first residence to track home maintenance.',
|
||||
notification_type: 'system',
|
||||
is_read: true,
|
||||
|
||||
@@ -3,7 +3,7 @@ import type { UserResponse } from '@/lib/api/auth';
|
||||
export const demoUser: UserResponse = {
|
||||
id: 1,
|
||||
username: 'demo_user',
|
||||
email: 'demo@casera.app',
|
||||
email: 'demo@honeyDue.treytartt.com',
|
||||
first_name: 'Demo',
|
||||
last_name: 'User',
|
||||
is_email_verified: true,
|
||||
|
||||
@@ -19,7 +19,7 @@ export interface ThemeDefinition {
|
||||
}
|
||||
|
||||
/**
|
||||
* Single "Warm Sage" theme — the Casera brand palette.
|
||||
* Single "Warm Sage" theme — the honeyDue brand palette.
|
||||
*/
|
||||
export const themes: ThemeDefinition[] = [
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
// ============================================================================
|
||||
// API-level types: errors, pagination, common response wrappers
|
||||
// Generated from myCribAPI-go/internal/dto/responses/auth.go (ErrorResponse, MessageResponse)
|
||||
// Generated from honeyDueAPI-go/internal/dto/responses/auth.go (ErrorResponse, MessageResponse)
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// ============================================================================
|
||||
// Auth request / response types
|
||||
// Generated from:
|
||||
// myCribAPI-go/internal/dto/requests/auth.go
|
||||
// myCribAPI-go/internal/dto/responses/auth.go
|
||||
// honeyDueAPI-go/internal/dto/requests/auth.go
|
||||
// honeyDueAPI-go/internal/dto/responses/auth.go
|
||||
// ============================================================================
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// ============================================================================
|
||||
// Contractor request / response types
|
||||
// Generated from:
|
||||
// myCribAPI-go/internal/dto/requests/contractor.go
|
||||
// myCribAPI-go/internal/dto/responses/contractor.go
|
||||
// honeyDueAPI-go/internal/dto/requests/contractor.go
|
||||
// honeyDueAPI-go/internal/dto/responses/contractor.go
|
||||
// ============================================================================
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
// ============================================================================
|
||||
// Document request / response types
|
||||
// Generated from:
|
||||
// myCribAPI-go/internal/dto/requests/document.go
|
||||
// myCribAPI-go/internal/dto/responses/document.go
|
||||
// myCribAPI-go/internal/models/document.go (DocumentType enum)
|
||||
// honeyDueAPI-go/internal/dto/requests/document.go
|
||||
// honeyDueAPI-go/internal/dto/responses/document.go
|
||||
// honeyDueAPI-go/internal/models/document.go (DocumentType enum)
|
||||
// ============================================================================
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
// ============================================================================
|
||||
// Static / lookup data types
|
||||
// Generated from:
|
||||
// myCribAPI-go/internal/handlers/static_data_handler.go (SeededDataResponse)
|
||||
// myCribAPI-go/internal/dto/responses/residence.go (ResidenceTypeResponse)
|
||||
// myCribAPI-go/internal/dto/responses/task.go (TaskCategory/Priority/Frequency)
|
||||
// myCribAPI-go/internal/dto/responses/contractor.go (ContractorSpecialtyResponse)
|
||||
// myCribAPI-go/internal/dto/responses/task_template.go (TaskTemplatesGroupedResponse)
|
||||
// honeyDueAPI-go/internal/handlers/static_data_handler.go (SeededDataResponse)
|
||||
// honeyDueAPI-go/internal/dto/responses/residence.go (ResidenceTypeResponse)
|
||||
// honeyDueAPI-go/internal/dto/responses/task.go (TaskCategory/Priority/Frequency)
|
||||
// honeyDueAPI-go/internal/dto/responses/contractor.go (ContractorSpecialtyResponse)
|
||||
// honeyDueAPI-go/internal/dto/responses/task_template.go (TaskTemplatesGroupedResponse)
|
||||
// ============================================================================
|
||||
|
||||
import type { ResidenceTypeResponse } from "./residence";
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// ============================================================================
|
||||
// Notification request / response types
|
||||
// Generated from:
|
||||
// myCribAPI-go/internal/services/notification_service.go
|
||||
// myCribAPI-go/internal/models/notification.go (NotificationType enum)
|
||||
// honeyDueAPI-go/internal/services/notification_service.go
|
||||
// honeyDueAPI-go/internal/models/notification.go (NotificationType enum)
|
||||
// ============================================================================
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// ============================================================================
|
||||
// Residence request / response types
|
||||
// Generated from:
|
||||
// myCribAPI-go/internal/dto/requests/residence.go
|
||||
// myCribAPI-go/internal/dto/responses/residence.go
|
||||
// honeyDueAPI-go/internal/dto/requests/residence.go
|
||||
// honeyDueAPI-go/internal/dto/responses/residence.go
|
||||
// ============================================================================
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// ============================================================================
|
||||
// Subscription request / response types
|
||||
// Generated from:
|
||||
// myCribAPI-go/internal/services/subscription_service.go
|
||||
// myCribAPI-go/internal/models/subscription.go (SubscriptionTier enum)
|
||||
// honeyDueAPI-go/internal/services/subscription_service.go
|
||||
// honeyDueAPI-go/internal/models/subscription.go (SubscriptionTier enum)
|
||||
// ============================================================================
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
// ============================================================================
|
||||
// Task template response types
|
||||
// Generated from:
|
||||
// myCribAPI-go/internal/dto/responses/task_template.go
|
||||
// honeyDueAPI-go/internal/dto/responses/task_template.go
|
||||
// ============================================================================
|
||||
|
||||
import type { TaskCategoryResponse, TaskFrequencyResponse } from "./task";
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
// ============================================================================
|
||||
// Task request / response types
|
||||
// Generated from:
|
||||
// myCribAPI-go/internal/dto/requests/task.go
|
||||
// myCribAPI-go/internal/dto/responses/task.go
|
||||
// honeyDueAPI-go/internal/dto/requests/task.go
|
||||
// honeyDueAPI-go/internal/dto/responses/task.go
|
||||
// ============================================================================
|
||||
|
||||
import type { TotalSummary } from "./residence";
|
||||
|
||||
+1
-1
@@ -2,7 +2,7 @@ import { NextResponse } from 'next/server';
|
||||
import type { NextRequest } from 'next/server';
|
||||
|
||||
export function middleware(request: NextRequest) {
|
||||
const token = request.cookies.get('casera-token')?.value;
|
||||
const token = request.cookies.get('honeydue-token')?.value;
|
||||
const { pathname } = request.nextUrl;
|
||||
|
||||
// Public paths that don't require auth
|
||||
|
||||
+1
-1
@@ -19,7 +19,7 @@ export const useThemeStore = create<ThemeState>()(
|
||||
},
|
||||
}),
|
||||
{
|
||||
name: "casera-theme",
|
||||
name: "honeydue-theme",
|
||||
}
|
||||
)
|
||||
);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Casera "Warm Sage" design system
|
||||
* honeyDue "Warm Sage" design system
|
||||
* Single brand palette — light + dark mode
|
||||
* Maps to shadcn/ui CSS variables and custom app variables
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user