Vue 3 + Nuxt 3 frontend for the Color Palette Tool application, allowing users to create and manage color palettes from images.
- Features
- Tech Stack
- Setup Requirements
- Getting Started
- Project Structure
- Development Workflow
- Deployment
- Troubleshooting
- Backend Repository
- Upload images via URL or local filesystem
- Browse local image collection
- Create named color palettes from images
- Manual color selection by clicking on images
- Automatic K-means clustering color extraction
- Color editing via RGB/HSV input or native color picker
- Image pixel sampling for color extraction
- Swatch reordering and deletion
- Export palettes as JSON (compatible with flock-of-postcards format)
- Responsive design for desktop and mobile
- Framework: Vue 3 + Nuxt 3
- Language: TypeScript
- State Management: Pinia
- Styling: Tailwind CSS
- HTTP Client: Fetch API / Axios
- Testing: Vitest + Vue Test Utils
- Design: Figma
- Build Tool: Vite (via Nuxt)
-
Node.js version
- Node.js 16+ (LTS recommended)
- npm or yarn
-
System dependencies
- Backend API running (see Backend Repository section)
-
Configuration
- Set up environment variables in
.envfile
- Set up environment variables in
# Clone the repository (if not already done)
git clone <repository-url>
cd color-palette-frontend
# Install dependencies
npm install
# or
yarn install# Start the development server
npm run dev
# or
yarn devThe frontend will be available at http://localhost:3000.
Create a .env file in the root directory with the following variables:
API_BASE_URL=http://localhost:3001/api/v1
IMAGE_METADATA_JSONL_FILE=/absolute/path/to/your/image_metadata.jsonl
API_BASE_URL: Configures the frontend to connect to the backend APIIMAGE_METADATA_JSONL_FILE: Absolute path to the JSONL file containing image metadata
color-palette-frontend/
├── assets/ # Static assets and CSS
├── components/ # Vue components
├── layouts/ # Nuxt layouts
├── pages/ # Nuxt pages
├── plugins/ # Nuxt plugins
├── public/ # Public static files
├── stores/ # Pinia stores
├── types/ # TypeScript type definitions
├── composables/ # Vue composables
├── utils/ # Utility functions
├── middleware/ # Nuxt middleware
├── server/ # Server-side code (if any)
├── nuxt.config.ts # Nuxt configuration
├── tailwind.config.js # Tailwind CSS configuration
├── tsconfig.json # TypeScript configuration
└── package.json # Project dependencies and scripts
Components are stored in the components/ directory and are auto-imported by Nuxt.
# Create a new component
touch components/ColorPicker.vueExample component structure:
<template>
<div class="color-picker">
<!-- Component template -->
</div>
</template>
<script setup lang="ts">
// Component logic using Vue 3 Composition API
const props = defineProps<{
initialColor: string
}>()
const emit = defineEmits<{
(e: 'update:color', color: string): void
}>()
// Component logic
</script>
<style scoped>
/* Component styles (if not using Tailwind) */
</style>This project uses Pinia for state management. Stores are located in the stores/ directory.
Example store:
// stores/palette.ts
import { defineStore } from 'pinia'
interface Color {
id: string
hex: string
rgb: [number, number, number]
hsv: [number, number, number]
position: number
}
interface Palette {
id: string
name: string
imageId: string
colors: Color[]
}
export const usePaletteStore = defineStore('palette', {
state: () => ({
palettes: [] as Palette[],
currentPalette: null as Palette | null,
loading: false,
error: null as string | null
}),
actions: {
async fetchPalettes() {
// Implementation
},
async createPalette(palette: Omit<Palette, 'id'>) {
// Implementation
}
// Other actions
}
})Usage in components:
import { usePaletteStore } from '~/stores/palette'
const paletteStore = usePaletteStore()
await paletteStore.fetchPalettes()API calls are made using the Fetch API or Axios. The base URL is configured in nuxt.config.ts:
// nuxt.config.ts
export default defineNuxtConfig({
// ...
runtimeConfig: {
public: {
apiBase: process.env.API_BASE_URL || 'http://localhost:3001/api/v1'
}
}
// ...
})Example API call in a component or store:
const config = useRuntimeConfig()
const { data, error } = await useFetch(`${config.public.apiBase}/images`)This project uses Vitest for testing Vue components and stores.
# Run all tests
npm test
# or
yarn test
# Run tests with UI
npm run test:ui
# or
yarn test:ui
# Run tests with coverage
npm run test:coverage
# or
yarn test:coverageExample component test:
// components/__tests__/ColorPicker.test.ts
import { describe, it, expect } from 'vitest'
import { mount } from '@vue/test-utils'
import ColorPicker from '../ColorPicker.vue'
describe('ColorPicker', () => {
it('renders correctly with initial color', () => {
const wrapper = mount(ColorPicker, {
props: {
initialColor: '#FF5733'
}
})
expect(wrapper.find('.color-picker').exists()).toBe(true)
// More assertions
})
// More tests
})# Build the application
npm run build
# or
yarn buildThis creates a .output directory with the production build.
# Generate static site
npm run generate
# or
yarn generateThis creates a dist directory with static HTML files.
# Build Docker image
docker build -t color-palette-frontend .
# Run Docker container
docker run -p 3000:3000 color-palette-frontend-
Clear Nuxt cache:
npx nuxi cleanup
-
Verify Node.js version:
node -v
Should be v16.0.0 or higher.
-
Check npm/yarn version:
npm -v # or yarn -v -
Reinstall dependencies:
rm -rf node_modules npm install # or yarn install -
Check API connectivity: Ensure the backend API is running at the URL specified in your
.envfile.
The backend API code is available at:
/Users/sbecker11/color-palette-app/color-palette-api
Make sure the API is running before starting the frontend development server.