added yoga stuff, i18n, workout tracking and a dashboard to track progress
This commit is contained in:
@@ -0,0 +1,100 @@
|
||||
<x-app-layout>
|
||||
<section class="bg-white dark:bg-gray-900 border-b border-gray-100 dark:border-gray-800">
|
||||
<div class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-8">
|
||||
<div class="flex items-start justify-between flex-col lg:flex-row gap-6">
|
||||
<div>
|
||||
<h1 class="text-2xl sm:text-3xl font-extrabold tracking-tight text-gray-900 dark:text-white">{{ __('app.yoga.browse') }}</h1>
|
||||
<p class="mt-2 text-gray-600 dark:text-gray-300">{{ __('app.yoga.browse_desc') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-6">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-6">
|
||||
<aside class="lg:col-span-12">
|
||||
<form action="{{ route('yoga.index') }}" method="GET" class="space-y-4 lg:space-y-0 lg:flex lg:flex-wrap lg:items-end lg:gap-4 bg-white dark:bg-gray-800 rounded-2xl p-4 ring-1 ring-gray-200 dark:ring-gray-700">
|
||||
<div class="w-full lg:w-72">
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">{{ __('app.yoga.search') }}</label>
|
||||
<input type="text" name="q" value="{{ $filters['q'] ?? '' }}" placeholder="{{ __('app.yoga.search_placeholder') }}" class="mt-1 w-full rounded-xl border-gray-300 dark:border-gray-700 bg-white/80 dark:bg-gray-900 text-gray-900 dark:text-gray-100 placeholder-gray-400 focus:border-indigo-500 focus:ring-indigo-500 px-3 py-2">
|
||||
</div>
|
||||
<div class="w-full lg:w-56">
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">{{ __('app.yoga.category') }}</label>
|
||||
<select name="category" class="mt-1 w-full rounded-xl border-gray-300 dark:border-gray-700 bg-white/80 dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:border-indigo-500 focus:ring-indigo-500 px-3 py-2">
|
||||
<option value="0">{{ __('app.yoga.any') }}</option>
|
||||
@foreach($categories as $c)
|
||||
<option value="{{ $c->id }}" @selected(($filters['category'] ?? 0) == $c->id)>{{ $c->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="w-full lg:w-72">
|
||||
<label class="block text-sm font-medium text-gray-700 dark:text-gray-300">{{ __('app.yoga.benefit') }}</label>
|
||||
<input type="text" name="benefit" value="{{ $filters['benefit'] ?? '' }}" placeholder="{{ __('app.yoga.benefit_placeholder') }}" class="mt-1 w-full rounded-xl border-gray-300 dark:border-gray-700 bg-white/80 dark:bg-gray-900 text-gray-900 dark:text-gray-100 placeholder-gray-400 focus:border-indigo-500 focus:ring-indigo-500 px-3 py-2">
|
||||
</div>
|
||||
<div class="w-full lg:w-auto flex items-center justify-between lg:justify-end gap-2 lg:ml-auto">
|
||||
<a href="{{ route('yoga.index') }}" class="text-sm text-gray-600 dark:text-gray-300 hover:text-gray-900 dark:hover:text-white">{{ __('app.yoga.reset') }}</a>
|
||||
<button type="submit" class="inline-flex items-center rounded-xl bg-gradient-to-r from-fuchsia-600 to-indigo-600 px-4 py-2 text-sm font-semibold text-white shadow hover:from-fuchsia-500 hover:to-indigo-500">{{ __('app.yoga.apply_filters') }}</button>
|
||||
</div>
|
||||
</form>
|
||||
</aside>
|
||||
|
||||
<div class="lg:col-span-12">
|
||||
<div class="flex items-center justify-between mb-4">
|
||||
<p class="text-sm text-gray-600 dark:text-gray-300">{{ __('app.yoga.showing') }} <span class="font-medium">{{ $poses->total() }}</span> {{ __('app.yoga.poses_noun') }}</p>
|
||||
<div class="flex items-center gap-2">
|
||||
<label class="text-sm text-gray-600 dark:text-gray-300">{{ __('app.exercises.per_page') }}</label>
|
||||
<select name="per_page" form="per-page-form" class="rounded-lg border-gray-300 dark:border-gray-700 bg-white/80 dark:bg-gray-900 text-gray-900 dark:text-gray-100 focus:border-indigo-500 focus:ring-indigo-500 px-2 py-1">
|
||||
@foreach([12, 24, 36] as $n)
|
||||
<option value="{{ $n }}" @selected(($filters['per_page'] ?? 12) == $n)>{{ $n }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<form id="per-page-form" action="{{ route('yoga.index') }}" method="GET" class="hidden">
|
||||
@foreach(request()->except('per_page') as $k => $v)
|
||||
<input type="hidden" name="{{ $k }}" value="{{ $v }}">
|
||||
@endforeach
|
||||
<input type="hidden" name="per_page" value="{{ $filters['per_page'] ?? 12 }}">
|
||||
</form>
|
||||
<script>
|
||||
document.addEventListener('change', (e) => {
|
||||
if (e.target && e.target.name === 'per_page') {
|
||||
const form = document.getElementById('per-page-form');
|
||||
form.querySelector('input[name="per_page"]').value = e.target.value;
|
||||
form.submit();
|
||||
}
|
||||
});
|
||||
</script>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if($poses->count() === 0)
|
||||
<div class="rounded-2xl border border-dashed border-gray-300 dark:border-gray-700 p-8 text-center text-gray-600 dark:text-gray-300">{{ __('app.yoga.none_found') }}</div>
|
||||
@else
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
@foreach($poses as $pose)
|
||||
<a href="{{ route('yoga.show', $pose->slug) }}" class="group rounded-3xl overflow-hidden bg-white dark:bg-gray-800 ring-1 ring-gray-200 dark:ring-gray-700 shadow-sm hover:shadow-xl transition">
|
||||
<div class="relative aspect-[16/9] overflow-hidden bg-white">
|
||||
@php $img = $pose->url_png ?: $pose->url_svg ?: $pose->url_svg_alt; @endphp
|
||||
@if($img)
|
||||
<img src="{{ $img }}" alt="{{ $pose->english_name }}" class="h-full w-full object-contain p-4 transition-transform duration-500 group-hover:scale-105">
|
||||
@else
|
||||
<div class="h-full w-full flex items-center justify-center text-gray-400">{{ __('app.yoga.no_image') }}</div>
|
||||
@endif
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-black/10 to-transparent"></div>
|
||||
<div class="absolute bottom-3 left-3 inline-flex items-center rounded-full bg-white/90 px-3 py-1 text-xs font-semibold text-gray-900 shadow">{{ $pose->english_name }}</div>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<div class="text-sm text-gray-600 dark:text-gray-300">{{ optional($pose->category)->name }}</div>
|
||||
@if($pose->sanskrit_name)
|
||||
<div class="mt-1 text-xs text-gray-500 italic">{{ $pose->sanskrit_name }}</div>
|
||||
@endif
|
||||
</div>
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="mt-6">{{ $poses->links() }}</div>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</x-app-layout>
|
||||
@@ -0,0 +1,124 @@
|
||||
<x-app-layout>
|
||||
<section class="relative overflow-hidden">
|
||||
<div class="absolute inset-0">
|
||||
@php $img = $pose->url_png ?: $pose->url_svg ?: $pose->url_svg_alt; @endphp
|
||||
@if($img)
|
||||
<img src="{{ $img }}" alt="{{ $pose->english_name }}" class="h-full w-full object-contain bg-white">
|
||||
@else
|
||||
<div class="h-full w-full bg-gray-100 dark:bg-gray-800"></div>
|
||||
@endif
|
||||
<div class="absolute inset-0 bg-gradient-to-b from-indigo-900/40 via-indigo-800/30 to-transparent"></div>
|
||||
</div>
|
||||
<div class="relative mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-12 sm:py-20">
|
||||
<a href="{{ url()->previous() ?? route('yoga.index') }}" class="inline-flex items-center text-sm font-medium text-white/90 hover:text-white">← {{ __('app.yoga.back') }}</a>
|
||||
<div class="mt-3 flex items-start justify-between gap-4">
|
||||
<h1 class="text-3xl sm:text-5xl font-extrabold tracking-tight text-white drop-shadow">{{ $pose->english_name }}</h1>
|
||||
</div>
|
||||
<div class="mt-4 flex flex-wrap items-center gap-2">
|
||||
@if($pose->category)
|
||||
<span class="inline-flex items-center rounded-full bg-white/90 px-3 py-1 text-xs font-semibold text-gray-900 shadow">{{ $pose->category->name }}</span>
|
||||
@endif
|
||||
@if($pose->sanskrit_name)
|
||||
<span class="inline-flex items-center rounded-full bg-emerald-100 text-emerald-700 px-2.5 py-1 text-xs font-semibold">Sanskrit: {{ $pose->sanskrit_name }}</span>
|
||||
@endif
|
||||
@if($pose->sanskrit_name_adapted)
|
||||
<span class="inline-flex items-center rounded-full bg-sky-100 text-sky-700 px-2.5 py-1 text-xs font-semibold">{{ $pose->sanskrit_name_adapted }}</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 py-10">
|
||||
<div class="grid grid-cols-1 lg:grid-cols-12 gap-8">
|
||||
<div class="lg:col-span-8">
|
||||
<div class="rounded-3xl overflow-hidden ring-1 ring-gray-200 dark:ring-gray-700 bg-white dark:bg-gray-800 p-6">
|
||||
<h2 class="text-lg font-semibold text-gray-900 dark:text-white">{{ __('app.yoga.description') }}</h2>
|
||||
<div class="prose prose-indigo dark:prose-invert max-w-none mt-3">
|
||||
@php $desc = trim((string) $pose->description); @endphp
|
||||
@if($desc !== '')
|
||||
@foreach(preg_split('/\r?\n+/', $desc) as $line)
|
||||
@if(trim($line) !== '')<p>{{ $line }}</p>@endif
|
||||
@endforeach
|
||||
@else
|
||||
<p>{{ __('app.yoga.no_description') }}</p>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-6 rounded-3xl overflow-hidden ring-1 ring-gray-200 dark:ring-gray-700 bg-white dark:bg-gray-800 p-6">
|
||||
<h2 class="text-lg font-semibold text-gray-900 dark:text-white">{{ __('app.yoga.benefits') }}</h2>
|
||||
<div class="prose prose-indigo dark:prose-invert max-w-none mt-3">
|
||||
@php $benef = trim((string) $pose->benefits); @endphp
|
||||
@if($benef !== '')
|
||||
@foreach(preg_split('/\r?\n+/', $benef) as $line)
|
||||
@if(trim($line) !== '')<p>{{ $line }}</p>@endif
|
||||
@endforeach
|
||||
@else
|
||||
<p>{{ __('app.yoga.no_benefits') }}</p>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="lg:col-span-4">
|
||||
<div class="rounded-2xl p-5 ring-1 ring-gray-200 dark:ring-gray-700 bg-white dark:bg-gray-800">
|
||||
<h3 class="text-sm font-semibold text-gray-900 dark:text-white">{{ __('app.yoga.pose_info') }}</h3>
|
||||
<dl class="mt-3 space-y-2 text-sm text-gray-700 dark:text-gray-300">
|
||||
@if($pose->translation_name)
|
||||
<div class="flex justify-between"><dt>{{ __('app.yoga.translation') }}</dt><dd class="text-right ms-3">{{ $pose->translation_name }}</dd></div>
|
||||
@endif
|
||||
@if($pose->sanskrit_name)
|
||||
<div class="flex justify-between"><dt>{{ __('app.yoga.sanskrit') }}</dt><dd class="text-right ms-3">{{ $pose->sanskrit_name }}</dd></div>
|
||||
@endif
|
||||
@if($pose->sanskrit_name_adapted)
|
||||
<div class="flex justify-between"><dt>{{ __('app.yoga.sanskrit_adapted') }}</dt><dd class="text-right ms-3">{{ $pose->sanskrit_name_adapted }}</dd></div>
|
||||
@endif
|
||||
@if($pose->category)
|
||||
<div class="flex justify-between"><dt>{{ __('app.yoga.category') }}</dt><dd class="text-right ms-3">{{ $pose->category->name }}</dd></div>
|
||||
@endif
|
||||
</dl>
|
||||
<div class="mt-5">
|
||||
<a href="{{ route('yoga.index') }}" class="inline-flex items-center rounded-xl bg-gradient-to-r from-fuchsia-600 to-indigo-600 px-4 py-2 text-sm font-semibold text-white shadow hover:from-fuchsia-500 hover:to-indigo-500">{{ __('app.yoga.browse_all') }}</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
@isset($similarPoses)
|
||||
<section class="mx-auto max-w-7xl px-4 sm:px-6 lg:px-8 pb-12">
|
||||
<div class="mt-8">
|
||||
<div class="flex items-end justify-between gap-4 mb-4">
|
||||
<h2 class="text-2xl font-bold text-gray-900 dark:text-white">{{ __('app.yoga.similar') }}</h2>
|
||||
<a href="{{ route('yoga.index') }}" class="text-sm font-semibold text-indigo-600 hover:text-indigo-500">{{ __('app.yoga.browse_all') }}</a>
|
||||
</div>
|
||||
@if($similarPoses->isEmpty())
|
||||
<div class="rounded-2xl border border-dashed border-gray-300 dark:border-gray-700 p-6 text-center text-gray-600 dark:text-gray-300">{{ __('app.yoga.similar_none') }}</div>
|
||||
@else
|
||||
<div class="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
@foreach($similarPoses as $p)
|
||||
<a href="{{ route('yoga.show', $p->slug) }}" class="group rounded-3xl overflow-hidden bg-white dark:bg-gray-800 ring-1 ring-gray-200 dark:ring-gray-700 shadow-sm hover:shadow-xl transition">
|
||||
<div class="relative aspect-[16/9] overflow-hidden bg-white">
|
||||
@php $img = $p->url_png ?: $p->url_svg ?: $p->url_svg_alt; @endphp
|
||||
@if($img)
|
||||
<img src="{{ $img }}" alt="{{ $p->english_name }}" class="h-full w-full object-contain transition-transform duration-500 group-hover:scale-105">
|
||||
@else
|
||||
<div class="h-full w-full flex items-center justify-center text-sm text-gray-500">{{ __('app.yoga.no_image') }}</div>
|
||||
@endif
|
||||
<div class="absolute inset-0 bg-gradient-to-t from-black/20 to-transparent"></div>
|
||||
<div class="absolute bottom-3 left-3 inline-flex items-center rounded-full bg-white/90 px-3 py-1 text-xs font-semibold text-gray-900 shadow">{{ $p->english_name }}</div>
|
||||
</div>
|
||||
<div class="p-4">
|
||||
<div class="mt-1 flex flex-wrap gap-2">
|
||||
@if($p->category)
|
||||
<span class="inline-flex items-center rounded-full px-2.5 py-1 text-xs font-medium bg-gray-100 text-gray-700 dark:bg-gray-700 dark:text-gray-200">{{ $p->category->name }}</span>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
</section>
|
||||
@endisset
|
||||
</x-app-layout>
|
||||
Reference in New Issue
Block a user