A modern, responsive ticket management application built with Vue 3, TypeScript, and Tailwind CSS. This is a carbon copy migration from the original React implementation, maintaining exact feature parity and user experience.
- Landing Page with wavy SVG background and decorative elements
- Authentication System with login/signup and session management
- Dashboard with ticket statistics and quick navigation
- Complete CRUD Operations for ticket management
- Responsive Design optimized for mobile, tablet, and desktop
- Responsive Sidebar with mobile hamburger menu
- Form Validation with real-time error handling
- Toast Notifications for user feedback
- Protected Routes with session-based authentication
- โ Max-width 1440px centered layout
- โ Wavy background hero section
- โ Decorative circle elements
- โ Card-style boxes with shadows and rounded corners
- โ Responsive mobile/tablet/desktop layouts
- โ Complete authentication with localStorage session management
- โ Full ticket CRUD with validation
- โ Status-based color coding (green/amber/gray)
- โ Accessibility compliance with semantic HTML
- โ Error handling for all scenarios
- Vue 3.5.22 - Progressive JavaScript framework with Composition API
- TypeScript 5.9.3 - Type-safe development
- Pinia 3.0.3 - Official Vue state management library
- Vue Router 4.6.3 - Client-side routing with navigation guards
- shadcn-vue - High-quality, accessible UI components
- Tailwind CSS 4.1.16 - Utility-first CSS framework
- vue-sonner 2.x - Beautiful toast notifications
- Vite 7.1.12 - Next-generation frontend tooling
- Node.js (version 16 or higher)
- pnpm package manager
-
Clone or download the project
cd /path/to/stage2-vue -
Install dependencies
pnpm install
-
Start the development server
pnpm dev
-
Open your browser
- Navigate to
http://localhost:5173 - The application will automatically reload when you make changes
- Navigate to
pnpm buildpnpm previewsrc/
โโโ components/
โ โโโ forms/
โ โ โโโ CreateTicketForm.vue # Create ticket modal
โ โ โโโ EditTicketForm.vue # Edit ticket modal
โ โโโ layout/
โ โ โโโ AppLayout.vue # Main app layout wrapper
โ โ โโโ Sidebar.vue # Responsive sidebar (desktop/mobile)
โ โ โโโ Footer.vue # Footer component
โ โโโ ui/
โ โโโ StatusBadge.vue # Ticket status badge
โ โโโ WaveBackground.vue # SVG wave decoration
โ โโโ DecorativeCircle.vue # Floating circles
โ โโโ [shadcn components] # UI primitives
โโโ composables/
โ โโโ useToast.ts # Toast notification wrapper
โโโ stores/
โ โโโ auth.ts # Pinia auth store
โ โโโ tickets.ts # Pinia tickets store
โโโ router/
โ โโโ index.ts # Vue Router configuration
โโโ types/
โ โโโ index.ts # TypeScript type definitions
โโโ utils/
โ โโโ statusColors.ts # Status color mappings
โโโ views/
โ โโโ LandingPage.vue # Public landing page
โ โโโ LoginPage.vue # Login form
โ โโโ SignupPage.vue # Signup form
โ โโโ Dashboard.vue # Dashboard with stats
โ โโโ TicketManagement.vue # Ticket CRUD interface
โโโ main.ts # Application entry point
This Vue implementation maintains exact feature parity with the React version:
- React Context API โ Pinia Stores
useState/useEffectโref/reactive/onMountedcreateContextโdefineStore- React Router โ Vue Router
- Props drilling โ Props with TypeScript interfaces
classNameโclass- Event handlers:
onClickโ@click
- Title: Required, 3-100 characters
- Description: Optional, max 500 characters
- Status: Required, one of: open/in_progress/closed
- Priority: Optional, one of: low/medium/high
- Email: Required, valid email format
- Password: Required, min 6 characters
- Name: Required, min 2 characters
- "Account created successfully! Welcome to Ticketly!"
- "Welcome back to Ticketly!"
- "Invalid email or password. Please check your credentials and try again."
- "Email already exists. Please use a different email or login."
- "Ticket created successfully!"
- "Ticket updated successfully!"
- "Ticket deleted successfully!"
- "Please fix the errors below"
User Object:
{
id: string; // Format: "user_" + timestamp
name: string;
email: string;
password: string;
}Ticket Object:
{
id: string // Format: "ticket_" + timestamp + "_" + random
title: string // 3-100 characters
description?: string // Max 500 characters
status: 'open' | 'in_progress' | 'closed'
priority?: 'low' | 'medium' | 'high'
createdBy: string // User ID
createdAt: string // ISO date string
updatedAt: string // ISO date string
}Session Token:
string; // Format: "token_" + timestamp + "_" + random- User State: Current logged-in user information
- Session Management: localStorage-based session tokens
- Actions:
login(),signup(),logout(),initializeAuth() - Data: Stored in
ticketapp_session,ticketapp_user,ticketapp_users
- Ticket State: Reactive array of all tickets
- CRUD Actions:
addTicket(),updateTicket(),deleteTicket(),loadTickets() - Getters:
getTicketStats()for dashboard metrics - Data: Persisted in
ticketapp_ticketslocalStorage key
All data is stored in localStorage with the following keys:
ticketapp_session: Current user session tokenticketapp_user: Current user informationticketapp_users: Database of all registered usersticketapp_tickets: Array of all tickets
- Form validation for email, password, and name
- Duplicate email prevention
- Automatic login after successful registration
- Email and password validation
- Session token generation and storage
- Redirect to dashboard on success
- Protected routes check for valid session token
- Automatic logout and redirect for invalid sessions
- Session persistence across browser refreshes
For testing purposes, you can use these credentials or create new accounts:
Pre-seeded Test User:
- Email:
admin@ticketly.com - Password:
password123 - Name:
Admin User
Or create a new account:
- Use any valid email format
- Password must be at least 6 characters
- Full name is required
- Stacked layout with hamburger menu
- Full-width cards and forms
- Touch-friendly button sizes
- Collapsible sidebar with slide-out sheet
- Two-column grid layouts
- Optimized spacing and typography
- Responsive sidebar behavior
- Three-column layouts where appropriate
- Fixed sidebar navigation
- Max-width 1440px container
- Hover states and interactions
- Proper heading hierarchy (h1, h2, h3)
- Semantic elements (
<main>,<section>,<nav>) - Form labels and associations
- Tab order and focus management
- Visible focus indicators
- Skip links where appropriate
- WCAG-compliant color contrast ratios
- Status colors with sufficient contrast:
- Open tickets: Green (#16a34a)
- In Progress: Amber (#d97706)
- Closed: Gray (#6b7280)
- ARIA labels and descriptions
- Alternative text for decorative elements
- Meaningful link text
- Title: Required, 1-100 characters
- Description: Optional, max 500 characters
- Status: Required, must be one of:
open,in_progress,closed - Priority: Optional, must be one of:
low,medium,high
- Email: Valid email format required
- Password: Minimum 6 characters
- Name: Required for registration
- Real-time validation with inline error messages
- Toast notifications for system-level errors
- Graceful fallbacks for failed operations
- No backend integration (localStorage only)
- No user avatar/profile images
- No ticket attachments
- No real-time collaboration
- No email notifications
- No password reset functionality
- No pagination (all tickets loaded at once)
- Backend API integration (REST/GraphQL)
- User profile management
- Ticket assignment to users
- Comments/activity log per ticket
- File attachments
- Email notifications
- Advanced filtering (date ranges, priority)
- Sorting options
- Export to CSV/PDF
- Dark mode toggle
- Multi-language support
# Install new dependencies
pnpm add <package-name>
# Add shadcn-vue component
pnpm dlx shadcn-vue@latest add <component-name>
# Type checking
pnpm vue-tsc --noEmit
# Linting
pnpm eslint src/This project is a learning exercise and migration reference. Feel free to:
- Report bugs via issues
- Suggest enhancements
- Submit pull requests for improvements
This project is part of the HNG Frontend Stage 2 requirements.
Built with โค๏ธ for the HNG Internship Program