Modern dark-themed task management UI built with Nuxt 3 and Vue.js.
- π Create, view, and delete tasks
- π·οΈ Change task status (To Do β In Progress β Done)
- π Optional due date with native datetime picker
- π Paginated task list responsive grid
- π Modern dark theme (Slate color palette)
- π Toast notifications for user feedback
- β Form validation
- π± Responsive design (mobile, tablet, desktop)
- Framework: Nuxt 3 (Vue.js 3)
- UI Library: Nuxt UI (based on Headless UI)
- Styling: Tailwind CSS
- HTTP Client: Nuxt
$fetch - State Management: Vue Composition API + Refs
- TypeScript: Full type safety
- Linting: ESLint + TypeScript
- Node.js 18+
- npm or yarn
npm installBy default, the frontend connects to http://localhost:8080/api/v1.
To change this, set an environment variable:
# .env file or export in shell
NUXT_PUBLIC_API_BASE=http://localhost:8080/api/v1Or edit nuxt.config.ts directly.
# Development with hot reload
npm run dev
# Build and preview production
npm run build
npm run previewThe app will be available at http://localhost:3000 (or another port if 3000 is taken).
βββ components/
β βββ TaskCard.vue # Single task display card
β βββ TaskForm.vue # Create/edit task form
β βββ TaskList.vue # Task grid with pagination
βββ composables/
β βββ useTaskApi.ts # API function layer
βββ layouts/
β βββ default.vue # Default page layout
βββ pages/
β βββ index.vue # Main page (home)
βββ types/
β βββ task.ts # TypeScript interfaces
βββ assets/
β βββ css/
β βββ main.css # Global styles + dark theme
βββ nuxt.config.ts # Nuxt configuration
βββ package.json
βββ tsconfig.json
nuxt.config.ts exposes useRuntimeConfig().public.apiBase which can be set via:
- Environment variable:
NUXT_PUBLIC_API_BASE - Default in config:
http://localhost:8080/api/v1
The app uses Nuxt UI's dark theme. To change colors, edit nuxt.config.ts:
ui: {
colors: {
primary: 'blue', // Options: 'blue', 'green', 'purple', etc.
gray: 'slate' // Grayscale palette
},
dark: true
}Displays individual task with:
- Title and description
- Status badge with color coding
- Due date and creation date
- Action buttons: Change status (if not current), Delete
Props:
task: Task- Task objectdeleting?: boolean- Show loading on delete button
Events:
delete(id: number)updateStatus(id: number, status: TaskStatus)
Form for creating/editing tasks with validation.
Props:
task?: Task- If provided, form enters edit mode
Events:
submit(data: CreateTaskRequest)cancel
Fields:
- Title (required)
- Description (optional)
- Status (required)
- Due Date (optional, native datetime picker)
Displays paginated grid of task cards.
Features:
- Auto-loads tasks on mount
- Pagination controls with page numbers
- Shows total count and current page
- Handles loading and error states
Exposed:
refresh()- Reload taskstotalElements- Total task count
All API calls are in composables/useTaskApi.ts:
const {
fetchPaginatedTasks, // (page: 0, size: 20) => PaginatedResponse<Task>
fetchTask, // (id: number) => Task
createTask, // (request: CreateTaskRequest) => Task
updateTaskStatus, // (id, status) => Task
deleteTask // (id: number) => void
} = useTaskApi()All functions throw errors on failure - catch and display with $toast.
Defined in types/task.ts:
Task- Full task objectCreateTaskRequest- Create payloadUpdateTaskStatusRequest- Status update payloadTaskStatus- Enum:TO_DO,IN_PROGRESS,DONEPaginatedResponse<T>- Generic paginated response
Primary grayscale (Slate):
- Background:
#0f172a(Slate 900) - Card:
#1e293b(Slate 800) - Text:
#f1f5f9(Slate 100) - Muted:
#94a3b8(Slate 400)
Accent colors:
- Primary/Blue:
#3b82f6 - Success/Green: Various greens
- Danger/Red:
#dc2626
Global styles in assets/css/main.css. Tailwind classes used throughout components.
# Build
npm run build
# Output in .output/ directory
# - .output/public/ (static assets)
# - .output/server/ (server bundle)Deploy the .output/public folder to any static hosting (Vercel, Netlify, etc.). The app is fully server-side rendered (SSR) by default.
| Variable | Description | Default |
|---|---|---|
NUXT_PUBLIC_API_BASE |
Backend API URL | http://localhost:8080/api/v1 |
Create a .env file in the frontend directory:
NUXT_PUBLIC_API_BASE=https://api.yourdomain.com/api/v1- Changes to
.vuefiles automatically hot reload - Nuxt DevTools available via
Shift + Option + D(Mac) orShift + Alt + D(Windows/Linux)
- Check browser DevTools Console for errors
- Network tab to inspect API calls
- Vue DevTools for component state
- Nuxt DevTools for module/project info
"Failed to load tasks" error:
- Ensure backend is running on
localhost:8080 - Check CORS configuration in backend
- Verify
NUXT_PUBLIC_API_BASEis correct
Date picker not closing:
- Native picker closes on outside click
- "Set" button can be used to explicitly close (if enabled)
Simply connect your repository and deploy. The build command is npm run build.
Make sure to set NUXT_PUBLIC_API_BASE to your production backend URL in the hosting platform's environment variables.
Create a Dockerfile:
FROM node:18-alpine AS build
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build
FROM node:18-alpine
WORKDIR /app
COPY --from=build /app/.output ./.output
COPY package.json .
EXPOSE 3000
CMD ["node", ".output/server/index.mjs"]| Script | Description |
|---|---|
npm run dev |
Start development server with hot reload |
npm run build |
Build for production |
npm run preview |
Preview production build locally |
npm run lint |
Run ESLint |
npm run lint:fix |
Fix linting errors |
- Follow Vue.js and Nuxt 3 best practices
- Use Composition API with
<script setup> - Keep components small and focused
- Add TypeScript types for all props/data
- Test on both light and dark themes if adding new colors
- Ensure API calls go through
useTaskApi.ts(single source of truth)
Educational/Demonstration project.
- Backend Repository:
../backend(if monorepo) or separate backend repo - API Documentation: See
backend/API.md - Nuxt UI Docs: https://ui.nuxt.com
- Tailwind CSS: https://tailwindcss.com
Happy Building! π