Build & Deploy / build (push) Failing after 5s
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
67 lines
2.6 KiB
Vue
67 lines
2.6 KiB
Vue
<script setup lang="ts">
|
|
const { t, locale } = useI18n()
|
|
const { api } = useApi()
|
|
const route = useRoute()
|
|
|
|
interface ExerciseDetail {
|
|
id: number
|
|
name: string
|
|
body_part: string | null
|
|
category: string | null
|
|
equipment: string | null
|
|
target: string | null
|
|
muscle_group: string | null
|
|
secondary_muscles: string[]
|
|
instructions: string[]
|
|
image_url: string | null
|
|
gif_url: string | null
|
|
attribution: string | null
|
|
}
|
|
|
|
const { data, pending } = await useAsyncData(
|
|
() => `exercise-${route.params.id}`,
|
|
() => api<ExerciseDetail>(`/api/exercises/${route.params.id}`, { query: { locale: locale.value } }),
|
|
{ watch: [locale] }
|
|
)
|
|
</script>
|
|
|
|
<template>
|
|
<div class="space-y-5">
|
|
<UButton to="/exercises" icon="i-lucide-arrow-left" color="neutral" variant="ghost" :label="t('common.back')" />
|
|
|
|
<div v-if="pending && !data" class="flex justify-center py-16"><SfLogo :size="56" loader /></div>
|
|
|
|
<template v-else-if="data">
|
|
<div class="rounded-2xl overflow-hidden bg-zinc-100 dark:bg-zinc-800 aspect-square max-w-sm mx-auto">
|
|
<img v-if="data.gif_url || data.image_url" :src="data.gif_url || data.image_url || ''" :alt="data.name" class="w-full h-full object-cover">
|
|
</div>
|
|
|
|
<div>
|
|
<h1 class="text-2xl font-black tracking-tight capitalize">{{ data.name }}</h1>
|
|
<div class="flex flex-wrap gap-2 mt-2">
|
|
<UBadge v-if="data.target" color="primary" variant="soft" class="capitalize">{{ data.target }}</UBadge>
|
|
<UBadge v-if="data.equipment" color="neutral" variant="soft" class="capitalize">{{ data.equipment }}</UBadge>
|
|
<UBadge v-if="data.body_part" color="neutral" variant="outline" class="capitalize">{{ data.body_part }}</UBadge>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-if="data.secondary_muscles?.length">
|
|
<h2 class="text-sm font-semibold text-zinc-500 mb-1">{{ t('exercises.secondaryMuscles') }}</h2>
|
|
<p class="text-sm capitalize">{{ data.secondary_muscles.join(', ') }}</p>
|
|
</div>
|
|
|
|
<div v-if="data.instructions?.length">
|
|
<h2 class="text-sm font-semibold text-zinc-500 mb-2">{{ t('exercises.instructions') }}</h2>
|
|
<ol class="space-y-2">
|
|
<li v-for="(step, i) in data.instructions" :key="i" class="flex gap-3">
|
|
<span class="shrink-0 size-6 rounded-full sf-flame-bg text-white text-xs font-bold flex items-center justify-center">{{ i + 1 }}</span>
|
|
<span class="text-sm">{{ step }}</span>
|
|
</li>
|
|
</ol>
|
|
</div>
|
|
|
|
<p v-if="data.attribution" class="text-xs text-zinc-400 pt-4">{{ data.attribution }}</p>
|
|
</template>
|
|
</div>
|
|
</template>
|