This is a complete Vue 3 + TypeScript conversion of the original React application.
src/
├── components/
│ ├── icons/ # SVG icon components
│ ├── common/ # Reusable components (Card, Modal, EmptyState)
│ ├── App.vue # Main application component with router outlet
│ ├── SidebarContent.vue
│ ├── NavItem.vue
│ ├── LoginPage.vue
│ ├── ClientHome.vue
│ ├── TrainerDashboard.vue
│ ├── ChatView.vue
│ ├── CircuitGroup.vue
│ ├── TrainingLog.vue
│ ├── NutritionLog.vue
│ ├── Goals.vue
│ ├── Schedule.vue
│ ├── Progress.vue
│ ├── AddWorkout.vue
│ ├── TrainerMessages.vue
│ ├── TrainerClientLogs.vue
│ ├── AdminPage.vue
│ └── ProfilePage.vue
├── router/
│ └── index.ts # Vue Router configuration with auth guards
├── stores/
│ └── user.ts # Pinia store for authentication and user state
├── data/
│ └── mockData.ts # Mock data and initial state
├── docs/ # Store all documents that are created here
├── server/ # The backend api - accessible via the /api/ router
├── types.ts # TypeScript type definitions
└── main.ts # Application entry point
- React: Functional components with hooks
- Vue: Single File Components (
.vue) with Composition API
- React:
useStatehooks - Vue:
ref()andreactive()from Composition API
- React: Props passed as object, callbacks with
onChange,onClick - Vue: Props via
defineProps, emits viadefineEmits
- React: JSX with curly braces
{} - Vue: Template syntax with
{{ }}for interpolation,v-directives
- React: Ternary operators and logical AND (
&&) - Vue:
v-if,v-else,v-showdirectives
- React:
.map()in JSX - Vue:
v-fordirective
- React:
useEffect()hooks - Vue:
watch()and lifecycle hooks
- React: SVG components returning JSX
- Vue: SVG components with template syntax
cd app-vue
npm install
npm run devnpm run build- Vue Router: Full client-side routing with authentication guards and role-based access control
- Pinia State Management: Centralized user store for authentication and session state
- Dark Mode: Toggle via button in sidebar
- Responsive Layout: Mobile-first design with collapsible sidebar
- Role-Based Navigation: Different nav items and routes for trainers vs clients
- Authentication Guards: Protected routes with automatic redirect to login for unauthenticated users
- TypeScript: Full type safety throughout
- Tailwind CSS: Pre-configured styling with dark mode support
<script setup lang="ts">
import type { User } from "@/types"
defineProps<{
user: User
}>()
</script><script setup lang="ts">
defineEmits<{
click: []
select: [id: string]
}>()
</script><script setup lang="ts">
import { ref, computed } from "vue"
const count = ref(0)
const doubled = computed(() => count.value * 2)
const increment = () => {
count.value++
}
</script><script setup lang="ts">
import { watch } from "vue"
watch(isDarkMode, (newVal) => {
if (newVal) {
document.documentElement.classList.add("dark")
}
})
</script>The app uses Vue Router with the following route organization:
-
Client Routes (
/home,/coaching,/circuit,/training,/nutrition,/goals,/schedule,/progress,/profile)- Accessible only to users with
CLIENTrole - Automatic redirect to
/dashboardif trainer tries to access
- Accessible only to users with
-
Trainer Routes (
/dashboard,/messages,/client-logs,/admin)- Accessible only to users with
TRAINERorADMINrole - Automatic redirect to
/homeif client tries to access
- Accessible only to users with
-
Shared Routes (
/schedule)- Accessible to both
CLIENTandTRAINERroles
- Accessible to both
-
Auth Routes (
/login)- Publicly accessible
- Authenticated users automatically redirected to appropriate home
All routes are protected by authentication guards:
- Authentication Check: Routes with
requiresAuth: trueredirect unauthenticated users to/login - Role Validation: Routes with role restrictions check user's role and redirect if unauthorized
- Login Prevention: Authenticated users trying to access
/loginare redirected to their home page
import { useRouter, useRoute } from "vue-router"
// Get router instance for navigation
const router = useRouter()
router.push("/home")
// Get current route information
const route = useRoute()
const currentPath = route.path
const title = route.meta.titleFor more details, see src/router/index.ts and docs/ROUTER_MIGRATION_TESTING.md.
- All page components are currently placeholders with "Coming Soon" messages
- Implement individual page components by replacing the placeholder content
- The app uses Tailwind CSS with a custom theme defined in
index.html - Icon components are individual
.vuefiles insrc/components/icons/ - The original data structures and types remain unchanged for easy migration
- Implement Individual Components: Replace placeholder components with full implementations
- Add Backend Integration: Connect to actual API endpoints (backend server code under
./server/) - Testing: Add unit tests with Vitest and component tests with Vue Test Utils
- Performance Optimization: Monitor bundle size and optimize lazy-loaded components
- API Integration: Replace mock data with real API calls to backend endpoints