ec165beeffcfc6f835b55a608b857270f9755679
Carry Your Live - Mobile To-Do & Calendar App
A minimalist, offline-first task management app built with Expo, React Native, and WatermelonDB. Features three primary screens: To-Do List, Add New Task, and Calendar with bottom navigation.
Features
Core Functionality
- Offline-First Architecture: Full CRUD operations work offline with WatermelonDB + SQLite
- Auto-Sync: Background synchronization with custom Postgres API when online
- Cross-Platform: iOS, Android, and Web from single codebase
Screens
1. To-Do List Screen
- Header: App logo + "TODO" title with rounded corners
- Category Filter: Horizontal scrollable chips (Work, Personal, School, Shopping, Health, Finance, All)
- Single selection with visual feedback (thicker border, shadow, scale animation)
- Instant task filtering
- Task List: Vertical scrolling with:
- Checkbox (empty/checked states with animation)
- Task title (truncated with ellipsis)
- Three-dot overflow menu (Edit, Delete, Duplicate, Mark Complete, Change Category, Change Priority)
- Priority badges with colors
- Due date/time with overdue/due-today highlighting
- Completed section (collapsible)
- Floating Action Button: Bottom-right, opens Add Task screen with press animation
2. Add New Task Screen
- Category Selector: Horizontal row of colored circles (required)
- Task Name: Single-line input, 100 char max (required)
- Subtasks: Unlimited, add/remove individually
- Date & Time: Date picker, time picker, calendar button
- Priority: Dropdown (None, Low, Medium, High, Critical) with color indicators
- Description: Multi-line text area, 1000 char max
- Bottom Actions: Submit (primary) / Cancel (secondary) fixed buttons
3. Calendar Screen
- Date Strip: Horizontal scrollable days of current month
- Month Label: Centered (e.g., "JAN 2026")
- Task List: Tasks for selected day with category color, title, time, completion status
- Empty State: "No tasks scheduled."
4. Settings Screen
- Dark Mode toggle
- Push Notifications toggle
- Reminder Preferences
- Default Category selector
- Sort Tasks By (Date, Priority, Alphabetically, Creation Date)
- Backup & Sync
- Version, Privacy Policy, Terms of Service
Task States
- Pending: Empty checkbox, normal text
- Completed: Checked checkbox, strikethrough, reduced opacity
- Overdue: Red due date, warning indicator
- Due Today: Blue highlight
- High Priority: Priority badge
Interactions
- Tap task → Edit screen
- Long press → Selection mode (multi-delete, multi-complete, change category/priority)
- Swipe left → Delete
- Swipe right → Complete
- Pull down → Refresh
Tech Stack
| Layer | Technology |
|---|---|
| Framework | Expo (React Native) |
| Language | TypeScript |
| Navigation | Expo Router (file-based) |
| Database | WatermelonDB + SQLite |
| State | WatermelonDB (reactive queries, no Redux needed) |
| Forms | React Hook Form + Zod validation |
| UI Components | React Native Paper + Custom SVG icons |
| Animations | React Native Reanimated |
| Date/Time | @react-native-community/datetimepicker + date-fns |
| Build | Expo Dev Client / EAS Build |
Project Structure
carry-your-live/
├── app/
│ ├── _layout.tsx # Root layout + DatabaseProvider
│ ├── (tabs)/
│ │ ├── _layout.tsx # Bottom tab navigator
│ │ ├── index.tsx # Tasks screen
│ │ ├── calendar.tsx # Calendar screen
│ │ └── settings.tsx # Settings screen
│ └── add-task.tsx # Add Task screen
├── src/
│ ├── components/ # Reusable UI components
│ │ ├── Header.tsx
│ │ ├── CategoryFilter.tsx
│ │ ├── TaskList.tsx
│ │ ├── TaskItem.tsx
│ │ ├── FloatingActionButton.tsx
│ │ ├── TabBarIcon.tsx
│ │ ├── CategorySelector.tsx
│ │ ├── TaskNameInput.tsx
│ │ ├── SubtasksSection.tsx
│ │ ├── DateTimePicker.tsx
│ │ ├── PrioritySelector.tsx
│ │ ├── DescriptionInput.tsx
│ │ ├── FormButtons.tsx
│ │ └── ListItem.tsx
│ ├── database/
│ │ ├── schema.ts # WatermelonDB schema
│ │ ├── index.ts # Database instance + collections
│ │ └── sync.ts # Custom API sync adapter
│ ├── models/
│ │ ├── Task.ts
│ │ ├── Category.ts
│ │ └── Subtask.ts
│ ├── hooks/
│ │ ├── useDatabase.tsx # Database context & providers
│ │ └── useTasks.tsx # Task queries with reactive state
│ ├── constants/
│ │ └── index.ts # Categories, priorities, colors
│ └── types/
│ └── index.ts # TypeScript interfaces
Data Models
Task
{
id: string;
title: string;
description: string;
categoryId: string;
priority: 'none' | 'low' | 'medium' | 'high' | 'critical';
completed: boolean;
dueDate: number; // timestamp
dueTime: string; // "HH:MM"
createdAt: Date;
updatedAt: Date;
subtasks: Subtask[];
}
Category
{
id: string;
name: string;
color: '#HEX';
order: number;
}
Subtask
{
id: string;
taskId: string;
title: string;
completed: boolean;
order: number;
createdAt: Date;
updatedAt: Date;
}
Default Categories
| Name | Color | Order |
|---|---|---|
| Work | #E53935 (Red) | 0 |
| Personal | #43A047 (Green) | 1 |
| School | #1E88E5 (Blue) | 2 |
| Shopping | #FB8C00 (Orange) | 3 |
| Health | #8E24AA (Purple) | 4 |
| Finance | #FDD835 (Yellow) | 5 |
Priority Colors
| Priority | Color |
|---|---|
| None | #9E9E9E |
| Low | #43A047 |
| Medium | #FB8C00 |
| High | #E53935 |
| Critical | #B71C1C |
Getting Started
Prerequisites
- Node.js 20+
- npm or yarn
- Expo CLI (
npm install -g expo-cli) - iOS Simulator (Mac) / Android Studio for mobile testing
Installation
cd carry-your-live
npm install
Development
# Start Expo dev server
npx expo start
# Run on specific platform
npx expo start --ios
npx expo start --android
npx expo start --web
Building
# Install EAS CLI
npm install -g eas-cli
# Configure project
eas build:configure
# Build for platforms
eas build --platform ios
eas build --platform android
eas build --platform web
Sync API Specification
The app expects a custom API at http://localhost:3000/api (configurable in src/database/sync.ts):
Pull Changes
GET /sync?since={timestamp}
Response:
{
"categories": [{ "id", "name", "color", "order", "createdAt", "updatedAt" }],
"tasks": [{ "id", "title", "description", "categoryId", "priority", "completed", "dueDate", "dueTime", "createdAt", "updatedAt" }],
"subtasks": [{ "id", "taskId", "title", "completed", "order", "createdAt", "updatedAt" }],
"timestamp": 1234567890
}
Push Changes
POST /sync/push
Body:
{
"changes": {
"categories": [...],
"tasks": [...],
"subtasks": [...]
},
"lastPulledAt": 1234567890
}
Configuration
Environment Variables
Create .env file:
EXPO_PUBLIC_API_URL=http://your-api-url/api
App Config
Modify app.json for:
- App name, slug, version
- Icon, splash screen
- Permissions (notifications, etc.)
- Orientation, theme
Visual Style Guide
- Background: White (#FFFFFF)
- Primary Accent: #E53935 (Pink/Red)
- Typography: Black (#212121) primary, #757575 secondary, #9E9E9E tertiary
- Borders: Thin (#E0E0E0), selected #E53935
- Radius: 16-20px for cards/buttons/inputs
- Spacing: 8px grid system
- Shadows: Minimal (elevation 1-3)
- Animations: 150-250ms, cubic easing
Offline-First Architecture
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Expo App │────▶│ WatermelonDB │────▶│ Your API │
│ (iOS/Android│ │ (SQLite) │ │ (Postgres) │
│ Web) │◀───▶│ + Sync │◀───▶│ │
└─────────────┘ └──────────────┘ └─────────────┘
- All writes go to local SQLite first
- Reactive queries update UI instantly
- Background sync pushes/pulls changes
- Conflict resolution: last-write-wins (customizable)
Contributing
- Follow existing code conventions
- Use TypeScript strict mode
- Write components with React Hook Form + Zod
- Use WatermelonDB decorators for models
- Test offline scenarios
License
MIT