Adding new style
This commit is contained in:
parent
3b836d945e
commit
3fa3eb90ee
|
|
@ -25,7 +25,7 @@ test('smoke test - app loads and editor opens', async ({ page }) => {
|
|||
await navButton.click()
|
||||
}
|
||||
|
||||
await expect(page.getByRole('heading', { name: 'Workout Plans' })).toBeVisible()
|
||||
await expect(page.getByRole('heading', { name: 'My Plans' })).toBeVisible()
|
||||
|
||||
// 4. Navigate to Editor
|
||||
await page.getByRole('button', { name: 'New Plan' }).click()
|
||||
|
|
|
|||
|
|
@ -305,54 +305,45 @@ const getSportName = (workout) => {
|
|||
|
||||
<template>
|
||||
<div class="h-full flex flex-col p-6 max-w-6xl mx-auto w-full">
|
||||
<!-- LINK TO DASHBOARD -->
|
||||
<div v-if="viewMode === 'browser'" class="mb-6 flex justify-between items-center">
|
||||
<div>
|
||||
<h1
|
||||
class="text-3xl font-bold bg-clip-text text-transparent bg-gradient-to-r from-blue-400 to-purple-400 mb-2"
|
||||
>
|
||||
Workout Plans
|
||||
</h1>
|
||||
<p class="text-gray-400">Manage your training collection</p>
|
||||
<!-- BROWSER TOOLBAR -->
|
||||
<div v-if="viewMode === 'browser'" class="editor-toolbar mb-6 rounded-xl">
|
||||
<div class="toolbar-left">
|
||||
<h2 class="text-lg font-bold text-white tracking-tight">My Plans</h2>
|
||||
<div class="toolbar-divider"></div>
|
||||
<!-- Search Input Stub -->
|
||||
<div class="relative group">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search workouts..."
|
||||
class="bg-transparent border-none text-sm text-white focus:outline-none w-48 transition-all"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-4">
|
||||
<!-- Source Toggle -->
|
||||
<div class="flex gap-2 bg-gray-900/50 p-1 rounded-lg border border-gray-800">
|
||||
<button
|
||||
:class="[
|
||||
'px-4 py-2 rounded-md text-sm font-medium transition-all flex items-center gap-2',
|
||||
sourceMode === 'remote'
|
||||
? 'bg-blue-600 text-white shadow-lg shadow-blue-900/20'
|
||||
: 'text-gray-400 hover:text-white hover:bg-white/5'
|
||||
]"
|
||||
@click="setSourceMode('remote')"
|
||||
>
|
||||
<div class="toolbar-right">
|
||||
<!-- Source Toggle (Segmented) -->
|
||||
<div class="segmented-control">
|
||||
<button :class="{ active: sourceMode === 'remote' }" @click="setSourceMode('remote')">
|
||||
<Cloud class="w-4 h-4" />
|
||||
Gapminder
|
||||
<span>Gapminder</span>
|
||||
</button>
|
||||
<button
|
||||
class="px-4 py-1.5 rounded-md transition-all"
|
||||
:class="
|
||||
sourceMode === 'local'
|
||||
? 'bg-purple-600 text-white shadow-lg'
|
||||
: 'text-gray-400 hover:text-white'
|
||||
"
|
||||
@click="setSourceMode('local')"
|
||||
>
|
||||
Local Files
|
||||
<button :class="{ active: sourceMode === 'local' }" @click="setSourceMode('local')">
|
||||
<FileJson class="w-4 h-4" />
|
||||
<span>Local</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<button class="primary-btn" @click="createNewWorkout">
|
||||
<Plus class="w-5 h-5" /> New Plan
|
||||
<div class="toolbar-divider"></div>
|
||||
|
||||
<button class="toolbar-btn primary-btn" @click="createNewWorkout">
|
||||
<Plus class="w-4 h-4" />
|
||||
<span>New Plan</span>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- WORKOUT BROWSER -->
|
||||
<div v-if="viewMode === 'browser'" class="flex-1 overflow-y-auto custom-scrollbar">
|
||||
<!-- ... existing browser content ... -->
|
||||
<!-- WORKOUT BROWSER GRID -->
|
||||
<div v-if="viewMode === 'browser'" class="flex-1 overflow-y-auto custom-scrollbar px-1">
|
||||
<div v-if="loading" class="flex flex-col items-center justify-center h-64 text-gray-500">
|
||||
<Loader2 class="w-8 h-8 animate-spin mb-2" />
|
||||
<span>Loading workouts...</span>
|
||||
|
|
@ -367,44 +358,59 @@ const getSportName = (workout) => {
|
|||
v-for="workout in workouts"
|
||||
:key="workout.workoutId || workout.filename"
|
||||
class="workout-card group"
|
||||
@click="editWorkout(workout)"
|
||||
>
|
||||
<div class="flex justify-between items-start mb-3">
|
||||
<!-- Card Badge (Top Right Action Area) -->
|
||||
<div
|
||||
class="absolute top-3 right-3 flex gap-2 opacity-0 group-hover:opacity-100 transition-all transform translate-x-2 group-hover:translate-x-0 z-10"
|
||||
>
|
||||
<button
|
||||
class="p-2 bg-gray-800 hover:bg-gray-700 text-white rounded-lg shadow-lg border border-gray-700 transition-colors"
|
||||
title="Duplicate"
|
||||
@click.stop="duplicateWorkout(workout)"
|
||||
>
|
||||
<Copy class="w-4 h-4" />
|
||||
</button>
|
||||
<button
|
||||
class="p-2 bg-blue-600 hover:bg-blue-500 text-white rounded-lg shadow-lg shadow-blue-900/20 border border-blue-500/50 transition-colors"
|
||||
title="Edit"
|
||||
@click.stop="editWorkout(workout)"
|
||||
>
|
||||
<Edit2 class="w-4 h-4" />
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Card Icon -->
|
||||
<div class="mb-4">
|
||||
<div
|
||||
class="p-2 rounded-lg bg-gray-800 text-blue-400 group-hover:bg-blue-900/30 transition-colors"
|
||||
class="w-12 h-12 rounded-xl flex items-center justify-center bg-gradient-to-br from-gray-800 to-gray-900 border border-gray-700 text-blue-400 group-hover:border-blue-500/30 group-hover:text-blue-300 transition-all shadow-inner"
|
||||
>
|
||||
<Dumbbell v-if="isStrength(workout)" class="w-6 h-6" />
|
||||
<Activity v-else class="w-6 h-6" />
|
||||
</div>
|
||||
<div class="flex gap-2">
|
||||
<button
|
||||
class="icon-btn p-1.5 hover:bg-white/10 rounded-md transition-colors text-gray-400 hover:text-white"
|
||||
title="Duplicate"
|
||||
@click.stop="duplicateWorkout(workout)"
|
||||
>
|
||||
<Copy class="w-5 h-5" />
|
||||
</button>
|
||||
<button
|
||||
class="icon-btn p-1.5 hover:bg-white/10 rounded-md transition-colors text-gray-400 hover:text-white"
|
||||
title="Edit"
|
||||
@click.stop="editWorkout(workout)"
|
||||
>
|
||||
<Edit2 class="w-5 h-5" />
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<h3 class="font-bold text-lg mb-1 truncate">{{ workout.workoutName }}</h3>
|
||||
<p class="text-xs text-gray-400 mb-4 line-clamp-2">
|
||||
{{ workout.description || 'No description provided' }}
|
||||
</p>
|
||||
|
||||
<!-- Content -->
|
||||
<div class="flex-1">
|
||||
<h3
|
||||
class="font-bold text-base text-white mb-1 group-hover:text-blue-400 transition-colors truncate"
|
||||
>
|
||||
{{ workout.workoutName }}
|
||||
</h3>
|
||||
<p class="text-xs text-gray-500 line-clamp-2 leading-relaxed">
|
||||
{{ workout.description || 'No description provided' }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<!-- Footer -->
|
||||
<div
|
||||
class="mt-auto flex justify-between items-center text-xs text-gray-500 border-t border-gray-800 pt-3"
|
||||
class="mt-4 pt-3 border-t border-gray-800 flex justify-between items-center text-[10px] uppercase font-bold tracking-wider text-gray-600"
|
||||
>
|
||||
<span>{{ getSportName(workout) }}</span>
|
||||
<span v-if="workout.isLocal" class="text-purple-400 flex items-center gap-1">
|
||||
<span v-if="workout.isLocal" class="text-purple-400/80 flex items-center gap-1">
|
||||
<FileJson class="w-3 h-3" /> Local
|
||||
</span>
|
||||
<span v-else class="text-blue-400 flex items-center gap-1">
|
||||
<span v-else class="text-blue-400/80 flex items-center gap-1">
|
||||
<Cloud class="w-3 h-3" /> Garmin
|
||||
</span>
|
||||
</div>
|
||||
|
|
@ -687,6 +693,24 @@ const getSportName = (workout) => {
|
|||
box-shadow: 0 4px 12px rgba(31, 111, 235, 0.3);
|
||||
}
|
||||
|
||||
.workout-card {
|
||||
background: #0d1117; /* Darker Github-like bg */
|
||||
border: 1px solid var(--border-color);
|
||||
border-radius: 12px;
|
||||
padding: 1.25rem;
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
position: relative;
|
||||
transition: all 0.2s cubic-bezier(0.25, 0.8, 0.25, 1);
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
.workout-card:hover {
|
||||
transform: translateY(-2px);
|
||||
border-color: #3b82f6; /* Blue 500 */
|
||||
box-shadow: 0 10px 30px -10px rgba(59, 130, 246, 0.15);
|
||||
}
|
||||
|
||||
.sync-res {
|
||||
font-size: 0.9rem;
|
||||
margin-right: 1rem;
|
||||
|
|
|
|||
Loading…
Reference in New Issue