help me project setup from scratch
"Generate project setup using Vite, TypeScript, Tailwind CSS, and ShadCN/UI. Structure the project as follows:
Ui/: Shared UI components using ShadCN UI (e.g., buttons, modals, inputs).
Loader/: A reusable loading spinner.
Sidebar/: A collapsible sidebar with navigation links.
Tooltips/: Tooltip components for hints.
Header/: A responsive header with a title and user profile.
Helper methods and reusable utility functions.
Context providers for sidebar, theme, and header states.
useApi: A custom fetch hook for API calls.
useMutation: Hook for handling mutations.
useQuery: Hook for fetching data efficiently.
endpoints.ts: API endpoint configurations.
path.ts: Route path constants.
constant.ts: Global constant values.
regex.ts: Common regex patterns.
Dashboard/: Includes component/, api-service.ts, data-types.ts, and dashboard.tsx.
Common/: Authentication pages (Login.tsx, SignUp.tsx).
Other components as needed.
Layout.tsx: Manages routes and child components.
Routes.tsx: Handles application routing.
Ensure proper TypeScript types for all API responses and state management using React Context. Implement lazy loading and error boundaries for better performance. Use ShadCN UI components efficiently for a modern design. Set up a basic authentication flow with protected routes and user session handling.*
I'll help you set up a complete project structure using Vite, TypeScript, Tailwind CSS, and ShadCN UI. Let's start by creating the project and configuring all the required components.
I've created a comprehensive project setup using Vite, TypeScript, Tailwind CSS, and ShadCN UI. Here's a breakdown of the structure:
To use this project:
npm install
npm run dev
The project is set up with all the required components and structure as specified in your requirements. You can extend it by adding more views, components, or functionality as needed.
Here's a step-by-step guide to set up the project from scratch:
# Create a new Vite project with React and TypeScript
npm create vite@latest my-app --template react-ts
# Navigate to the project directory
cd my-app
# Install React Router and other core dependencies
npm install react-router-dom zod @hookform/resolvers clsx tailwind-merge react-hook-form lucide-react class-variance-authority
# Install Tailwind CSS and its dependencies
npm install tailwindcss @tailwindcss/vite tailwindcss-animate
# Create tailwind.config.ts
npx tailwindcss init -p
# Install shadcn CLI
npm install -D @types/node
# Initialize shadcn/ui
npx shadcn@latest init
When prompted during the shadcn/ui initialization:
src/index.css
tailwind.config.ts
@/components
@/lib/utils
# Install required shadcn/ui components
npx shadcn@latest add button card form input avatar dropdown-menu toast tooltip tabs separator
# Create the main directories
mkdir -p src/components/{loader,sidebar,header,tooltips,error-boundary} src/context src/hooks src/lib src/view/{dashboard/components,common}
Create or update the vite.config.ts
file with the following content:
# Create vite.config.ts
cat > vite.config.ts << 'EOL'
import path from "path"
import tailwindcss from "@tailwindcss/vite"
import react from "@vitejs/plugin-react"
import { defineConfig } from "vite"
export default defineConfig({
plugins: [react(), tailwindcss()],
resolve: {
alias: {
"@": path.resolve(__dirname, "./src"),
},
},
})
EOL
Update the tsconfig.json
file to include path aliases:
# Update tsconfig.json for path aliases
cat > tsconfig.json << 'EOL'
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
/* Bundler mode */
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
/* Linting */
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true,
/* Paths */
"baseUrl": ".",
"paths": {
"@/*": ["./src/*"]
}
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}
EOL
# Update index.css for Tailwind
cat > src/index.css << 'EOL'
@import "tailwindcss";
@layer base {
:root {
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;
--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;
--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;
--primary: 221.2 83.2% 53.3%;
--primary-foreground: 210 40% 98%;
--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;
--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;
--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;
--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;
--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 221.2 83.2% 53.3%;
--radius: 0.5rem;
/* Sidebar variables */
--sidebar-background: 0 0% 98%;
--sidebar-foreground: 240 5.3% 26.1%;
--sidebar-primary: 240 5.9% 10%;
--sidebar-primary-foreground: 0 0% 98%;
--sidebar-accent: 240 4.8% 95.9%;
--sidebar-accent-foreground: 240 5.9% 10%;
--sidebar-border: 220 13% 91%;
--sidebar-ring: 217.2 91.2% 59.8%;
}
.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;
--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;
--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;
--primary: 217.2 91.2% 59.8%;
--primary-foreground: 222.2 47.4% 11.2%;
--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;
--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;
--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;
--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;
--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 224.3 76.3% 48%;
/* Sidebar variables for dark mode */
--sidebar-background: 240 5.9% 10%;
--sidebar-foreground: 240 4.8% 95.9%;
--sidebar-primary: 0 0% 98%;
--sidebar-primary-foreground: 240 5.9% 10%;
--sidebar-accent: 240 3.7% 15.9%;
--sidebar-accent-foreground: 240 4.8% 95.9%;
--sidebar-border: 240 3.7% 15.9%;
--sidebar-ring: 217.2 91.2% 59.8%;
}
}
@layer base {
* {
@apply border-border;
}
body {
@apply bg-background text-foreground;
font-feature-settings: "rlig" 1, "calt" 1;
}
}
EOL
# Update tailwind.config.ts
cat > tailwind.config.ts << 'EOL'
import type { Config } from "tailwindcss"
const config = {
darkMode: ["class"],
content: ["./pages/**/*.{ts,tsx}", "./components/**/*.{ts,tsx}", "./app/**/*.{ts,tsx}", "./src/**/*.{ts,tsx}", "*.{js,ts,jsx,tsx,mdx}"],
prefix: "",
theme: {
container: {
center: true,
padding: "2rem",
screens: {
"2xl": "1400px",
},
},
extend: {
colors: {
border: "hsl(var(--border))",
input: "hsl(var(--input))",
ring: "hsl(var(--ring))",
background: "hsl(var(--background))",
foreground: "hsl(var(--foreground))",
primary: {
DEFAULT: "hsl(var(--primary))",
foreground: "hsl(var(--primary-foreground))",
},
secondary: {
DEFAULT: "hsl(var(--secondary))",
foreground: "hsl(var(--secondary-foreground))",
},
destructive: {
DEFAULT: "hsl(var(--destructive))",
foreground: "hsl(var(--destructive-foreground))",
},
muted: {
DEFAULT: "hsl(var(--muted))",
foreground: "hsl(var(--muted-foreground))",
},
accent: {
DEFAULT: "hsl(var(--accent))",
foreground: "hsl(var(--accent-foreground))",
},
popover: {
DEFAULT: "hsl(var(--popover))",
foreground: "hsl(var(--popover-foreground))",
},
card: {
DEFAULT: "hsl(var(--card))",
foreground: "hsl(var(--card-foreground))",
},
sidebar: {
DEFAULT: "hsl(var(--sidebar-background))",
foreground: "hsl(var(--sidebar-foreground))",
border: "hsl(var(--sidebar-border))",
ring: "hsl(var(--sidebar-ring))",
accent: "hsl(var(--sidebar-accent))",
"accent-foreground": "hsl(var(--sidebar-accent-foreground))",
},
},
borderRadius: {
lg: "var(--radius)",
md: "calc(var(--radius) - 2px)",
sm: "calc(var(--radius) - 4px)",
},
keyframes: {
"accordion-down": {
from: { height: "0" },
to: { height: "var(--radix-accordion-content-height)" },
},
"accordion-up": {
from: { height: "var(--radix-accordion-content-height)" },
to: { height: "0" },
},
},
animation: {
"accordion-down": "accordion-down 0.2s ease-out",
"accordion-up": "accordion-up 0.2s ease-out",
},
},
},
plugins: [require("tailwindcss-animate")],
} satisfies Config
export default config
EOL
# Create utils.ts
mkdir -p src/lib
cat > src/lib/utils.ts << 'EOL'
import { type ClassValue, clsx } from "clsx"
import { twMerge } from "tailwind-merge"
/**
* Combines class names with Tailwind CSS classes
*/
export function cn(...inputs: ClassValue[]) {
return twMerge(clsx(inputs))
}
/**
* Format a date to a readable string
*/
export function formatDate(date: Date | string, options?: Intl.DateTimeFormatOptions) {
const defaultOptions: Intl.DateTimeFormatOptions = {
year: "numeric",
month: "short",
day: "numeric",
}
const dateObj = typeof date === "string" ? new Date(date) : date
return new Intl.DateTimeFormat("en-US", options || defaultOptions).format(dateObj)
}
/**
* Truncate a string to a specified length
*/
export function truncateString(str: string, maxLength: number = 50) {
if (str.length <= maxLength) return str
return `${str.slice(0, maxLength)}...`
}
/**
* Debounce a function
*/
export function debounce<T extends (...args: any[]) => any>(
func: T,
wait: number
): (...args: Parameters<T>) => void {
let timeout: ReturnType<typeof setTimeout> | null = null
return function(...args: Parameters<T>) {
if (timeout) clearTimeout(timeout)
timeout = setTimeout(() => func(...args), wait)
}
}
/**
* Generate a random ID
*/
export function generateId(length: number = 8) {
return Math.random().toString(36).substring(2, 2 + length)
}
EOL
# Start the development server
npm run dev
After running these commands, you'll have a basic project structure set up with Vite, TypeScript, Tailwind CSS, and shadcn/ui. You can then start implementing the components, contexts, hooks, and views as shown in the previous code examples.
The project will be accessible at http://localhost:5173 (or another port if 5173 is already in use).
After setting up the basic structure, you can:
This will give you the complete project as shown in the previous examples.