Skip to content

CodeDaim0n/nextjs-with-supabase

Repository files navigation

Tasksmith (TSM) - Minimalist Todo Application

A modern, minimalist todo application built with Next.js and Supabase, featuring per-user task management, optimistic UI updates, and comprehensive filtering/sorting capabilities.

Features

  • Secure Authentication: Built-in authentication with Supabase Auth
  • Per-User Tasks: Row-Level Security ensures users only see their own tasks
  • Optimistic UI: Instant feedback with graceful error handling
  • Advanced Filtering: Filter by status, priority, due date, and search by title
  • Flexible Sorting: Sort by any column (title, status, priority, due date, updated date)
  • Responsive Design: Works seamlessly on desktop and mobile devices
  • Real-time Updates: React Query ensures data consistency across tabs
  • Modern UI: Built with shadcn/ui components and Tailwind CSS

Tech Stack

  • Frontend: Next.js 15, React 19, TypeScript
  • Backend: Supabase (PostgreSQL + Auth + RLS)
  • UI: Tailwind CSS, shadcn/ui, Radix UI primitives
  • State Management: TanStack Query (React Query), Zustand for local state
  • Date Handling: date-fns
  • Table: TanStack Table

Getting Started

Prerequisites

  • Node.js 18+ and npm
  • A Supabase project

1. Clone and Install

git clone <your-repo>
cd nextjs-with-supabase
npm install

2. Environment Setup

Create a .env.local file:

NEXT_PUBLIC_SUPABASE_URL=your_supabase_project_url
NEXT_PUBLIC_SUPABASE_PUBLISHABLE_OR_ANON_KEY=your_supabase_anon_key

3. Database Setup

Run the following SQL in your Supabase SQL editor to set up the database schema:

-- Create enum types for todo status and priority
CREATE TYPE todo_status AS ENUM ('todo', 'in_progress', 'done', 'blocked');
CREATE TYPE todo_priority AS ENUM ('low', 'medium', 'high', 'urgent');

-- Create todos table
CREATE TABLE IF NOT EXISTS public.todos (
  id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
  user_id UUID NOT NULL REFERENCES auth.users(id) ON DELETE CASCADE,
  title TEXT NOT NULL CHECK (char_length(title) BETWEEN 1 AND 140),
  description TEXT,
  status todo_status NOT NULL DEFAULT 'todo',
  due_date TIMESTAMPTZ,
  priority todo_priority NOT NULL DEFAULT 'medium',
  created_at TIMESTAMPTZ NOT NULL DEFAULT now(),
  updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
);

-- Create indexes for performance
CREATE INDEX IF NOT EXISTS idx_todos_user_id ON public.todos(user_id);
CREATE INDEX IF NOT EXISTS idx_todos_due ON public.todos(due_date DESC NULLS LAST);
CREATE INDEX IF NOT EXISTS idx_todos_status ON public.todos(status);
CREATE INDEX IF NOT EXISTS idx_todos_priority ON public.todos(priority DESC);

-- Enable trigram extension for text search (if not already enabled)
CREATE EXTENSION IF NOT EXISTS pg_trgm;
CREATE INDEX IF NOT EXISTS idx_todos_title_trgm ON public.todos USING gin (title gin_trgm_ops);

-- Enable Row Level Security
ALTER TABLE public.todos ENABLE ROW LEVEL SECURITY;

-- Create RLS policies
CREATE POLICY "select_own" ON public.todos FOR SELECT USING (user_id = auth.uid());
CREATE POLICY "insert_own" ON public.todos FOR INSERT WITH CHECK (user_id = auth.uid());
CREATE POLICY "update_own" ON public.todos FOR UPDATE USING (user_id = auth.uid());
CREATE POLICY "delete_own" ON public.todos FOR DELETE USING (user_id = auth.uid());

-- Create function to automatically update updated_at timestamp
CREATE OR REPLACE FUNCTION public.set_updated_at() RETURNS TRIGGER AS $$
BEGIN 
  NEW.updated_at = now(); 
  RETURN NEW; 
END; 
$$ LANGUAGE plpgsql;

-- Create trigger to automatically update updated_at
CREATE TRIGGER set_updated_at 
  BEFORE UPDATE ON public.todos
  FOR EACH ROW 
  EXECUTE PROCEDURE public.set_updated_at();

4. Run the Application

npm run dev

Open http://localhost:3000 to view the application.

Project Structure

├── app/                      # Next.js app directory
│   ├── auth/                 # Authentication pages
│   ├── protected/            # Protected todo dashboard
│   ├── layout.tsx           # Root layout with providers
│   └── page.tsx             # Landing page
├── components/              # React components
│   ├── ui/                  # shadcn/ui components
│   ├── todo-dashboard.tsx   # Main dashboard
│   ├── todo-table.tsx       # Data table with sorting
│   ├── todo-filters.tsx     # Filtering sidebar
│   ├── todo-quick-add.tsx   # Quick add form
│   └── todo-edit-dialog.tsx # Edit modal
├── lib/                     # Utilities and configurations
│   ├── hooks/               # Custom hooks (todo operations)
│   ├── providers/           # React Query provider
│   ├── types/               # TypeScript type definitions
│   └── supabase/            # Supabase client configuration
└── supabase/
    └── migrations/          # Database schema

Key Features in Detail

Todo Management

  • Quick Add: Fast todo creation with expandable detailed form
  • Inline Editing: Update status and priority directly in the table
  • Full Edit Modal: Comprehensive editing with all fields
  • Optimistic Updates: Instant UI feedback with rollback on errors

Filtering & Sorting

  • Status Filters: Filter by todo, in_progress, done, blocked
  • Priority Filters: Filter by low, medium, high, urgent priority levels
  • Date Presets: Quick filters for "Due Today", "This Week", "Overdue"
  • Text Search: Search todos by title with trigram matching
  • Multi-Column Sorting: Sort by any column with visual indicators

UI/UX

  • Responsive Design: Optimized for mobile and desktop
  • Dark/Light Mode: Theme switching with system preference detection
  • Loading States: Skeleton loaders and loading indicators
  • Error Handling: User-friendly error messages with retry options
  • Empty States: Helpful messaging when no todos exist

Data & Security

  • Row-Level Security: Users can only access their own todos
  • Real-time Sync: React Query ensures data consistency
  • Optimistic UI: Instant updates with server synchronization
  • Data Validation: Client and server-side validation

Development

Available Scripts

  • npm run dev - Start development server
  • npm run build - Build for production
  • npm run start - Start production server
  • npm run lint - Run ESLint

Key Dependencies

  • @tanstack/react-query - Server state management with optimistic updates
  • @tanstack/react-table - Powerful table with sorting and filtering
  • @radix-ui/ - Accessible UI primitives
  • date-fns - Date manipulation and formatting
  • zustand - Lightweight state management

Architecture Decisions

  1. Optimistic UI: All mutations use optimistic updates for better UX
  2. React Query: Centralized server state management with caching
  3. Row-Level Security: Database-level security for multi-tenant data
  4. Component Composition: Modular components for maintainability
  5. TypeScript: Full type safety throughout the application

Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make your changes
  4. Add tests if applicable
  5. Submit a pull request

License

This project is licensed under the MIT License.

Releases

No releases published

Packages

 
 
 

Contributors