Initial commit

This commit is contained in:
Rutra
2026-02-25 00:34:39 +01:00
commit 54b0fc3485
178 changed files with 12761 additions and 0 deletions

View File

@@ -0,0 +1,120 @@
@component('admin/layouts/main')
@slot('main')
<h1 class="text-2xl font-bold mb-6">{{ project ? 'Modifier le projet' : 'Nouveau projet' }}</h1>
<form action="{{ project ? `/admin/projects/${project.id}` : '/admin/projects' }}" method="post" class="bg-white p-6 rounded shadow max-w-2xl">
{{{ csrfField() }}}
<div class="space-y-4">
<div>
<label for="title" class="block text-sm font-medium text-gray-700 mb-1">Titre</label>
<input type="text" name="title" id="title" value="{{ project?.title || '' }}" required
class="w-full px-3 py-2 border rounded" />
</div>
<div>
<label for="content" class="block text-sm font-medium text-gray-700 mb-1">Contenu (Markdown)</label>
<textarea name="content" id="content" rows="8" class="w-full px-3 py-2 border rounded">{{ project?.content || '' }}</textarea>
</div>
<div class="grid grid-cols-2 gap-4">
<div>
<label for="start" class="block text-sm font-medium text-gray-700 mb-1">Début</label>
<input type="date" name="start" id="start" value="{{ project?.start ? project.start.toISODate() : '' }}"
class="w-full px-3 py-2 border rounded" />
</div>
<div>
<label for="end" class="block text-sm font-medium text-gray-700 mb-1">Fin</label>
<input type="date" name="end" id="end" value="{{ project?.end ? project.end.toISODate() : '' }}"
class="w-full px-3 py-2 border rounded" />
</div>
</div>
<div>
<label for="thumbnailUrl" class="block text-sm font-medium text-gray-700 mb-1">Image miniature</label>
<div x-data="{ open: false, selected: '{{ project?.thumbnailUrl || '' }}' }" class="relative">
<input type="hidden" name="thumbnailUrl" x-model="selected">
<button type="button" @click="open = !open" class="w-full px-3 py-2 border rounded text-left flex items-center justify-between bg-white">
<span x-text="selected ? selected.split('/').pop() : 'Sélectionner une image'"></span>
<svg class="w-4 h-4 text-gray-500" fill="none" stroke="currentColor" viewBox="0 0 24 24"><path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M19 9l-7 7-7-7"></path></svg>
</button>
<div x-show="open" @click.away="open = false" class="absolute z-10 w-full mt-1 bg-white border rounded shadow-lg max-h-60 overflow-y-auto grid grid-cols-3 gap-2 p-2">
<div @click="selected = ''; open = false" class="col-span-3 p-2 hover:bg-gray-100 cursor-pointer text-sm text-gray-500 text-center border-b mb-2">
Aucune image
</div>
@each(image in images)
<div @click="selected = '{{ image.filePath }}'; open = false" class="cursor-pointer group relative aspect-square border rounded overflow-hidden hover:border-blue-500" :class="{'ring-2 ring-blue-500': selected === '{{ image.filePath }}'}">
<img src="{{ image.filePath }}" alt="{{ image.originalName }}" class="w-full h-full object-cover">
<div class="absolute inset-0 bg-black/50 opacity-0 group-hover:opacity-100 flex items-center justify-center text-white text-xs p-1 text-center transition-opacity">
{{ image.originalName }}
</div>
</div>
@endeach
</div>
<!-- Preview of selected image -->
<template x-if="selected">
<div class="mt-2">
<p class="text-xs text-gray-500 mb-1">Aperçu:</p>
<img :src="selected" class="h-24 w-auto object-contain border rounded bg-gray-50">
</div>
</template>
</div>
</div>
<div>
<label for="categoryId" class="block text-sm font-medium text-gray-700 mb-1">Catégorie</label>
<select name="categoryId" id="categoryId" class="w-full px-3 py-2 border rounded">
<option value="">—</option>
@each(cat in categories)
<option value="{{ cat.id }}" {{ project?.categoryId === cat.id ? 'selected' : '' }}>{{ cat.name }}</option>
@endeach
</select>
</div>
<div class="grid grid-cols-1 md:grid-cols-3 gap-6">
<!-- Tags Selection -->
<div class="bg-gray-50 p-4 rounded border" x-data="{ search: '' }">
<label class="block text-sm font-bold text-gray-700 mb-2 border-b pb-1">Tags</label>
<input type="text" x-model="search" placeholder="Rechercher..." class="w-full px-2 py-1 mb-2 border rounded text-sm mb-2">
<div class="max-h-60 overflow-y-auto space-y-2 pr-2">
@each(tag in tags)
<label class="flex items-center hover:bg-gray-100 p-1 rounded cursor-pointer transition-colors" x-show="'{{ tag.name.toLowerCase() }}'.includes(search.toLowerCase())">
<input type="checkbox" name="tagIds" value="{{ tag.id }}" class="mr-2 h-4 w-4 text-blue-600 rounded border-gray-300 focus:ring-blue-500"
{{ project?.tags?.find(t => t.id === tag.id) ? 'checked' : '' }} />
<span class="text-sm text-gray-700" style="color: {{ tag.color }}">{{ tag.name }}</span>
</label>
@endeach
</div>
</div>
<!-- Trainings Selection -->
<div class="bg-gray-50 p-4 rounded border">
<label class="block text-sm font-bold text-gray-700 mb-2 border-b pb-1">Formations</label>
<div class="max-h-60 overflow-y-auto space-y-2 pr-2">
@each(t in trainings)
<label class="flex items-center hover:bg-gray-100 p-1 rounded cursor-pointer transition-colors">
<input type="checkbox" name="trainingIds" value="{{ t.id }}" class="mr-2 h-4 w-4 text-blue-600 rounded border-gray-300 focus:ring-blue-500"
{{ project?.trainings?.find(tr => tr.id === t.id) ? 'checked' : '' }} />
<span class="text-sm text-gray-700">{{ t.name }}</span>
</label>
@endeach
</div>
</div>
<!-- Experiences Selection -->
<div class="bg-gray-50 p-4 rounded border">
<label class="block text-sm font-bold text-gray-700 mb-2 border-b pb-1">Expériences</label>
<div class="max-h-60 overflow-y-auto space-y-2 pr-2">
@each(e in experiences)
<label class="flex items-center hover:bg-gray-100 p-1 rounded cursor-pointer transition-colors">
<input type="checkbox" name="experienceIds" value="{{ e.id }}" class="mr-2 h-4 w-4 text-blue-600 rounded border-gray-300 focus:ring-blue-500"
{{ project?.experiences?.find(exp => exp.id === e.id) ? 'checked' : '' }} />
<span class="text-sm text-gray-700">{{ e.name }} - {{e.place }}</span>
</label>
@endeach
</div>
</div>
</div>
<button type="submit" class="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700">
Enregistrer
</button>
</div>
</form>
@endslot
@end

View File

@@ -0,0 +1,44 @@
@component('admin/layouts/main')
@slot('main')
<div class="flex justify-between items-center mb-6">
<h1 class="text-2xl font-bold">Projets</h1>
<a href="/admin/projects/create" class="bg-blue-600 text-white px-4 py-2 rounded hover:bg-blue-700">
Nouveau projet
</a>
</div>
<div class="bg-white rounded shadow overflow-hidden">
<table class="min-w-full divide-y divide-gray-200">
<thead class="bg-gray-50">
<tr>
<th class="px-4 py-2 text-left text-sm font-medium text-gray-700">Titre</th>
<th class="px-4 py-2 text-left text-sm font-medium text-gray-700">Catégorie</th>
<th class="px-4 py-2 text-left text-sm font-medium text-gray-700">Début</th>
<th class="px-4 py-2 text-right text-sm font-medium text-gray-700">Actions</th>
</tr>
</thead>
<tbody class="divide-y divide-gray-200">
@each(p in projects)
<tr>
<td class="px-4 py-2">{{ p.title }}</td>
<td class="px-4 py-2">{{ p.category?.name || '-' }}</td>
<td class="px-4 py-2">{{ p.start ? p.start.toISODate() : '-' }}</td>
<td class="px-4 py-2 text-right">
<a href="/admin/projects/{{ p.id }}/edit" class="text-blue-600 hover:underline mr-2">Modifier</a>
<form action="/admin/projects/{{ p.id }}/delete" method="post" class="inline">
{{{ csrfField() }}}
<button type="submit" class="text-red-600 hover:underline" onclick="return confirm('Supprimer ?')">
Supprimer
</button>
</form>
</td>
</tr>
@else
<tr>
<td colspan="4" class="px-4 py-6 text-center text-gray-500">Aucun projet</td>
</tr>
@endeach
</tbody>
</table>
</div>
@endslot
@end