Skip to content

Repository files navigation

Constara 🌐

A modern full-stack web app for digitizing and managing business card contacts — with OCR scanning, duplicate detection, and LinkedIn integration.

Tech Stack

  • Frontend: Next.js 14 (App Router) + React 18 + Tailwind CSS
  • Backend: Next.js API Routes
  • Database: Firebase Firestore
  • Auth: Firebase Authentication (email/password)
  • Storage: Firebase Storage
  • OCR: Tesseract.js (client-side + server-side)

Setup Guide

1. Install dependencies

cd constara
npm install

2. Firebase Setup

  1. Go to Firebase Console

  2. Create a new project (or use existing)

  3. Enable these services:

    • Authentication → Sign-in method → Email/Password ✓
    • Firestore Database → Create database (start in test mode for dev)
    • Storage → Get started
  4. Get your config:

    • Project Settings → General → Your apps → Add web app
    • Copy the firebaseConfig values

3. Configure Environment

Edit .env.local with your Firebase credentials:

NEXT_PUBLIC_FIREBASE_API_KEY=AIza...
NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=your-project.firebaseapp.com
NEXT_PUBLIC_FIREBASE_PROJECT_ID=your-project-id
NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET=your-project.appspot.com
NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=123456789
NEXT_PUBLIC_FIREBASE_APP_ID=1:123:web:abc

4. Firestore Security Rules

In Firebase Console → Firestore → Rules:

rules_version = '2';
service cloud.firestore {
  match /databases/{database}/documents {
    match /users/{userId} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
    match /contacts/{contactId} {
      allow read, write: if request.auth != null && request.auth.uid == resource.data.userId;
      allow create: if request.auth != null && request.auth.uid == request.resource.data.userId;
    }
  }
}

5. Storage Security Rules

In Firebase Console → Storage → Rules:

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /cards/{userId}/{allPaths=**} {
      allow read, write: if request.auth != null && request.auth.uid == userId;
    }
  }
}

6. Create Firestore Indexes

The app needs a composite index for contacts. Firebase will prompt you to create it automatically when you first query — or create it manually:

  • Collection: contacts
  • Fields: userId (Ascending), isDeleted (Ascending), createdAt (Descending)

7. Run Development Server

npm run dev

Open http://localhost:3000


Features

📸 Business Card OCR

  • Upload PNG/JPG/WEBP images
  • Auto-extract: name, email, phone, company, title, location
  • Review and edit before saving

🔁 Duplicate Detection

  • Checks email, phone, name+company
  • Shows modal to update existing or create new

🔍 Smart Search

  • Real-time search across name, company, email, notes
  • Grid and list view toggle

🔗 LinkedIn Integration

  • Save LinkedIn URLs manually
  • One-click Google search: site:linkedin.com/in "Name" "Company"

✏️ Full Contact Management

  • Create, read, update, soft-delete
  • Manual entry or OCR upload

Project Structure

constara/
├── app/
│   ├── layout.tsx          # Root layout + Auth context
│   ├── page.tsx            # Root redirect
│   ├── dashboard/          # Main contacts dashboard
│   ├── login/              # Login page
│   ├── signup/             # Sign up page
│   ├── upload/             # Business card upload + OCR
│   ├── contacts/
│   │   ├── page.tsx        # Contacts list
│   │   └── new/page.tsx    # Manual contact creation
│   ├── contact/[id]/       # Contact detail + edit
│   ├── settings/           # User settings
│   └── api/
│       ├── ocr/route.ts    # OCR endpoint
│       └── contacts/       # CRUD endpoints
│
├── components/
│   ├── ContactCard.tsx     # Grid card component
│   ├── ContactForm.tsx     # Create/edit form
│   ├── UploadCard.tsx      # Drag-drop upload
│   ├── Navbar.tsx          # Top navigation
│   ├── Sidebar.tsx         # Side navigation
│   ├── SearchBar.tsx       # Search input
│   └── DuplicateModal.tsx  # Duplicate warning
│
├── lib/
│   ├── firebase.ts         # Firebase initialization
│   ├── auth.ts             # Auth functions
│   ├── db.ts               # Firestore CRUD
│   ├── storage.ts          # Image uploads
│   ├── ocr.ts              # OCR (client-side)
│   └── duplicateCheck.ts   # Duplicate logic
│
└── types/index.ts          # TypeScript types

OCR Tips

For best results:

  • Use clear, well-lit photos
  • Avoid glare and shadows
  • Keep the card flat and centered
  • Higher resolution = better accuracy

The OCR uses Tesseract.js which runs in the browser (no external API needed). Processing takes 3-8 seconds depending on image quality.

About

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages