feat: add transitions and micro-interactions across all views
- Page transitions with slide-up/fade on route changes (App.vue) - NavRail sliding active indicator with spring-like easing - List enter/leave/move animations on Entries, Projects, Clients, Timer - Modal enter/leave transitions with scale+fade on all dialogs - Dropdown transitions with overshoot on all select/picker components - Button feedback (scale on hover/active), card hover lift effects - Timer pulse on start, glow on stop, floating empty state icons - Content fade-in on Dashboard, Reports, Calendar, Timesheet - Tag chip enter/leave animations in AppTagInput - Progress bar smooth width transitions - Implementation plan document
This commit is contained in:
@@ -12,11 +12,12 @@
|
||||
</div>
|
||||
|
||||
<!-- Projects Grid -->
|
||||
<div v-if="projectsStore.projects.length > 0" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
<TransitionGroup v-if="projectsStore.projects.length > 0" name="list" tag="div" class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
||||
<div
|
||||
v-for="project in projectsStore.projects"
|
||||
v-for="(project, index) in projectsStore.projects"
|
||||
:key="project.id"
|
||||
class="group bg-bg-surface border border-border-subtle rounded-lg shadow-[0_1px_3px_rgba(0,0,0,0.3)] hover:bg-bg-elevated transition-all duration-150 cursor-pointer"
|
||||
class="group bg-bg-surface border border-border-subtle rounded-lg shadow-[0_1px_3px_rgba(0,0,0,0.3)] card-hover cursor-pointer"
|
||||
:style="{ transitionDelay: `${index * 30}ms` }"
|
||||
@click="openEditDialog(project)"
|
||||
>
|
||||
<div class="flex border-l-[2px] hover:border-l-[3px] rounded-l-lg transition-all duration-150" :style="{ borderLeftColor: project.color }">
|
||||
@@ -54,7 +55,7 @@
|
||||
</div>
|
||||
<div class="w-full bg-bg-elevated rounded-full h-1">
|
||||
<div
|
||||
class="h-1 rounded-full transition-all"
|
||||
class="h-1 rounded-full progress-bar"
|
||||
:class="getBudgetPct(project) > 90 ? 'bg-status-error' : getBudgetPct(project) > 75 ? 'bg-status-warning' : 'bg-accent'"
|
||||
:style="{ width: Math.min(getBudgetPct(project), 100) + '%' }"
|
||||
/>
|
||||
@@ -63,11 +64,11 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</TransitionGroup>
|
||||
|
||||
<!-- Empty State -->
|
||||
<div v-else class="flex flex-col items-center justify-center py-16">
|
||||
<FolderKanban class="w-12 h-12 text-text-tertiary" :stroke-width="1.5" />
|
||||
<FolderKanban class="w-12 h-12 text-text-tertiary animate-float" :stroke-width="1.5" />
|
||||
<p class="text-sm text-text-secondary mt-4">No projects yet</p>
|
||||
<p class="text-xs text-text-tertiary mt-2 max-w-xs text-center">Projects organize your time entries and set billing rates for clients.</p>
|
||||
<button
|
||||
@@ -79,12 +80,13 @@
|
||||
</div>
|
||||
|
||||
<!-- Create/Edit Dialog -->
|
||||
<Transition name="modal">
|
||||
<div
|
||||
v-if="showDialog"
|
||||
class="fixed inset-0 bg-black/70 backdrop-blur-[4px] flex items-center justify-center p-4 z-50"
|
||||
@click.self="tryCloseDialog"
|
||||
>
|
||||
<div class="bg-bg-surface border border-border-subtle rounded-lg shadow-[0_1px_3px_rgba(0,0,0,0.3)] w-full max-w-md p-6 animate-modal-enter max-h-[calc(100vh-2rem)] overflow-y-auto">
|
||||
<div class="bg-bg-surface border border-border-subtle rounded-lg shadow-[0_1px_3px_rgba(0,0,0,0.3)] w-full max-w-md p-6 max-h-[calc(100vh-2rem)] overflow-y-auto">
|
||||
<h2 class="text-[1.125rem] font-semibold font-[family-name:var(--font-heading)] text-text-primary mb-4">
|
||||
{{ editingProject ? 'Edit Project' : 'Create Project' }}
|
||||
</h2>
|
||||
@@ -240,14 +242,16 @@
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
|
||||
<!-- Delete Confirmation Dialog -->
|
||||
<Transition name="modal">
|
||||
<div
|
||||
v-if="showDeleteDialog"
|
||||
class="fixed inset-0 bg-black/70 backdrop-blur-[4px] flex items-center justify-center p-4 z-50"
|
||||
@click.self="cancelDelete"
|
||||
>
|
||||
<div class="bg-bg-surface border border-border-subtle rounded-lg shadow-[0_1px_3px_rgba(0,0,0,0.3)] w-full max-w-sm p-6 animate-modal-enter">
|
||||
<div class="bg-bg-surface border border-border-subtle rounded-lg shadow-[0_1px_3px_rgba(0,0,0,0.3)] w-full max-w-sm p-6">
|
||||
<h2 class="text-[1.125rem] font-semibold font-[family-name:var(--font-heading)] text-text-primary mb-2">Delete Project</h2>
|
||||
<p class="text-[0.75rem] text-text-secondary mb-6">
|
||||
Are you sure you want to delete "{{ projectToDelete?.name }}"? This action cannot be undone.
|
||||
@@ -268,6 +272,7 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
|
||||
<AppDiscardDialog :show="showDiscardDialog" @cancel="cancelDiscard" @discard="confirmDiscard" />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user