A gift management application designed to help you track, organize, and remember gifts for the special people in your life. Built with React Native and Expo.
- Add and organize people you buy gifts for
- Track birthdays (with optional year for age calculation)
- Store relationship types and personal notes
- Group people into categories (Family, Friends, Colleagues)
- Create private gift idea lists for each person
- Add gift ideas with names, URLs, and notes
- Share gift maps with family and friends via unique links
- Others can reserve items anonymously (perfect for coordinated gifting)
- Real-time updates when items are reserved
- Track birthdays, holidays, anniversaries, and custom events
- Four-stage gift status workflow: Idea β Shopping β Bought β Delivered
- View upcoming events at a glance
- Automatic countdown to important dates
- Local push notifications for upcoming events
- Automated reminders at 30 days, 7 days, and 1 day before events
- Configurable per-event notification preferences
- Record past gifts (both given and received)
- Attach photos and receipts
- Add product links and notes
- Search and filter by person or direction (gave/received)
- Avoid duplicate gifts by referencing history
- Organize people into custom groups
- Bidirectional relationship management
- Quick access to all group members
- One-way export to device calendar
- Keep gift events synchronized with your schedule
Inspired by high-end jewelry brands (Cartier, Rolex, Tiffany's):
Color Palette:
- Primary: Deep charcoal navy (
#1a1f2e) - Accent: Champagne gold (
#c9a961) - Rose Gold: Available for special highlights
- Background: Warm cream/ivory (
#fafaf9) - Surface: Pure white with elevated cream variations
Typography:
- Light weights (300-400) for elegance
- Generous letter spacing for refinement
- Uppercase buttons with extended tracking
- Small caps labels
Details:
- Minimal border radius (4-12px)
- Subtle shadows (0.04-0.08 opacity)
- Gold accent borders and dividers
- Sophisticated spacing scale
- React Native - Cross-platform mobile framework
- Expo - Development platform and toolchain
- TypeScript - Type safety and better DX
- Expo Router - File-based navigation
- Zustand - Lightweight state management
- Custom hooks for feature-specific logic
- Firebase Authentication - User auth with email/password
- Cloud Firestore - Real-time NoSQL database
- Firebase Storage - Photo and file storage
- Expo Notifications - Local push notifications
- Expo Calendar - Device calendar integration
- React Hook Form - Form validation and management
- date-fns - Date manipulation and formatting
gifting/
βββ app/ # Expo Router screens
β βββ (auth)/ # Authentication screens
β β βββ login.tsx
β β βββ register.tsx
β βββ (tabs)/ # Main app tabs
β β βββ index.tsx # Home/Dashboard
β β βββ people/
β β β βββ index.tsx # People list
β β β βββ [id].tsx # Person detail
β β β βββ add.tsx # Add person
β β βββ events.tsx # Events list
β β βββ history.tsx # History list
β βββ gift-map/
β β βββ [personId].tsx # Gift map (owner view)
β βββ shared/
β β βββ [shareToken].tsx # Shared gift map (public)
β βββ groups/
β βββ index.tsx # Groups list
β βββ [id].tsx # Group detail
β
βββ src/
β βββ components/ # Reusable components
β β βββ ui/ # Base UI components
β β β βββ Button.tsx
β β β βββ Input.tsx
β β β βββ Loading.tsx
β β β βββ EmptyState.tsx
β β βββ people/
β β β βββ PersonCard.tsx
β β β βββ PersonForm.tsx
β β βββ gift-maps/
β β β βββ GiftItemCard.tsx
β β β βββ GiftItemForm.tsx
β β β βββ ShareLinkModal.tsx
β β βββ events/
β β β βββ EventCard.tsx
β β β βββ EventForm.tsx
β β βββ history/
β β β βββ HistoryCard.tsx
β β β βββ HistoryForm.tsx
β β βββ groups/
β β βββ GroupCard.tsx
β β βββ GroupForm.tsx
β β
β βββ store/ # Zustand stores
β β βββ authStore.ts
β β βββ peopleStore.ts
β β βββ giftMapsStore.ts
β β βββ eventsStore.ts
β β βββ historyStore.ts
β β βββ groupsStore.ts
β β
β βββ repositories/ # Data access layer
β β βββ person.repository.ts
β β βββ giftMap.repository.ts
β β βββ event.repository.ts
β β βββ history.repository.ts
β β βββ group.repository.ts
β β
β βββ services/ # External services
β β βββ firebase.ts
β β βββ firestore.service.ts
β β βββ storage.service.ts
β β βββ notifications.service.ts
β β βββ calendar.service.ts
β β
β βββ hooks/ # Custom React hooks
β β βββ useAuth.ts
β β βββ usePeople.ts
β β βββ useGiftMaps.ts
β β βββ useEvents.ts
β β βββ useHistory.ts
β β βββ useGroups.ts
β β
β βββ types/ # TypeScript types
β β βββ person.ts
β β βββ giftMap.ts
β β βββ giftEvent.ts
β β βββ giftHistory.ts
β β βββ group.ts
β β
β βββ utils/ # Utility functions
β β βββ date.ts
β β βββ validation.ts
β β βββ constants.ts
β β
β βββ styles/ # Design system
β βββ theme.ts # Luxury theme
β
βββ assets/ # Static assets
βββ package.json
βββ tsconfig.json
βββ app.json # Expo configuration
βββ README.md
users/{userId}/
βββ people/{personId}
β βββ name: string
β βββ relationship: string
β βββ birthdayMonth: number (1-12)
β βββ birthdayDay: number (1-31)
β βββ birthdayYear: number | null
β βββ notes: string
β βββ groupIds: string[]
β βββ createdAt: timestamp
β βββ updatedAt: timestamp
β
βββ gift_maps/{giftMapId}
β βββ personId: string
β βββ personName: string (denormalized)
β βββ shareToken: string | null
β βββ isShared: boolean
β βββ items: Array<{
β β id: string
β β name: string
β β url: string | null
β β notes: string | null
β β isReserved: boolean
β β reservedAt: timestamp | null
β β order: number
β β }>
β βββ createdAt: timestamp
β βββ updatedAt: timestamp
β
βββ gift_events/{eventId}
β βββ personId: string
β βββ personName: string (denormalized)
β βββ eventType: 'birthday' | 'holiday' | 'custom'
β βββ eventDate: timestamp
β βββ status: 'idea' | 'shopping' | 'bought' | 'delivered'
β βββ remindersEnabled: boolean
β βββ notes: string | null
β βββ createdAt: timestamp
β βββ updatedAt: timestamp
β
βββ gift_history/{historyId}
β βββ personId: string
β βββ personName: string (denormalized)
β βββ giftName: string
β βββ direction: 'gave' | 'received'
β βββ date: timestamp
β βββ notes: string | null
β βββ link: string | null
β βββ photoUrl: string | null
β βββ createdAt: timestamp
β βββ updatedAt: timestamp
β
βββ groups/{groupId}
βββ name: string
βββ memberIds: string[] (person IDs)
βββ createdAt: timestamp
βββ updatedAt: timestamp
shared_gift_maps/{shareToken}/ # Public collection
βββ userId: string
βββ giftMapId: string
βββ personName: string
βββ items: Array<{...}>
βββ updatedAt: timestamp
Gift Map Items as Array: Embedded array for better performance and offline support
Denormalization: Person names stored in events/history/maps to avoid complex queries
Shared Maps Duplication: Separate collection for public access without authentication
Bidirectional Relationships: Groups maintain memberIds, persons maintain groupIds
- Node.js (v16 or higher)
- npm or yarn
- Expo CLI:
npm install -g expo-cli - iOS Simulator (macOS) or Android Emulator
- Expo Go app (for testing on physical devices)
- Create a Firebase project at console.firebase.google.com
- Enable Authentication with Email/Password provider
- Create a Firestore Database in production mode
- Enable Firebase Storage for photo uploads
- Copy your Firebase config
-
Clone the repository:
git clone https://github.com/yourusername/gifting-app.git cd gifting-app -
Install dependencies:
npm install
-
Configure Firebase:
Create
src/config/firebase.config.ts:export const firebaseConfig = { apiKey: "YOUR_API_KEY", authDomain: "YOUR_AUTH_DOMAIN", projectId: "YOUR_PROJECT_ID", storageBucket: "YOUR_STORAGE_BUCKET", messagingSenderId: "YOUR_MESSAGING_SENDER_ID", appId: "YOUR_APP_ID" };
-
Deploy Firestore Security Rules:
In Firebase Console β Firestore β Rules:
rules_version = '2'; service cloud.firestore { match /databases/{database}/documents { // Users can only access their own data match /users/{userId} { allow read, write: if request.auth != null && request.auth.uid == userId; match /{document=**} { allow read, write: if request.auth != null && request.auth.uid == userId; } } // Shared gift maps are publicly readable match /shared_gift_maps/{shareToken} { allow read: if true; allow write: if request.auth != null && request.auth.uid == resource.data.userId; } } }
-
Deploy Storage Security Rules:
In Firebase Console β Storage β Rules:
rules_version = '2'; service firebase.storage { match /b/{bucket}/o { match /users/{userId}/history_photos/{photoId} { allow read, write: if request.auth != null && request.auth.uid == userId; } } }
-
Start the development server:
npx expo start
-
Run on a device:
- Scan QR code with Expo Go app (iOS/Android)
- Press
ifor iOS Simulator - Press
afor Android Emulator
- Tap the People tab
- Tap + Add button
- Fill in name and relationship
- Optionally add birthday (month, day, year)
- Add notes about preferences, sizes, etc.
- Tap Add Person
- Open a person's detail page
- Tap Gift Map
- Tap + Add Gift Item
- Add gift name, URL, and notes
- Save the item
- Open a gift map
- Tap Share Gift Map
- Copy the share link
- Send to family/friends via text or email
- Recipients can view and reserve items anonymously
- Go to Events tab
- Tap + Add
- Select person and event type
- Choose date
- Enable Reminders
- You'll receive notifications at 30d, 7d, and 1d before
- Go to History tab
- Tap + Add
- Select person
- Enter gift name and direction (gave/received)
- Add photo, link, and notes
- Save
# Start development server
npm start
# Start with cleared cache
npm start -- --clear
# Run on iOS
npm run ios
# Run on Android
npm run android
# Type checking
npm run type-check
# Lint code
npm run lint- TypeScript for type safety
- Functional components with hooks
- Zustand for state management
- Repository pattern for data access
- Custom hooks for business logic
- Define types in
src/types/ - Create repository in
src/repositories/ - Create Zustand store in
src/store/ - Create custom hook in
src/hooks/ - Build UI components in
src/components/ - Create screen in
app/
- Sign up with email/password
- Log in and log out
- Create, edit, delete people
- Add birthday with and without year
- Create gift maps with items
- Generate and test share links
- Reserve items on shared maps
- Create events with different types
- Verify notifications trigger
- Add history with photos
- Create and manage groups
- Add/remove members from groups
- Export events to calendar
- Test offline functionality
- Create an event for tomorrow
- Enable reminders
- Set device time forward 23 hours
- Verify notification appears
# Install EAS CLI
npm install -g eas-cli
# Configure EAS
eas build:configure
# Build for iOS
eas build --platform ios
# Submit to App Store
eas submit --platform ios# Build for Android
eas build --platform android
# Submit to Play Store
eas submit --platform android- Email/password authentication via Firebase
- No user data stored in AsyncStorage
- Secure token management by Firebase SDK
- User data isolated per Firebase Auth UID
- Firestore security rules enforce user boundaries
- Shared gift maps use UUID tokens (not user IDs)
- Never commit
firebase.config.tsto version control - Use environment variables for sensitive data
- Validate all user inputs
- Sanitize URLs before opening
Contributions are welcome! Please follow these steps:
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
feat: Add new feature
fix: Fix bug
docs: Update documentation
style: Format code
refactor: Refactor code
test: Add tests
chore: Update dependencies
This project is licensed under the MIT License - see the LICENSE file for details.
- Design inspired by Cartier, Rolex, and Tiffany & Co.
- Built with React Native and Expo
- Backend powered by Firebase
- Icons from Expo Icons
If you have any questions or need help:
- π Issues: GitHub Issues
- π¬ Discussions: GitHub Discussions
- Add web version using React Native Web
- Implement push notifications (FCM)
- Add social authentication (Google, Apple)
- Create gift recommendations AI
- Add collaborative shopping lists
- Integrate with Amazon/shopping APIs
- Add budget tracking
- Create gift wrapping tracker
- Add multi-language support
- Dark mode
Made with β€οΈ and attention to detail