Big refactoring of PARCOURSMOB - Initial commit
This commit is contained in:
47
themes/default/layouts/_partials/address_autocomplete.html
Normal file
47
themes/default/layouts/_partials/address_autocomplete.html
Normal file
@@ -0,0 +1,47 @@
|
||||
{{ define "address_autocomplete" }}
|
||||
|
||||
<div class="col-span-6 relative" x-data="{
|
||||
input: {{if .Address}}'{{.Address.properties.label}}'{{else}}null{{end}},
|
||||
address: null,
|
||||
addressObject: {{if .Address}}{properties: {label: '{{.Address.properties.label}}'}}{{else}}null{{end}},
|
||||
responselength: 0,
|
||||
async autocomplete() {
|
||||
if(this.input == null || this.input == '') {
|
||||
this.responselength = 0
|
||||
return []
|
||||
}
|
||||
if(this.addressObject != null && this.input == this.addressObject.properties.label) {
|
||||
this.responselength = 0
|
||||
return []
|
||||
}
|
||||
result = await fetch('https://geocode.ridygo.fr/v1/autocomplete/\?text=' + this.input)
|
||||
json = await result.json()
|
||||
|
||||
this.responselength = json['features'].length
|
||||
return json['features']
|
||||
},
|
||||
select(a) {
|
||||
this.address = JSON.stringify(a)
|
||||
this.addressObject = a
|
||||
this.input = a.properties.label
|
||||
}
|
||||
}">
|
||||
<input type="hidden" name="{{ .FieldName }}" x-model="address">
|
||||
<label for="address" class="block text-sm font-medium text-gray-700">Adresse</label>
|
||||
<input type="text"
|
||||
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm border-gray-300 rounded-2xl"
|
||||
x-model="input">
|
||||
|
||||
<ul x-show="responselength > 0"
|
||||
class="absolute z-10 mt-1 w-full bg-white shadow-lg max-h-60 rounded-xl py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm" tabindex="-1" role="listbox" aria-labelledby="listbox-label" aria-activedescendant="listbox-option-3">
|
||||
<template x-for="item in autocomplete">
|
||||
<a href="#">
|
||||
<li class="text-gray-900 hover:bg-gray-200 cursor-default select-none relative py-2 pl-3 pr-9"
|
||||
@click="select(item)">
|
||||
<span class="font-normal block truncate" x-text="item.properties.label" ></span>
|
||||
</li>
|
||||
</a>
|
||||
</template>
|
||||
</ul>
|
||||
</div>
|
||||
{{ end }}
|
||||
19
themes/default/layouts/_partials/mainmenu.html
Normal file
19
themes/default/layouts/_partials/mainmenu.html
Normal file
@@ -0,0 +1,19 @@
|
||||
{{define "mainmenu"}}
|
||||
|
||||
{{range .LayoutState.MenuItems}}
|
||||
<nav class="px-2 space-y-1">
|
||||
<a href="{{.Link}}"
|
||||
{{ if .Active }}
|
||||
class="bg-white text-co-blue group flex items-center px-2 py-2 text-base font-medium rounded-2xl">
|
||||
{{ else}}
|
||||
class="text-white hover:bg-white hover:bg-opacity-5 group flex items-center px-2 py-2 text-base font-medium rounded-2xl">
|
||||
{{end}}
|
||||
|
||||
{{$.IconSet.Icon .Icon "mr-4 flex-shrink-0 h-6 w-6"}}
|
||||
|
||||
{{.Title}}
|
||||
</a>
|
||||
</nav>
|
||||
{{end}}
|
||||
|
||||
{{end}}
|
||||
@@ -0,0 +1,37 @@
|
||||
{{define "groups_admins"}}
|
||||
<div class="border-t border-gray-200 px-4 py-5 sm:px-6">
|
||||
|
||||
<h2 class="text-md font-medium text-gray-900">Administrateurs</h2>
|
||||
|
||||
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
|
||||
|
||||
<div class="relative rounded-lg bg-white px-6 py-5 flex items-center space-x-3 focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-co-blue">
|
||||
<div class="flex-shrink-0">
|
||||
<img class="h-10 w-10 rounded-co" src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="">
|
||||
</div>
|
||||
<div class="flex-1 min-w-0">
|
||||
<a href="#" class="focus:outline-none">
|
||||
<span class="absolute inset-0" aria-hidden="true"></span>
|
||||
<p class="text-sm font-medium text-gray-900">Leslie Alexander</p>
|
||||
<p class="text-sm text-gray-500 truncate">aaa@bbb.fr</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- More people... -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-6 py-4">
|
||||
<h2 class="text-md font-medium text-gray-900">Ajouter</h2>
|
||||
<div class="flex">
|
||||
<div class="pr-2 flex-1">
|
||||
<input type="text" name="name" id="name"
|
||||
class="mt-1 border-gray-300 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm rounded-2xl"
|
||||
placeholder="Email">
|
||||
</div>
|
||||
<button class="px-1 py-1 border border-transparent text-sm font-medium rounded-2xl shadow-sm text-white bg-co-blue hover:bg-co-blue focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-co-blue">Ajouter</button>
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{{end}}
|
||||
142
themes/default/layouts/administration/create_group.html
Normal file
142
themes/default/layouts/administration/create_group.html
Normal file
@@ -0,0 +1,142 @@
|
||||
{{define "content"}}
|
||||
|
||||
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
|
||||
<h1 class="text-2xl font-semibold text-gray-900">Administration > Créer une organisation</h1>
|
||||
</div>
|
||||
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-8" x-data="{
|
||||
fields: {
|
||||
name: null,
|
||||
},
|
||||
rules: {
|
||||
name: ['required'],
|
||||
},
|
||||
formValidation: {
|
||||
valid: false,
|
||||
fields: {
|
||||
name: {valid: null},
|
||||
}
|
||||
},
|
||||
isFormValid: true,
|
||||
validate() {
|
||||
this.formValidation = Iodine.assert(this.fields, this.rules)
|
||||
},
|
||||
validateField(field) {
|
||||
this.formValidation.fields[field] = Iodine.assert(this.fields[field], this.rules[field])
|
||||
},
|
||||
submit(event) {
|
||||
this.validate()
|
||||
if(!this.formValidation.valid) {
|
||||
this.isFormValid = false
|
||||
event.preventDefault()
|
||||
}
|
||||
return this.formValidation.valid
|
||||
}
|
||||
}">
|
||||
<form class="space-y-6" method="POST" @submit="submit">
|
||||
<div class="bg-white shadow px-4 py-5 sm:rounded-lg sm:p-6">
|
||||
<div class="md:grid md:grid-cols-3 md:gap-6">
|
||||
<div class="md:col-span-1">
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900">Nouvelle organisation</h3>
|
||||
<p class="mt-1 text-sm text-gray-500">Informations de base sur la nouvelle organisation à créer</p>
|
||||
</div>
|
||||
<div class="mt-5 md:mt-0 md:col-span-2">
|
||||
<div class="grid grid-cols-6 gap-6">
|
||||
<div class="col-span-6">
|
||||
<label for="name" class="block text-sm font-medium text-gray-700">Nom de
|
||||
l'organisation</label>
|
||||
<input type="text" name="name" id="name"
|
||||
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm rounded-2xl"
|
||||
x-model="fields.name" @blur="validateField('name')"
|
||||
:class="formValidation.fields.name.valid == false ? 'border-co-red border-2' : 'border-gray-300'">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white shadow px-4 py-5 sm:rounded-lg sm:p-6">
|
||||
<div class="md:grid md:grid-cols-3 md:gap-6">
|
||||
<div class="md:col-span-1">
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900">Paramètres</h3>
|
||||
<p class="mt-1 text-sm text-gray-500">Paramètres de configuration de l'organisation (modules
|
||||
accessibles, ...)</p>
|
||||
</div>
|
||||
<div class="mt-5 md:mt-0 md:col-span-2">
|
||||
|
||||
<fieldset>
|
||||
<legend class="sr-only">Droits d'accès aux modules</legend>
|
||||
<div class="text-base font-medium text-gray-900" aria-hidden="true">Droits d'accès aux modules</div>
|
||||
<div class="mt-4 space-y-4">
|
||||
<div class="flex items-start">
|
||||
<div class="h-5 flex items-center">
|
||||
<input id="beneficiaries" name="modules.beneficiaries" type="checkbox" checked
|
||||
class="focus:ring-co-blue h-4 w-4 text-co-blue border-gray-300 rounded">
|
||||
</div>
|
||||
<div class="ml-3 text-sm">
|
||||
<label for="modules.beneficiaries" class="font-medium text-gray-700">Bénéficiaires</label>
|
||||
<p class="text-gray-500">Gestion des bénéficiaires assignés à sa propre organisation.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start">
|
||||
<div class="flex items-center h-5">
|
||||
<input id="journeys" name="modules.journeys" type="checkbox"
|
||||
class="focus:ring-co-blue h-4 w-4 text-co-blue border-gray-300 rounded">
|
||||
</div>
|
||||
<div class="ml-3 text-sm">
|
||||
<label for="modules.journeys" class="font-medium text-gray-700">Déplacements</label>
|
||||
<p class="text-gray-500">Trouver des solutions et organiser les déplacements de ses bénéficiaires.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start">
|
||||
<div class="flex items-center h-5">
|
||||
<input id="vehicles" name="modules.vehicles" type="checkbox"
|
||||
class="focus:ring-co-blue h-4 w-4 text-co-blue border-gray-300 rounded">
|
||||
</div>
|
||||
<div class="ml-3 text-sm">
|
||||
<label for="modules.vehicles" class="font-medium text-gray-700">Véhicules</label>
|
||||
<p class="text-gray-500">Trouver et réserver des véhicules pour ses bénéficiaires.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start">
|
||||
<div class="flex items-center h-5">
|
||||
<input id="vehicles_management" name="modules.vehicles_management" type="checkbox"
|
||||
class="focus:ring-co-blue h-4 w-4 text-co-blue border-gray-300 rounded">
|
||||
</div>
|
||||
<div class="ml-3 text-sm">
|
||||
<label for="modules.vehicles_management" class="font-medium text-gray-700">Gestion des véhicules</label>
|
||||
<p class="text-gray-500">Gérer les véhicules et réservations (pour les gestionnaires de flottes)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start">
|
||||
<div class="flex items-center h-5">
|
||||
<input id="events" name="modules.events" type="checkbox"
|
||||
class="focus:ring-co-blue h-4 w-4 text-co-blue border-gray-300 rounded">
|
||||
</div>
|
||||
<div class="ml-3 text-sm">
|
||||
<label for="modules.events" class="font-medium text-gray-700">Dispositifs</label>
|
||||
<p class="text-gray-500">Gestion des dispositifs pour les bénéficiaires (auto-écoles sociales, événements, ...)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<p x-show="! isFormValid" class="px-4 py-2 text-sm text-co-red">Certains champs de sont pas valides.</p>
|
||||
<a href="/app/administration/">
|
||||
<button type="button"
|
||||
class="bg-white py-2 px-4 border border-gray-300 rounded-2xl shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">Annuler</button>
|
||||
</a>
|
||||
<button type="submit"
|
||||
class="ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-2xl text-white bg-co-blue hover:bg-co-blue focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">Créer l'organisation</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
||||
114
themes/default/layouts/administration/display_group.html
Normal file
114
themes/default/layouts/administration/display_group.html
Normal file
@@ -0,0 +1,114 @@
|
||||
{{define "content"}}
|
||||
<main class="py-10">
|
||||
<div class="max-w-3xl mx-auto px-4 sm:px-6 md:flex md:items-center md:justify-between md:space-x-5 lg:max-w-7xl lg:px-8">
|
||||
<div class="flex items-center space-x-5">
|
||||
<!-- <div class="flex-shrink-0">
|
||||
<div class="relative">
|
||||
<img class="h-16 w-16 rounded-co" src="/app/beneficiaries/{{.ViewState.ID}}/picture" alt="">
|
||||
<span class="absolute inset-0 shadow-inner rounded-full" aria-hidden="true"></span>
|
||||
</div>
|
||||
</div> -->
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold text-gray-900">{{.ViewState.group.Data.name}}</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mt-6 flex flex-col-reverse justify-stretch space-y-4 space-y-reverse sm:flex-row-reverse sm:justify-end sm:space-x-reverse sm:space-y-0 sm:space-x-3 md:mt-0 md:flex-row md:space-x-3">
|
||||
<button type="button"
|
||||
class="inline-flex items-center justify-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-2xl text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-co-blue">Supprimer</button>
|
||||
<a href="/app/administration/groups/{{.ViewState.group.ID}}/update" class="inline-flex"><button type="button"
|
||||
class="w-full px-4 py-2 border border-transparent text-sm font-medium rounded-2xl shadow-sm text-white bg-co-blue hover:bg-co-blue focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-co-blue">Modifier</button></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-8 max-w-3xl mx-auto grid grid-cols-1 gap-6 sm:px-6 lg:max-w-7xl lg:grid-flow-col-dense lg:grid-cols-3">
|
||||
<div class="space-y-6 lg:col-start-1 lg:col-span-2">
|
||||
<section aria-labelledby="beneficiary-information-title">
|
||||
<div class="bg-white shadow sm:rounded-lg">
|
||||
<div class="px-4 py-5 sm:px-6">
|
||||
<h2 id="beneficiary-information-title" class="text-lg leading-6 font-medium text-gray-900">
|
||||
Paramètres de l'organisation</h2>
|
||||
<p class="mt-1 max-w-2xl text-sm text-gray-500">Paramètres généraux de l'organisation</p>
|
||||
</div>
|
||||
{{template "groups_admins" .}}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<section aria-labelledby="modules-title" class="lg:col-start-3 lg:col-span-1">
|
||||
<div class="bg-white px-4 py-5 shadow sm:rounded-lg sm:px-6">
|
||||
<h2 id="modules-title" class="text-lg font-medium text-gray-900">Modules activés</h2>
|
||||
|
||||
<fieldset>
|
||||
<div class="mt-4 space-y-4">
|
||||
<div class="flex items-start">
|
||||
<div class="h-5 flex items-center">
|
||||
<input id="beneficiaries" name="modules.beneficiaries" type="checkbox" disabled {{if .ViewState.group.Data.modules.beneficiaries}} checked{{end}}
|
||||
class="focus:ring-co-blue h-4 w-4 text-co-blue border-gray-300 rounded">
|
||||
</div>
|
||||
<div class="ml-3 text-sm">
|
||||
<label for="modules.beneficiaries" class="font-medium text-gray-700">Bénéficiaires</label>
|
||||
<p class="text-gray-500">Gestion des bénéficiaires assignés à sa propre organisation.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start">
|
||||
<div class="flex items-center h-5">
|
||||
<input id="journeys" name="modules.journeys" type="checkbox" disabled {{if .ViewState.group.Data.modules.journeys}} checked{{end}}
|
||||
class="focus:ring-co-blue h-4 w-4 text-co-blue border-gray-300 rounded">
|
||||
</div>
|
||||
<div class="ml-3 text-sm">
|
||||
<label for="modules.journeys" class="font-medium text-gray-700">Déplacements</label>
|
||||
<p class="text-gray-500">Trouver des solutions et organiser les déplacements de ses bénéficiaires.</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start">
|
||||
<div class="flex items-center h-5">
|
||||
<input id="vehicles" name="modules.vehicles" type="checkbox" disabled {{if .ViewState.group.Data.modules.vehicles}} checked{{end}}
|
||||
class="focus:ring-co-blue h-4 w-4 text-co-blue border-gray-300 rounded">
|
||||
</div>
|
||||
<div class="ml-3 text-sm">
|
||||
<label for="modules.vehicles" class="font-medium text-gray-700">Véhicules</label>
|
||||
<p class="text-gray-500">Trouver et réserver des véhicules pour ses bénéficiaires.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start">
|
||||
<div class="flex items-center h-5">
|
||||
<input id="vehicles_management" name="modules.vehicles_management" type="checkbox" disabled {{if .ViewState.group.Data.modules.vehicles_management}} checked{{end}}
|
||||
class="focus:ring-co-blue h-4 w-4 text-co-blue border-gray-300 rounded">
|
||||
</div>
|
||||
<div class="ml-3 text-sm">
|
||||
<label for="modules.vehicles_management" class="font-medium text-gray-700">Gestion des véhicules</label>
|
||||
<p class="text-gray-500">Gérer les véhicules et réservations (pour les gestionnaires de flottes)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start">
|
||||
<div class="flex items-center h-5">
|
||||
<input id="events" name="modules.events" type="checkbox" disabled {{if .ViewState.group.Data.modules.events}} checked{{end}}
|
||||
class="focus:ring-co-blue h-4 w-4 text-co-blue border-gray-300 rounded">
|
||||
</div>
|
||||
<div class="ml-3 text-sm">
|
||||
<label for="modules.events" class="font-medium text-gray-700">Dispositifs</label>
|
||||
<p class="text-gray-500">Gestion des dispositifs pour les bénéficiaires (auto-écoles sociales, événements, ...)
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex items-start">
|
||||
<div class="flex items-center h-5">
|
||||
<input id="events" name="modules.events" type="checkbox" disabled {{if .ViewState.group.Data.modules.administration}} checked{{end}}
|
||||
class="focus:ring-co-blue h-4 w-4 text-co-blue border-gray-300 rounded">
|
||||
</div>
|
||||
<div class="ml-3 text-sm">
|
||||
<label for="modules.events" class="font-medium text-gray-700">Administration</label>
|
||||
<p class="text-gray-500">Administration générale de la plateforme PARCOURSMOB. Créer, ajouter des organisations et administrateurs.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</div>
|
||||
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
{{end}}
|
||||
136
themes/default/layouts/administration/home.html
Normal file
136
themes/default/layouts/administration/home.html
Normal file
@@ -0,0 +1,136 @@
|
||||
{{define "content"}}
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
|
||||
<h1 class="text-2xl font-semibold text-gray-900">Administration</h1>
|
||||
</div>
|
||||
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-8">
|
||||
<h2 class="text-gray-500 text-xs font-medium uppercase tracking-wide">Statistiques</h2>
|
||||
<ul role="list" class="mt-3 grid grid-cols-1 gap-5 sm:gap-6 sm:grid-cols-2 lg:grid-cols-4">
|
||||
<li class="col-span-1 flex shadow-sm rounded-3xl">
|
||||
<div
|
||||
class="flex-shrink-0 flex items-center justify-center w-16 bg-co-blue text-white text-sm font-medium rounded-l-3xl">
|
||||
{{.IconSet.Icon "hero:outline/user-group" "h-6 w-6"}}
|
||||
</div>
|
||||
<div
|
||||
class="flex-1 flex items-center justify-between border-t border-r border-b border-gray-200 bg-white rounded-r-3xl truncate">
|
||||
<div class="flex-1 px-4 py-2 text-sm truncate">
|
||||
<a href="#" class="text-gray-900 font-medium hover:text-gray-600">Bénéficiaires</a>
|
||||
<p class="text-gray-500">160 bénéficiaires</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="col-span-1 flex shadow-sm rounded-3xl">
|
||||
<div
|
||||
class="flex-shrink-0 flex items-center justify-center w-16 bg-co-green text-white text-sm font-medium rounded-l-3xl">
|
||||
{{.IconSet.Icon "hero:outline/office-building" "h-6 w-6"}}
|
||||
</div>
|
||||
<div
|
||||
class="flex-1 flex items-center justify-between border-t border-r border-b border-gray-200 bg-white rounded-r-3xl truncate">
|
||||
<div class="flex-1 px-4 py-2 text-sm truncate">
|
||||
<a href="#" class="text-gray-900 font-medium hover:text-gray-600">Organisations</a>
|
||||
<p class="text-gray-500">12 organisations</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="col-span-1 flex shadow-sm rounded-3xl">
|
||||
<div
|
||||
class="flex-shrink-0 flex items-center justify-center w-16 bg-co-red text-white text-sm font-medium rounded-l-3xl">
|
||||
{{.IconSet.Icon "hero:outline/briefcase" "h-6 w-6"}}
|
||||
</div>
|
||||
<div
|
||||
class="flex-1 flex items-center justify-between border-t border-r border-b border-gray-200 bg-white rounded-r-3xl truncate">
|
||||
<div class="flex-1 px-4 py-2 text-sm truncate">
|
||||
<a href="#" class="text-gray-900 font-medium hover:text-gray-600">Référents</a>
|
||||
<p class="text-gray-500">53 membres</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="col-span-1 flex shadow-sm rounded-3xl">
|
||||
<div
|
||||
class="flex-shrink-0 flex items-center justify-center w-16 bg-co-yellow text-white text-sm font-medium rounded-l-3xl">
|
||||
{{.IconSet.Icon "hero:outline/shield-check" "h-6 w-6"}}
|
||||
</div>
|
||||
<div
|
||||
class="flex-1 flex items-center justify-between border-t border-r border-b border-gray-200 bg-white rounded-r-3xl truncate">
|
||||
<div class="flex-1 px-4 py-2 text-sm truncate">
|
||||
<a href="#" class="text-gray-900 font-medium hover:text-gray-600">Accompagnement</a>
|
||||
<p class="text-gray-500">363 actions réalisées</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="max-w-7xl mt-10 mx-auto px-4 sm:px-6 md:px-8">
|
||||
<h2 class="text-xl font-semibold text-gray-500">Gestion des organisations</h2>
|
||||
|
||||
<div class="sm:flex sm:items-center">
|
||||
<div class="sm:flex-auto">
|
||||
<p class="mt-2 text-sm text-gray-700"></p>
|
||||
</div>
|
||||
<div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
|
||||
<a href="/app/administration/groups/">
|
||||
<button type="button"
|
||||
class="inline-flex items-center justify-center rounded-2xl border border-transparent bg-co-blue px-4 py-2 text-sm font-medium text-white shadow-sm focus:outline-none focus:ring-2 focus:ring-co-blue focus:ring-offset-2 sm:w-auto">
|
||||
{{$.IconSet.Icon "hero:outline/plus-circle" "h-5 w-5 mr-3"}}
|
||||
Ajouter une organisation
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white shadow overflow-hidden sm:rounded-3xl mt-4">
|
||||
<ul role="list" class="divide-y divide-gray-200">
|
||||
{{range .ViewState.groups}}
|
||||
<li>
|
||||
<a href="/app/administration/groups/{{.ID}}" class="block hover:bg-gray-50">
|
||||
<div class="px-4 py-4 flex items-center sm:px-6">
|
||||
<div class="min-w-0 flex-1 sm:flex sm:items-center sm:justify-between">
|
||||
<div class="truncate">
|
||||
<div class="flex text-sm">
|
||||
<p class="font-medium text-lg text-co-blue truncate">{{.Data.name}}</p>
|
||||
<p class="ml-1 flex-shrink-0 font-normal text-gray-500"></p>
|
||||
</div>
|
||||
<div class="mt-2 flex">
|
||||
<div class="flex items-center text-sm text-gray-500">
|
||||
{{$.IconSet.Icon "hero:outline/user-group" "flex-shrink-0 mr-1.5 h-5 w-5"}}
|
||||
<p>
|
||||
{{ len .Members }} bénéficiaires
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-4 flex-shrink-0 sm:mt-0 sm:ml-5">
|
||||
<div class="flex overflow-hidden -space-x-1">
|
||||
<img class="inline-block h-6 w-6 rounded-full ring-2 ring-white"
|
||||
src="https://images.unsplash.com/photo-1506794778202-cad84cf45f1d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
|
||||
alt="Dries Vincent">
|
||||
|
||||
<img class="inline-block h-6 w-6 rounded-full ring-2 ring-white"
|
||||
src="https://images.unsplash.com/photo-1517841905240-472988babdf9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
|
||||
alt="Lindsay Walton">
|
||||
|
||||
<img class="inline-block h-6 w-6 rounded-full ring-2 ring-white"
|
||||
src="https://images.unsplash.com/photo-1438761681033-6461ffad8d80?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
|
||||
alt="Courtney Henry">
|
||||
|
||||
<img class="inline-block h-6 w-6 rounded-full ring-2 ring-white"
|
||||
src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
|
||||
alt="Tom Cook">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="ml-5 flex-shrink-0">
|
||||
{{$.IconSet.Icon "hero:solid/chevron-right" "h-5 w-5 text-gray-400"}}
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
40
themes/default/layouts/auth/groups.html
Normal file
40
themes/default/layouts/auth/groups.html
Normal file
@@ -0,0 +1,40 @@
|
||||
{{define "main"}}
|
||||
<html class="h-full bg-gray-50">
|
||||
<head>
|
||||
<title>PARCOURSMOB</title>
|
||||
<link rel="stylesheet" href="/public/css/main.css" />
|
||||
<!-- <script defer type="text/javascript" src="/public/js/main.js" defer></script> -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/@kingshott/iodine@8.1.0/dist/iodine.min.umd.js" defer></script>
|
||||
<script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
|
||||
</head>
|
||||
<body class="h-full">
|
||||
<div class="min-h-full flex flex-col justify-center py-12 sm:px-6 lg:px-8 h-">
|
||||
<div class="sm:mx-auto sm:w-full sm:max-w-md">
|
||||
{{.IconSet.Icon "coopgo:parcoursmob/monogram" "mx-auto h-16 w-auto"}}
|
||||
<h2 class="mt-6 text-center text-3xl font-extrabold text-gray-900">Connectez vous à votre organisation</h2>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md">
|
||||
<div class="bg-white shadow sm:rounded-3xl">
|
||||
<form id="groupform" class="space-y-6" action="" method="POST" x-data="{group: null}" x-init="$watch('group', value => document.getElementById('groupform').submit())">
|
||||
<fieldset>
|
||||
<legend class="sr-only">Organisations</legend>
|
||||
{{range .ViewState.groups}}
|
||||
<div class="relative bg-white rounded-md -space-y-px sm:rounded-3xl">
|
||||
<label class="sm:rounded-3xl relative text-co-blue hover:text-white hover:bg-co-blue p-4 flex flex-row cursor-pointer md:pl-4 md:pr-6 focus:outline-none">
|
||||
<span class="flex-1 items-center text-xl">
|
||||
<input x-model="group" type="radio" name="group" value="{{.ID}}" class="h-4 w-4 sr-only" aria-labelledby="group-{{.ID}}-label" aria-describedby="group-{{.ID}}-description-0">
|
||||
<span id="group-{{.ID}}-label" class="ml-3 font-medium">{{.Data.name}}</span>
|
||||
</span>
|
||||
<span id="group-{{.ID}}-description-0" class="ml-6 pl-1 text-sm md:ml-0 md:pl-0 md:text-right">{{$.IconSet.Icon "hero:solid/chevron-right" "w-6 h-6"}}</span>
|
||||
</label>
|
||||
</div>
|
||||
{{end}}
|
||||
</fieldset>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
{{end}}
|
||||
@@ -0,0 +1,5 @@
|
||||
{{define "beneficiary_events"}}
|
||||
<div class="px-4 py-6 sm:px-6">
|
||||
TODO Dispositifs
|
||||
</div>
|
||||
{{end}}
|
||||
@@ -0,0 +1,5 @@
|
||||
{{define "beneficiary_files"}}
|
||||
<div class="px-4 py-6 sm:px-6">
|
||||
TODO Fichiers
|
||||
</div>
|
||||
{{end}}
|
||||
@@ -0,0 +1,5 @@
|
||||
{{define "beneficiary_journeys"}}
|
||||
<div class="px-4 py-6 sm:px-6">
|
||||
TODO Déplacements
|
||||
</div>
|
||||
{{end}}
|
||||
@@ -0,0 +1,108 @@
|
||||
{{define "beneficiary_notes"}}
|
||||
<div class="px-4 py-6 sm:px-6">
|
||||
<ul role="list" class="space-y-8">
|
||||
<li>
|
||||
<div class="flex space-x-3">
|
||||
<div class="flex-shrink-0">
|
||||
<img class="h-10 w-10 rounded-full"
|
||||
src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
|
||||
alt="">
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-sm">
|
||||
<a href="#" class="font-medium text-gray-900">Leslie Alexander</a>
|
||||
</div>
|
||||
<div class="mt-1 text-sm text-gray-700">
|
||||
<p>Ducimus quas delectus ad maxime totam doloribus reiciendis ex.
|
||||
Tempore dolorem maiores. Similique voluptatibus tempore non ut.</p>
|
||||
</div>
|
||||
<div class="mt-2 text-sm space-x-2">
|
||||
<span class="text-gray-500 font-medium">4d ago</span>
|
||||
<span class="text-gray-500 font-medium">·</span>
|
||||
<button type="button" class="text-gray-900 font-medium">Reply</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div class="flex space-x-3">
|
||||
<div class="flex-shrink-0">
|
||||
<img class="h-10 w-10 rounded-full"
|
||||
src="https://images.unsplash.com/photo-1519244703995-f4e0f30006d5?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
|
||||
alt="">
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-sm">
|
||||
<a href="#" class="font-medium text-gray-900">Michael Foster</a>
|
||||
</div>
|
||||
<div class="mt-1 text-sm text-gray-700">
|
||||
<p>Et ut autem. Voluptatem eum dolores sint necessitatibus quos. Quis
|
||||
eum qui dolorem accusantium voluptas voluptatem ipsum. Quo facere
|
||||
iusto quia accusamus veniam id explicabo et aut.</p>
|
||||
</div>
|
||||
<div class="mt-2 text-sm space-x-2">
|
||||
<span class="text-gray-500 font-medium">4d ago</span>
|
||||
<span class="text-gray-500 font-medium">·</span>
|
||||
<button type="button" class="text-gray-900 font-medium">Reply</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div class="flex space-x-3">
|
||||
<div class="flex-shrink-0">
|
||||
<img class="h-10 w-10 rounded-full"
|
||||
src="https://images.unsplash.com/photo-1506794778202-cad84cf45f1d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
|
||||
alt="">
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-sm">
|
||||
<a href="#" class="font-medium text-gray-900">Dries Vincent</a>
|
||||
</div>
|
||||
<div class="mt-1 text-sm text-gray-700">
|
||||
<p>Expedita consequatur sit ea voluptas quo ipsam recusandae. Ab sint et
|
||||
voluptatem repudiandae voluptatem et eveniet. Nihil quas consequatur
|
||||
autem. Perferendis rerum et.</p>
|
||||
</div>
|
||||
<div class="mt-2 text-sm space-x-2">
|
||||
<span class="text-gray-500 font-medium">4d ago</span>
|
||||
<span class="text-gray-500 font-medium">·</span>
|
||||
<button type="button" class="text-gray-900 font-medium">Reply</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bg-gray-50 px-4 py-6 sm:px-6">
|
||||
<div class="flex space-x-3">
|
||||
<div class="flex-shrink-0">
|
||||
<img class="h-10 w-10 rounded-co"
|
||||
src="https://images.unsplash.com/photo-1517365830460-955ce3ccd263?ixlib=rb-=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=8&w=256&h=256&q=80"
|
||||
alt="">
|
||||
</div>
|
||||
<div class="min-w-0 flex-1">
|
||||
<form action="#">
|
||||
<div>
|
||||
<label for="comment" class="sr-only">Note</label>
|
||||
<textarea id="comment" name="comment" rows="3"
|
||||
class="shadow-sm block w-full focus:ring-blue-500 focus:border-blue-500 sm:text-sm border border-gray-300 rounded-md"
|
||||
placeholder="Ajouter une note"></textarea>
|
||||
</div>
|
||||
<div class="mt-3 flex items-center justify-between">
|
||||
<a href="#"
|
||||
class="group inline-flex items-start text-sm space-x-2 text-gray-500 hover:text-gray-900">
|
||||
<!-- Heroicon name: solid/question-mark-circle -->
|
||||
{{.IconSet.Icon "hero:solid/question-mark-icon" "flex-shrink-0 h-5 w-5 text-gray-400 group-hover:text-gray-500" }}
|
||||
<span> Accepte le "markdown". </span>
|
||||
</a>
|
||||
<button type="submit"
|
||||
class="inline-flex items-center justify-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-co-blue hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">Ajouter la note</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
173
themes/default/layouts/beneficiaries/create.html
Normal file
173
themes/default/layouts/beneficiaries/create.html
Normal file
@@ -0,0 +1,173 @@
|
||||
{{define "content"}}
|
||||
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
|
||||
<h1 class="text-2xl font-semibold text-gray-900">Ajouter un bénéficiaire</h1>
|
||||
</div>
|
||||
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-8"
|
||||
x-data="{
|
||||
fields: {
|
||||
first_name: null,
|
||||
last_name: null,
|
||||
email: null,
|
||||
phone_number: null,
|
||||
birthdate: null
|
||||
},
|
||||
rules: {
|
||||
first_name: ['required'],
|
||||
last_name: ['required'],
|
||||
email: ['required', 'email'],
|
||||
phone_number: ['required', 'regexMatch:^((\\+)33|0)[1-9](\\d{2}){4}$'],
|
||||
birthdate: ['optional'],
|
||||
},
|
||||
formValidation: {
|
||||
valid: false,
|
||||
fields: {
|
||||
first_name: {valid: null},
|
||||
last_name: {valid: null},
|
||||
email: {valid: null},
|
||||
phone_number: {valid: null},
|
||||
birthdate: {valid: null},
|
||||
}
|
||||
},
|
||||
isFormValid: true,
|
||||
validate() {
|
||||
this.formValidation = Iodine.assert(this.fields, this.rules)
|
||||
},
|
||||
validateField(field) {
|
||||
this.formValidation.fields[field] = Iodine.assert(this.fields[field], this.rules[field])
|
||||
},
|
||||
submit(event) {
|
||||
this.validate()
|
||||
if(!this.formValidation.valid) {
|
||||
this.isFormValid = false
|
||||
event.preventDefault()
|
||||
}
|
||||
return this.formValidation.valid
|
||||
}
|
||||
}">
|
||||
<form class="space-y-6" method="POST" @submit="submit">
|
||||
<div class="bg-white shadow px-4 py-5 sm:rounded-lg sm:p-6">
|
||||
<div class="md:grid md:grid-cols-3 md:gap-6">
|
||||
<div class="md:col-span-1">
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900">Informations obligatoires</h3>
|
||||
<p class="mt-1 text-sm text-gray-500">Informations personnelles sur le bénéficiaire obligatoires
|
||||
pour créer son profil dans PARCOURSMOB</p>
|
||||
</div>
|
||||
<div class="mt-5 md:mt-0 md:col-span-2">
|
||||
<div class="grid grid-cols-6 gap-6">
|
||||
<div class="col-span-6 sm:col-span-3">
|
||||
<label for="first_name" class="block text-sm font-medium text-gray-700">Prénom</label>
|
||||
<input type="text" name="first_name" id="first_name" autocomplete="given-name"
|
||||
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm rounded-2xl"
|
||||
x-model="fields.first_name" @blur="validateField('first_name')"
|
||||
:class="formValidation.fields.first_name.valid == false ? 'border-co-red border-2' : 'border-gray-300'">
|
||||
</div>
|
||||
|
||||
<div class="col-span-6 sm:col-span-3">
|
||||
<label for="last_name" class="block text-sm font-medium text-gray-700">Nom</label>
|
||||
<input type="text" name="last_name" id="last_name" autocomplete="family-name"
|
||||
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm rounded-2xl"
|
||||
x-model="fields.last_name" @blur="validateField('last_name')"
|
||||
:class="formValidation.fields.last_name.valid == false ? 'border-co-red border-2' : 'border-gray-300'">
|
||||
</div>
|
||||
|
||||
<div class="col-span-6 sm:col-span-4">
|
||||
<label for="email" class="block text-sm font-medium text-gray-700">Email</label>
|
||||
<input type="text" name="email" id="email" autocomplete="email"
|
||||
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm rounded-2xl"
|
||||
x-model="fields.email" @blur="validateField('email')"
|
||||
:class="formValidation.fields.email.valid == false ? 'border-co-red border-2' : 'border-gray-300'">
|
||||
</div>
|
||||
|
||||
<div class="col-span-6 sm:col-span-4">
|
||||
<label for="phone_number" class="block text-sm font-medium text-gray-700">Numéro de
|
||||
téléphone</label>
|
||||
<input type="text" name="phone_number" id="phone_number" autocomplete="phone" placeholder="+33612345678"
|
||||
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm rounded-2xl"
|
||||
x-model="fields.phone_number" @blur="validateField('phone_number')"
|
||||
:class="formValidation.fields.phone_number.valid == false ? 'border-co-red border-2' : 'border-gray-300'">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white shadow px-4 py-5 sm:rounded-lg sm:p-6">
|
||||
<div class="md:grid md:grid-cols-3 md:gap-6">
|
||||
<div class="md:col-span-1">
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900">Informations optionnelles</h3>
|
||||
<p class="mt-1 text-sm text-gray-500">Autres informations de profil optionnelles</p>
|
||||
</div>
|
||||
<div class="mt-5 space-y-6 md:mt-0 md:col-span-2">
|
||||
<div class="grid grid-cols-6 gap-6">
|
||||
|
||||
<div class="col-span-6 sm:col-span-3">
|
||||
<label for="birthdate" class="block text-sm font-medium text-gray-700">Date de
|
||||
naissance</label>
|
||||
<input type="date" name="birthdate" id="birthdate" autocomplete="birthdate" placeholder="JJ/MM/AAAA"
|
||||
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm rounded-2xl"
|
||||
x-model="fields.birthdate" @blur="validateField('birthdate')"
|
||||
:class="formValidation.fields.birthdate.valid == false ? 'border-co-red border-2' : 'border-gray-300'">
|
||||
</div>
|
||||
|
||||
<div class="col-span-6 sm:col-span-3">
|
||||
<label for="gender" class="block text-sm font-medium text-gray-700">Genre</label>
|
||||
<div class="sm:mt-0 sm:col-span-2">
|
||||
<select id="gender" name="gender" autocomplete="gender" x-model="gender"
|
||||
class="max-w-lg mt-1 block focus:ring-co-blue focus:border-co-blue w-full shadow-sm sm:max-w-xs sm:text-sm border-gray-300 rounded-2xl">
|
||||
<option value="0">Inconnu</option>
|
||||
<option value="1">Masculin</option>
|
||||
<option value="2">Féminin</option>
|
||||
<option value="9">Sans objet</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="col-span-3 sm:col-span-3">
|
||||
<label class="block text-sm font-medium text-gray-700"> Photo </label>
|
||||
<div class="mt-1 flex items-center space-x-5">
|
||||
<span class="inline-block h-12 w-12 rounded-co overflow-hidden bg-gray-100">
|
||||
{{.IconSet.Icon "img:profile-picture-placeholder" "h-full w-full"}}
|
||||
</span>
|
||||
<button type="button"
|
||||
class="bg-white py-2 px-3 border border-gray-300 rounded-2xl shadow-sm text-sm leading-4 font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">
|
||||
Charger la photo
|
||||
</button>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white shadow px-4 py-5 sm:rounded-lg sm:p-6">
|
||||
<div class="md:grid md:grid-cols-3 md:gap-6">
|
||||
<div class="md:col-span-1">
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900">Paramètres</h3>
|
||||
<p class="mt-1 text-sm text-gray-500">Paramètres liés au bénéficiaire, utiles pour exploiter les fonctionnalités de PARCOURSMOB</p>
|
||||
</div>
|
||||
<div class="mt-5 space-y-6 md:mt-0 md:col-span-2">
|
||||
|
||||
{{ $fieldName := "address" }}
|
||||
{{ template "address_autocomplete" dict "FieldName" $fieldName }}
|
||||
|
||||
<!-- will dolater : tags, groups, ... -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<p x-show="! isFormValid" class="px-4 py-2 text-sm text-co-red">Certains champs de sont pas valides.</p>
|
||||
<a href="/app/beneficiaries/">
|
||||
<button type="button"
|
||||
class="bg-white py-2 px-4 border border-gray-300 rounded-2xl shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">Annuler</button>
|
||||
</a>
|
||||
<button type="submit"
|
||||
class="ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-2xl text-white bg-co-blue hover:bg-co-blue focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">Créer le bénéficiaire</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
||||
304
themes/default/layouts/beneficiaries/display.html
Normal file
304
themes/default/layouts/beneficiaries/display.html
Normal file
@@ -0,0 +1,304 @@
|
||||
{{define "content"}}
|
||||
<main class="py-10">
|
||||
<!-- Page header -->
|
||||
<div class="max-w-3xl mx-auto px-4 sm:px-6 md:flex md:items-center md:justify-between md:space-x-5 lg:max-w-7xl lg:px-8">
|
||||
<div class="flex items-center space-x-5">
|
||||
<div class="flex-shrink-0">
|
||||
<div class="relative">
|
||||
<img class="h-16 w-16 rounded-co" src="/app/beneficiaries/{{.ViewState.ID}}/picture" alt="">
|
||||
<span class="absolute inset-0 shadow-inner rounded-full" aria-hidden="true"></span>
|
||||
</div>
|
||||
</div>
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold text-gray-900">{{.ViewState.Data.first_name}}
|
||||
{{.ViewState.Data.last_name}}</h1>
|
||||
<p class="text-sm font-medium text-gray-500">{{if .ViewState.Metadata.created}}Ajouté le <time
|
||||
datetime="2022-07-25">{{.ViewState.Metadata.created}}</time> par
|
||||
<a href="#" class="text-gray-900">Conseiller 1</a>{{end}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mt-6 flex flex-col-reverse justify-stretch space-y-4 space-y-reverse sm:flex-row-reverse sm:justify-end sm:space-x-reverse sm:space-y-0 sm:space-x-3 md:mt-0 md:flex-row md:space-x-3">
|
||||
<button type="button"
|
||||
class="inline-flex items-center justify-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-2xl text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-co-blue">Supprimer</button>
|
||||
<a href="/app/beneficiaries/{{.ViewState.ID}}/update" class="inline-flex"><button type="button"
|
||||
class="w-full px-4 py-2 border border-transparent text-sm font-medium rounded-2xl shadow-sm text-white bg-co-blue hover:bg-co-blue focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-co-blue">Modifier</button></a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 max-w-3xl mx-auto grid grid-cols-1 gap-6 sm:px-6 lg:max-w-7xl lg:grid-flow-col-dense lg:grid-cols-3">
|
||||
<div class="space-y-6 lg:col-start-1 lg:col-span-2">
|
||||
<section aria-labelledby="beneficiary-information-title">
|
||||
<div class="bg-white shadow sm:rounded-lg">
|
||||
<div class="px-4 py-5 sm:px-6">
|
||||
<h2 id="beneficiary-information-title" class="text-lg leading-6 font-medium text-gray-900">
|
||||
Informations personnelles</h2>
|
||||
<p class="mt-1 max-w-2xl text-sm text-gray-500">Informations générales sur le bénéficiaire.</p>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 px-4 py-5 sm:px-6">
|
||||
<dl class="grid grid-cols-1 gap-x-4 gap-y-8 sm:grid-cols-2">
|
||||
{{if .ViewState.Data.email}}
|
||||
<div class="sm:col-span-1">
|
||||
<dt class="text-sm font-medium text-gray-500">Email</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900">{{.ViewState.Data.email}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if .ViewState.Data.phone_number}}
|
||||
<div class="sm:col-span-1">
|
||||
<dt class="text-sm font-medium text-gray-500">Téléphone</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900">{{.ViewState.Data.phone_number}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if .ViewState.Data.birthdate}}
|
||||
<div class="sm:col-span-1">
|
||||
<dt class="text-sm font-medium text-gray-500">Date de naissance</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900">{{(timeFrom .ViewState.Data.birthdate).Format
|
||||
"02/01/2006"}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if and .ViewState.Data.gender (ne .ViewState.Data.gender "0")}}
|
||||
<div class="sm:col-span-1">
|
||||
<dt class="text-sm font-medium text-gray-500">Genre</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900">{{genderISO5218 .ViewState.Data.gender}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if .ViewState.Data.address}}
|
||||
<div class="sm:col-span-1">
|
||||
<dt class="text-sm font-medium text-gray-500">Adresse</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900">{{.ViewState.Data.address.properties.label}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section aria-labelledby="functionalities-title" x-data="{
|
||||
tab: 'notes',
|
||||
to(event) {
|
||||
this.tab = event.target.value
|
||||
}
|
||||
}">
|
||||
<div class="bg-white shadow sm:rounded-lg sm:overflow-hidden">
|
||||
<div class="divide-y divide-gray-200">
|
||||
<div>
|
||||
<div class="sm:hidden">
|
||||
<label for="tabs" class="sr-only">Select a tab</label>
|
||||
<select id="tabs" name="tabs" @change="to"
|
||||
class="block w-full pl-3 pr-10 py-2 text-base border-gray-300 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm rounded-md">
|
||||
<option value="notes">Notes</option>
|
||||
|
||||
<option value="journeys">Déplacements</option>
|
||||
|
||||
<option value="events">Dispositifs</option>
|
||||
|
||||
<option value="files">Documents</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="hidden sm:block">
|
||||
<div class="border-b border-gray-200 pl-4">
|
||||
<nav class="-mb-px flex space-x-8" aria-label="Tabs">
|
||||
<!-- Current: "border-indigo-500 text-indigo-600", Default: "border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300" -->
|
||||
<a href="#" @click="tab = 'notes'"
|
||||
class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
|
||||
:class="tab == 'notes' ? 'border-co-blue text-co-blue' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'">
|
||||
Notes </a>
|
||||
|
||||
<a href="#" @click="tab = 'journeys'"
|
||||
class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
|
||||
:class="tab == 'journeys' ? 'border-co-blue text-co-blue' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'">
|
||||
Déplacements </a>
|
||||
|
||||
<a href="#" @click="tab = 'vehicles'"
|
||||
class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
|
||||
:class="tab == 'vehicles' ? 'border-co-blue text-co-blue' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'">
|
||||
Véhicules </a>
|
||||
|
||||
<a href="#" @click="tab = 'events'"
|
||||
class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
|
||||
:class="tab == 'events' ? 'border-co-blue text-co-blue' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'">
|
||||
Dispositifs </a>
|
||||
|
||||
<a href="#" @click="tab = 'files'"
|
||||
class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
|
||||
:class="tab == 'files' ? 'border-co-blue text-co-blue' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'">
|
||||
Documents </a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div x-show="tab == 'notes'">{{template "beneficiary_notes" .}}</div>
|
||||
<div x-show="tab == 'journeys'">{{template "beneficiary_journeys" .}}</div>
|
||||
<div x-show="tab == 'events'">{{template "beneficiary_events" .}}</div>
|
||||
<div x-show="tab == 'files'">{{template "beneficiary_files" .}}</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<section aria-labelledby="timeline-title" class="lg:col-start-3 lg:col-span-1">
|
||||
<div class="bg-white px-4 py-5 shadow sm:rounded-lg sm:px-6">
|
||||
<h2 id="timeline-title" class="text-lg font-medium text-gray-900">Actions réalisées</h2>
|
||||
|
||||
<!-- Activity Feed -->
|
||||
<div class="mt-6 flow-root">
|
||||
<ul role="list" class="-mb-8">
|
||||
<li>
|
||||
<div class="relative pb-8">
|
||||
<span class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200"
|
||||
aria-hidden="true"></span>
|
||||
<div class="relative flex space-x-3">
|
||||
<div>
|
||||
<span
|
||||
class="h-8 w-8 rounded-full bg-gray-400 flex items-center justify-center ring-8 ring-white">
|
||||
<!-- Heroicon name: solid/user -->
|
||||
<svg class="w-5 h-5 text-white" xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd"
|
||||
d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z"
|
||||
clip-rule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4">
|
||||
<div>
|
||||
<p class="text-sm text-gray-500">Applied to <a href="#"
|
||||
class="font-medium text-gray-900">Front End Developer</a></p>
|
||||
</div>
|
||||
<div class="text-right text-sm whitespace-nowrap text-gray-500">
|
||||
<time datetime="2020-09-20">Sep 20</time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div class="relative pb-8">
|
||||
<span class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200"
|
||||
aria-hidden="true"></span>
|
||||
<div class="relative flex space-x-3">
|
||||
<div>
|
||||
<span
|
||||
class="h-8 w-8 rounded-full bg-blue-500 flex items-center justify-center ring-8 ring-white">
|
||||
<!-- Heroicon name: solid/thumb-up -->
|
||||
<svg class="w-5 h-5 text-white" xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path
|
||||
d="M2 10.5a1.5 1.5 0 113 0v6a1.5 1.5 0 01-3 0v-6zM6 10.333v5.43a2 2 0 001.106 1.79l.05.025A4 4 0 008.943 18h5.416a2 2 0 001.962-1.608l1.2-6A2 2 0 0015.56 8H12V4a2 2 0 00-2-2 1 1 0 00-1 1v.667a4 4 0 01-.8 2.4L6.8 7.933a4 4 0 00-.8 2.4z" />
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4">
|
||||
<div>
|
||||
<p class="text-sm text-gray-500">Advanced to phone screening by <a href="#"
|
||||
class="font-medium text-gray-900">Bethany Blake</a></p>
|
||||
</div>
|
||||
<div class="text-right text-sm whitespace-nowrap text-gray-500">
|
||||
<time datetime="2020-09-22">Sep 22</time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div class="relative pb-8">
|
||||
<span class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200"
|
||||
aria-hidden="true"></span>
|
||||
<div class="relative flex space-x-3">
|
||||
<div>
|
||||
<span
|
||||
class="h-8 w-8 rounded-full bg-green-500 flex items-center justify-center ring-8 ring-white">
|
||||
<!-- Heroicon name: solid/check -->
|
||||
<svg class="w-5 h-5 text-white" xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd"
|
||||
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
||||
clip-rule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4">
|
||||
<div>
|
||||
<p class="text-sm text-gray-500">Completed phone screening with <a href="#"
|
||||
class="font-medium text-gray-900">Martha Gardner</a></p>
|
||||
</div>
|
||||
<div class="text-right text-sm whitespace-nowrap text-gray-500">
|
||||
<time datetime="2020-09-28">Sep 28</time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div class="relative pb-8">
|
||||
<span class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200"
|
||||
aria-hidden="true"></span>
|
||||
<div class="relative flex space-x-3">
|
||||
<div>
|
||||
<span
|
||||
class="h-8 w-8 rounded-full bg-blue-500 flex items-center justify-center ring-8 ring-white">
|
||||
<!-- Heroicon name: solid/thumb-up -->
|
||||
<svg class="w-5 h-5 text-white" xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path
|
||||
d="M2 10.5a1.5 1.5 0 113 0v6a1.5 1.5 0 01-3 0v-6zM6 10.333v5.43a2 2 0 001.106 1.79l.05.025A4 4 0 008.943 18h5.416a2 2 0 001.962-1.608l1.2-6A2 2 0 0015.56 8H12V4a2 2 0 00-2-2 1 1 0 00-1 1v.667a4 4 0 01-.8 2.4L6.8 7.933a4 4 0 00-.8 2.4z" />
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4">
|
||||
<div>
|
||||
<p class="text-sm text-gray-500">Advanced to interview by <a href="#"
|
||||
class="font-medium text-gray-900">Bethany Blake</a></p>
|
||||
</div>
|
||||
<div class="text-right text-sm whitespace-nowrap text-gray-500">
|
||||
<time datetime="2020-09-30">Sep 30</time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div class="relative pb-8">
|
||||
<div class="relative flex space-x-3">
|
||||
<div>
|
||||
<span
|
||||
class="h-8 w-8 rounded-full bg-green-500 flex items-center justify-center ring-8 ring-white">
|
||||
<!-- Heroicon name: solid/check -->
|
||||
<svg class="w-5 h-5 text-white" xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd"
|
||||
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
||||
clip-rule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4">
|
||||
<div>
|
||||
<p class="text-sm text-gray-500">Completed interview with <a href="#"
|
||||
class="font-medium text-gray-900">Katherine Snyder</a></p>
|
||||
</div>
|
||||
<div class="text-right text-sm whitespace-nowrap text-gray-500">
|
||||
<time datetime="2020-10-04">Oct 4</time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="mt-6 flex flex-col justify-stretch">
|
||||
<button type="button"
|
||||
class="inline-flex items-center justify-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">Advance
|
||||
to offer</button>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
{{end}}
|
||||
159
themes/default/layouts/beneficiaries/list.html
Normal file
159
themes/default/layouts/beneficiaries/list.html
Normal file
@@ -0,0 +1,159 @@
|
||||
{{define "content"}}
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
|
||||
<h1 class="text-2xl font-semibold text-gray-900">Bénéficiaires</h1>
|
||||
|
||||
<div class="sm:flex sm:items-center">
|
||||
<div class="sm:flex-auto">
|
||||
<p class="mt-2 text-sm text-gray-700"></p>
|
||||
</div>
|
||||
<div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
|
||||
<a href="/app/beneficiaries/create">
|
||||
<button type="button"
|
||||
class="inline-flex items-center justify-center rounded-2xl border border-transparent bg-co-blue px-4 py-2 text-sm font-medium text-white shadow-sm focus:outline-none focus:ring-2 focus:ring-ci-blue focus:ring-offset-2 sm:w-auto">
|
||||
{{$.IconSet.Icon "hero:outline/plus-circle" "h-5 w-5 mr-3"}}
|
||||
Ajouter
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8" x-data="{
|
||||
state: {{.ViewState.JSONWithLimits 0 10}},
|
||||
current: 0,
|
||||
nb_pages() {
|
||||
let nbEl = this.state.count
|
||||
return Math.ceil(nbEl/10)
|
||||
},
|
||||
async paginate(page) {
|
||||
let start = (page-1)*10
|
||||
if(start < 0|| start > this.state.count) {
|
||||
return
|
||||
}
|
||||
let resp = await fetch('/api/cache/' + this.state.cache_id + '?limits.min=' + start + '&limits.max=' + (start+10))
|
||||
let data = await resp.json()
|
||||
this.state.beneficiaries = data
|
||||
this.current=page-1
|
||||
}
|
||||
}">
|
||||
<div class="mt-8 flex flex-col">
|
||||
<div class="-my-2 -mx-4 overflow-x-auto sm:-mx-6 lg:-mx-8">
|
||||
<div class="inline-block min-w-full py-2 align-middle md:px-6 lg:px-8">
|
||||
<div class="overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg">
|
||||
<table class="min-w-full divide-y divide-gray-300">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th scope="col"
|
||||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
||||
Nom
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||
Téléphone
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||
Adresse
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||
Labels
|
||||
</th>
|
||||
<th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6">
|
||||
<span class="sr-only">Modifier</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-200 bg-white">
|
||||
<template x-for="beneficiary in state.beneficiaries">
|
||||
<tr>
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||
<div class="flex items-center">
|
||||
<div class="h-10 w-10 flex-shrink-0">
|
||||
<img class="h-10 w-10 rounded-co"
|
||||
:src="'/app/beneficiaries/' + beneficiary.id + '/picture'" alt="">
|
||||
</div>
|
||||
<div class="ml-4">
|
||||
<div class="font-medium text-gray-900"><span
|
||||
x-text="beneficiary.data.first_name"></span> <span
|
||||
x-text="beneficiary.data.last_name"></span></div>
|
||||
<div class="text-gray-500" x-text="beneficiary.data.email"></div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
|
||||
<div class="text-gray-900" x-text="beneficiary.data.phone_number"></div>
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500"
|
||||
x-text="beneficiary.data.address ? beneficiary.data.address.properties.label : ''">
|
||||
</td>
|
||||
<td class="whitespace-nowrap px-3 py-4 text-sm text-gray-500">
|
||||
<template x-for="tag in beneficiary.data.tags">
|
||||
<span
|
||||
class="inline-flex rounded-full bg-green-100 px-2 text-xs font-semibold leading-5 text-green-800"
|
||||
x-text="tag"></span>
|
||||
</template>
|
||||
</td>
|
||||
<td
|
||||
class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6">
|
||||
<a :href="'/app/beneficiaries/' + beneficiary.id"
|
||||
class="text-co-blue hover:text-co-blue">Voir<span class="sr-only">, <span
|
||||
x-text="beneficiary.data.first_name"></span> <span
|
||||
x-text="beneficiary.data.last_name"></span></a>
|
||||
</td>
|
||||
</tr>
|
||||
</template>
|
||||
|
||||
<!-- More people... -->
|
||||
</tbody>
|
||||
</table>
|
||||
<div class="bg-white px-4 py-3 flex items-center justify-between border-t border-gray-200 sm:px-6">
|
||||
<div class="flex-1 flex justify-between sm:hidden">
|
||||
<a href="#" class="relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50"
|
||||
@click="paginate(current)"> Previous </a>
|
||||
<a href="#" class="ml-3 relative inline-flex items-center px-4 py-2 border border-gray-300 text-sm font-medium rounded-md text-gray-700 bg-white hover:bg-gray-50"
|
||||
@click="paginate(current+2)"> Next </a>
|
||||
</div>
|
||||
<div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
|
||||
<div>
|
||||
<p class="text-sm text-gray-700">
|
||||
Résultats
|
||||
<span class="font-medium" x-text="Math.min((current * 10)+1, state.count)"></span>
|
||||
à
|
||||
<span class="font-medium" x-text="Math.min((current * 10)+10, state.count)"></span>
|
||||
sur
|
||||
<span class="font-medium" x-text="state.count"></span>
|
||||
</p>
|
||||
</div>
|
||||
<div>
|
||||
<nav class="relative z-0 inline-flex rounded-md shadow-sm -space-x-px" aria-label="Pagination">
|
||||
<a href="#" class="relative inline-flex items-center px-2 py-2 rounded-l-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50"
|
||||
@click="paginate(current)">
|
||||
<span class="sr-only">Previous</span>
|
||||
<!-- Heroicon name: solid/chevron-left -->
|
||||
<svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</a>
|
||||
<template x-for="i in nb_pages">
|
||||
<a href="#" @click="paginate(i)"
|
||||
class="relative inline-flex items-center px-4 py-2 border text-sm font-medium"
|
||||
:class="i == current+1 ? 'z-10 bg-indigo-50 border-co-blue text-co-blue' : 'bg-white border-gray-300 text-gray-500 hover:bg-gray-50'"
|
||||
x-text="i"></a>
|
||||
</template>
|
||||
<!-- Current: "z-10 bg-indigo-50 border-indigo-500 text-indigo-600", Default: "bg-white border-gray-300 text-gray-500 hover:bg-gray-50" -->
|
||||
<a href="#" class="relative inline-flex items-center px-2 py-2 rounded-r-md border border-gray-300 bg-white text-sm font-medium text-gray-500 hover:bg-gray-50"
|
||||
@click="paginate(current+2)">
|
||||
<span class="sr-only">Next</span>
|
||||
<!-- Heroicon name: solid/chevron-right -->
|
||||
<svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</a>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
173
themes/default/layouts/beneficiaries/update.html
Normal file
173
themes/default/layouts/beneficiaries/update.html
Normal file
@@ -0,0 +1,173 @@
|
||||
{{define "content"}}
|
||||
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
|
||||
<h1 class="text-2xl font-semibold text-gray-900">Modifier un bénéficiaire</h1>
|
||||
</div>
|
||||
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-8"
|
||||
x-data="{
|
||||
fields: {
|
||||
first_name: '{{ .ViewState.Data.first_name }}',
|
||||
last_name: '{{ .ViewState.Data.last_name }}',
|
||||
email: '{{ .ViewState.Data.email }}',
|
||||
phone_number: '{{ .ViewState.Data.phone_number }}',
|
||||
birthdate: {{if .ViewState.Data.birthdate}}'{{ (timeFrom .ViewState.Data.birthdate).Format "2006-01-02" }}'{{else}}null{{end}},
|
||||
gender: {{.ViewState.Data.gender}}
|
||||
},
|
||||
rules: {
|
||||
first_name: ['required'],
|
||||
last_name: ['required'],
|
||||
email: ['required', 'email'],
|
||||
phone_number: ['required', 'regexMatch:^((\\+)33|0)[1-9](\\d{2}){4}$'],
|
||||
birthdate: ['optional'],
|
||||
},
|
||||
formValidation: {
|
||||
valid: false,
|
||||
fields: {
|
||||
first_name: {valid: null},
|
||||
last_name: {valid: null},
|
||||
email: {valid: null},
|
||||
phone_number: {valid: null},
|
||||
birthdate: {valid: null},
|
||||
}
|
||||
},
|
||||
isFormValid: true,
|
||||
validate() {
|
||||
this.formValidation = Iodine.assert(this.fields, this.rules)
|
||||
},
|
||||
validateField(field) {
|
||||
this.formValidation.fields[field] = Iodine.assert(this.fields[field], this.rules[field])
|
||||
},
|
||||
submit(event) {
|
||||
this.validate()
|
||||
if(!this.formValidation.valid) {
|
||||
this.isFormValid = false
|
||||
event.preventDefault()
|
||||
}
|
||||
return this.formValidation.valid
|
||||
}
|
||||
}">
|
||||
<form class="space-y-6" method="POST" @submit="submit">
|
||||
<div class="bg-white shadow px-4 py-5 sm:rounded-lg sm:p-6">
|
||||
<div class="md:grid md:grid-cols-3 md:gap-6">
|
||||
<div class="md:col-span-1">
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900">Informations obligatoires</h3>
|
||||
<p class="mt-1 text-sm text-gray-500">Informations personnelles sur le bénéficiaire obligatoires
|
||||
pour créer son profil dans PARCOURSMOB</p>
|
||||
</div>
|
||||
<div class="mt-5 md:mt-0 md:col-span-2">
|
||||
<div class="grid grid-cols-6 gap-6">
|
||||
<div class="col-span-6 sm:col-span-3">
|
||||
<label for="first_name" class="block text-sm font-medium text-gray-700">Prénom</label>
|
||||
<input type="text" name="first_name" id="first_name" autocomplete="given-name"
|
||||
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm rounded-2xl"
|
||||
x-model="fields.first_name" @blur="validateField('first_name')"
|
||||
:class="formValidation.fields.first_name.valid == false ? 'border-co-red border-2' : 'border-gray-300'">
|
||||
</div>
|
||||
|
||||
<div class="col-span-6 sm:col-span-3">
|
||||
<label for="last_name" class="block text-sm font-medium text-gray-700">Nom</label>
|
||||
<input type="text" name="last_name" id="last_name" autocomplete="family-name"
|
||||
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm rounded-2xl"
|
||||
x-model="fields.last_name" @blur="validateField('last_name')"
|
||||
:class="formValidation.fields.last_name.valid == false ? 'border-co-red border-2' : 'border-gray-300'">
|
||||
</div>
|
||||
|
||||
<div class="col-span-6 sm:col-span-4">
|
||||
<label for="email" class="block text-sm font-medium text-gray-700">Email</label>
|
||||
<input type="text" name="email" id="email" autocomplete="email"
|
||||
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm rounded-2xl"
|
||||
x-model="fields.email" @blur="validateField('email')"
|
||||
:class="formValidation.fields.email.valid == false ? 'border-co-red border-2' : 'border-gray-300'">
|
||||
</div>
|
||||
|
||||
<div class="col-span-6 sm:col-span-4">
|
||||
<label for="phone_number" class="block text-sm font-medium text-gray-700">Numéro de
|
||||
téléphone</label>
|
||||
<input type="text" name="phone_number" id="phone_number" autocomplete="phone" placeholder="+33612345678"
|
||||
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm rounded-2xl"
|
||||
x-model="fields.phone_number" @blur="validateField('phone_number')"
|
||||
:class="formValidation.fields.phone_number.valid == false ? 'border-co-red border-2' : 'border-gray-300'">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="bg-white shadow px-4 py-5 sm:rounded-lg sm:p-6">
|
||||
<div class="md:grid md:grid-cols-3 md:gap-6">
|
||||
<div class="md:col-span-1">
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900">Informations optionnelles</h3>
|
||||
<p class="mt-1 text-sm text-gray-500">Autres informations de profil optionnelles</p>
|
||||
</div>
|
||||
<div class="mt-5 space-y-6 md:mt-0 md:col-span-2">
|
||||
<div class="grid grid-cols-6 gap-6">
|
||||
|
||||
<div class="col-span-6 sm:col-span-3">
|
||||
<label for="birthdate" class="block text-sm font-medium text-gray-700">Date de
|
||||
naissance</label>
|
||||
<input type="date" name="birthdate" id="birthdate" autocomplete="birthdate" placeholder="JJ/MM/AAAA"
|
||||
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm rounded-2xl"
|
||||
x-model="fields.birthdate" @blur="validateField('birthdate')"
|
||||
:class="formValidation.fields.birthdate.valid == false ? 'border-co-red border-2' : 'border-gray-300'">
|
||||
</div>
|
||||
|
||||
<div class="col-span-6 sm:col-span-3">
|
||||
<label for="gender" class="block text-sm font-medium text-gray-700">Genre</label>
|
||||
<div class="sm:mt-0 sm:col-span-2">
|
||||
<select id="gender" name="gender" autocomplete="gender" x-model="gender"
|
||||
class="max-w-lg mt-1 block focus:ring-co-blue focus:border-co-blue w-full shadow-sm sm:max-w-xs sm:text-sm border-gray-300 rounded-2xl">
|
||||
<option value="0">Inconnu</option>
|
||||
<option value="1" :selected="fields.gender == '1'">Masculin</option>
|
||||
<option value="2" :selected="fields.gender == '2'">Féminin</option>
|
||||
<option value="9" :selected="fields.gender == '9'">Sans objet</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- <div class="col-span-3 sm:col-span-3">
|
||||
<label class="block text-sm font-medium text-gray-700"> Photo </label>
|
||||
<div class="mt-1 flex items-center space-x-5">
|
||||
<span class="inline-block h-12 w-12 rounded-co overflow-hidden bg-gray-100">
|
||||
{{.IconSet.Icon "img:profile-picture-placeholder" "h-full w-full"}}
|
||||
</span>
|
||||
<button type="button"
|
||||
class="bg-white py-2 px-3 border border-gray-300 rounded-2xl shadow-sm text-sm leading-4 font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">
|
||||
Charger la photo
|
||||
</button>
|
||||
</div>
|
||||
</div> -->
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white shadow px-4 py-5 sm:rounded-lg sm:p-6">
|
||||
<div class="md:grid md:grid-cols-3 md:gap-6">
|
||||
<div class="md:col-span-1">
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900">Paramètres</h3>
|
||||
<p class="mt-1 text-sm text-gray-500">Paramètres liés au bénéficiaire, utiles pour exploiter les fonctionnalités de PARCOURSMOB</p>
|
||||
</div>
|
||||
<div class="mt-5 space-y-6 md:mt-0 md:col-span-2">
|
||||
|
||||
{{ $fieldName := "address" }}
|
||||
{{ template "address_autocomplete" (dict "FieldName" $fieldName "Address" .ViewState.Data.address) }}
|
||||
<!-- will dolater : tags, groups, ... -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<p x-show="! isFormValid" class="px-4 py-2 text-sm text-co-red">Certains champs de sont pas valides.</p>
|
||||
<a href="/app/beneficiaries/{{.ViewState.ID}}">
|
||||
<button type="button"
|
||||
class="bg-white py-2 px-4 border border-gray-300 rounded-2xl shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">Annuler</button>
|
||||
</a>
|
||||
<button type="submit"
|
||||
class="ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-2xl text-white bg-co-blue hover:bg-co-blue focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">Modifier</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
||||
@@ -0,0 +1,31 @@
|
||||
{{define "beneficiaries_widget"}}
|
||||
<div class="col-span-1 bg-white rounded-2xl shadow divide-y divide-gray-200">
|
||||
<div class="-ml-4 -mt-2 px-4 py-2 flex items-center justify-between flex-wrap sm:flex-nowrap">
|
||||
<div class="ml-4 mt-2">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">Bénéficiaires</h3>
|
||||
<h2 class="text-sm leading-6 font-medium text-gray-600">Derniers ajoutés</h2>
|
||||
</div>
|
||||
<!-- <div class="ml-4 mt-2 flex-shrink-0">
|
||||
<button type="button" class="relative inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-co-blue hover:bg-co-blue focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">Voir</button>
|
||||
</div> -->
|
||||
</div>
|
||||
<ul role="list" class="divide-y divide-gray-200">
|
||||
{{range .latest}}
|
||||
<li class="py-2 px-4 flex">
|
||||
<a href="/app/beneficiaries/{{.ID}}" class="flex w-full">
|
||||
<img class="h-6 w-6 rounded-co" src="/app/beneficiaries/{{.ID}}/picture" alt="">
|
||||
<div class="ml-3">
|
||||
<p class="text-sm font-medium text-gray-900">{{.Data.first_name}} {{.Data.last_name}}</p>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
|
||||
<a href="/app/beneficiaries/">
|
||||
<button class="w-full p-2 text-center bg-co-blue text-white rounded-b-2xl text-sm">
|
||||
Gérer les bénéficiaires
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
{{end}}
|
||||
15
themes/default/layouts/dashboard/dashboard.html
Normal file
15
themes/default/layouts/dashboard/dashboard.html
Normal file
@@ -0,0 +1,15 @@
|
||||
{{define "content"}}
|
||||
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
|
||||
<h1 class="text-2xl font-semibold text-gray-900">Tableau de bord</h1>
|
||||
</div>
|
||||
<div class="max-w-7xl mx-auto py-8 px-4 sm:px-6 md:px-8">
|
||||
<div class="py-4 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
|
||||
|
||||
{{template "beneficiaries_widget" .ViewState.beneficiaries}}
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
177
themes/default/layouts/layout.html
Normal file
177
themes/default/layouts/layout.html
Normal file
@@ -0,0 +1,177 @@
|
||||
{{define "main"}}
|
||||
<!DOCTYPE html>
|
||||
<html class="h-full bg-gray-100">
|
||||
|
||||
<head>
|
||||
<title>PARCOURSMOB</title>
|
||||
<link rel="stylesheet" href="/public/css/main.css" />
|
||||
<!-- <script defer type="text/javascript" src="/public/js/main.js" defer></script> -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/@kingshott/iodine@8.1.0/dist/iodine.min.umd.js" defer></script>
|
||||
<script defer src="https://unpkg.com/alpinejs@3.x.x/dist/cdn.min.js" defer></script>
|
||||
</head>
|
||||
|
||||
<body class="h-full" x-data="{ offCanvasMenu: false }">
|
||||
<div class="relative z-40 md:hidden" role="dialog" aria-modal="true">
|
||||
|
||||
<div class="fixed inset-0 bg-gray-600 bg-opacity-75" x-show="offCanvasMenu"
|
||||
x-transition:enter="transition-opacity ease-linear duration-300" x-transition:enter-start="opacity-0"
|
||||
x-transition:enter-end="opacity-100" x-transition:leave="transition-opacity ease-linear duration-300"
|
||||
x-transition:leave-start="opacity-100" x-transition:leave-end="opacity-0"></div>
|
||||
|
||||
<div class="fixed inset-0 flex z-40" x-show="offCanvasMenu"
|
||||
x-transition:enter="transition ease-in-out duration-300 transform" x-transition:enter-start="-translate-x-full"
|
||||
x-transition:enter-end="translate-x-0" x-transition:leave="transition ease-in-out duration-300 transform"
|
||||
x-transition:leave-start="translate-x-0" x-transition:leave-end="-translate-x-full">
|
||||
<div class="relative flex-1 flex flex-col max-w-xs w-full pt-5 pb-4 bg-co-blue">
|
||||
<div class="absolute top-0 right-0 -mr-12 pt-2" @click="offCanvasMenu = false">
|
||||
<button type="button"
|
||||
class="ml-1 flex items-center justify-center h-10 w-10 rounded-full focus:outline-none focus:ring-2 focus:ring-inset focus:ring-white">
|
||||
<span class="sr-only">Close sidebar</span>
|
||||
{{ .IconSet.Icon "hero:outline/x" "h-6 w-6" }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="flex-shrink-0 flex items-center px-4">
|
||||
<img class="h-8 w-auto" src="/public/images/parcoursmob_logo_whitered.svg" alt="PARCOURSMOB">
|
||||
</div>
|
||||
<div class="mt-5 flex-1 h-0 overflow-y-auto">
|
||||
|
||||
{{ template "mainmenu" . }}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex-shrink-0 w-14" aria-hidden="true">
|
||||
<!-- Dummy element to force sidebar to shrink to fit close icon -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Static sidebar for desktop -->
|
||||
<div class="hidden md:flex md:w-64 md:flex-col md:fixed md:inset-y-0">
|
||||
<!-- Sidebar component, swap this element with another sidebar if you like -->
|
||||
<div class="flex flex-col flex-grow pt-5 bg-co-blue overflow-y-auto">
|
||||
<div class="flex items-center flex-shrink-0 px-4">
|
||||
<img class="h-8 w-auto" src="/public/images/parcoursmob_logo_whitered.svg" alt="PARCOURSMOB">
|
||||
</div>
|
||||
<div class="mt-5 flex-1 flex flex-col">
|
||||
{{ template "mainmenu" . }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="md:pl-64 flex flex-col flex-1">
|
||||
<div class="sticky top-0 z-10 flex-shrink-0 flex h-16 bg-white shadow">
|
||||
<button @click="offCanvasMenu = true" type="button"
|
||||
class="px-4 border-r border-gray-200 text-gray-500 focus:outline-none focus:ring-2 focus:ring-inset focus:ring-co-blue md:hidden">
|
||||
<span class="sr-only">Open sidebar</span>
|
||||
<!-- Heroicon name: outline/menu-alt-2 -->
|
||||
<svg class="h-6 w-6" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2"
|
||||
stroke="currentColor" aria-hidden="true">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M4 6h16M4 12h16M4 18h7" />
|
||||
</svg>
|
||||
</button>
|
||||
<div class="flex-1 px-4 flex justify-between">
|
||||
<div class="flex-1 flex">
|
||||
<form class="w-full flex md:ml-0" action="/app/beneficiaries/" method="GET">
|
||||
<label for="search-field" class="sr-only">Search</label>
|
||||
<div class="relative w-full text-gray-400 focus-within:text-gray-600">
|
||||
<div class="absolute inset-y-0 left-0 flex items-center pointer-events-none">
|
||||
<!-- Heroicon name: solid/search -->
|
||||
{{$.IconSet.Icon "hero:solid/search" "h5 w-5"}}
|
||||
</div>
|
||||
<input id="search-field"
|
||||
class="block w-full h-full pl-8 pr-3 py-2 border-transparent text-gray-900 placeholder-gray-500 focus:outline-none focus:placeholder-gray-400 focus:ring-0 focus:border-transparent sm:text-sm"
|
||||
placeholder="Chercher un bénéficiaire" type="search" name="search">
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
<div class="ml-4 flex items-center md:ml-6">
|
||||
|
||||
|
||||
<a href="/app/administration/">
|
||||
{{if and .AdministrationState.Display .AdministrationState.Active}}
|
||||
<button
|
||||
class="max-w-xs bg-co-blue px-4 py-2 text-white flex items-center text-sm rounded-2xl focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">
|
||||
{{.IconSet.Icon "hero:outline/cog" "h-6 w-6"}} Administration
|
||||
</button>
|
||||
{{else if and .AdministrationState.Display}}
|
||||
<button
|
||||
class="max-w-xs bg-white hover:bg-gray-50 border-gray-300 border px-4 py-2 text-gray-700 flex items-center text-sm rounded-2xl focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">
|
||||
{{.IconSet.Icon "hero:outline/cog" "h-6 w-6"}} Administration
|
||||
</button>
|
||||
{{end}}
|
||||
</a>
|
||||
<div class="ml-3 relative" x-data="{ groupMenuOpen: false }">
|
||||
<div>
|
||||
<button @click="groupMenuOpen = ! groupMenuOpen" type="button"
|
||||
class="max-w-xs bg-white hover:bg-gray-50 border-gray-300 border px-4 py-2 text-gray-700 flex items-center text-sm rounded-2xl focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">
|
||||
{{.Group.Data.name}}
|
||||
</button>
|
||||
</div>
|
||||
<div
|
||||
class="origin-top-right absolute right-0 mt-2 w-48 rounded-md shadow-lg py-1 bg-white ring-1 ring-black ring-opacity-5 focus:outline-none"
|
||||
role="menu" aria-orientation="vertical" aria-labelledby="group-menu-button" tabindex="-1"
|
||||
x-show="groupMenuOpen" x-transition:enter="transition ease-out duration-100"
|
||||
x-transition:enter-start="transform opacity-0 scale-95"
|
||||
x-transition:enter-end="transform opacity-100 scale-100"
|
||||
x-transition:leave="transition ease-in duration-75"
|
||||
x-transition:leave-start="transform opacity-100 scale-100"
|
||||
x-transition:leave-end="transform opacity-0 scale-95">
|
||||
<!-- Active: "bg-gray-100", Not Active: "" -->
|
||||
<a href="/app/group/settings" class="block px-4 py-2 text-sm text-gray-700" role="menuitem" tabindex="-1"
|
||||
id="user-menu-item-1">Paramètres</a>
|
||||
|
||||
<a href="/auth/groups/switch" class="block px-4 py-2 text-sm text-gray-700" role="menuitem" tabindex="-1"
|
||||
id="user-menu-item-2">Changer d'organisation</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Profile dropdown -->
|
||||
<div class="ml-3 relative" x-data="{ profileMenuOpen: false }">
|
||||
<div>
|
||||
<button @click="profileMenuOpen = ! profileMenuOpen" type="button"
|
||||
class="max-w-xs bg-white flex items-center text-sm rounded-co focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue"
|
||||
id="user-menu-button" aria-expanded="false" aria-haspopup="true">
|
||||
<span class="sr-only">Open user menu</span>
|
||||
<img class="h-8 w-8 rounded-co"
|
||||
src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
|
||||
alt="Menu utilisateur">
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div
|
||||
class="origin-top-right absolute right-0 mt-2 w-48 rounded-md shadow-lg py-1 bg-white ring-1 ring-black ring-opacity-5 focus:outline-none"
|
||||
role="menu" aria-orientation="vertical" aria-labelledby="user-menu-button" tabindex="-1"
|
||||
x-show="profileMenuOpen" x-transition:enter="transition ease-out duration-100"
|
||||
x-transition:enter-start="transform opacity-0 scale-95"
|
||||
x-transition:enter-end="transform opacity-100 scale-100"
|
||||
x-transition:leave="transition ease-in duration-75"
|
||||
x-transition:leave-start="transform opacity-100 scale-100"
|
||||
x-transition:leave-end="transform opacity-0 scale-95">
|
||||
<!-- Active: "bg-gray-100", Not Active: "" -->
|
||||
<a href="/app/profile" class="block px-4 py-2 text-sm text-gray-700" role="menuitem" tabindex="-1"
|
||||
id="user-menu-item-0">Votre profil</a>
|
||||
|
||||
<a href="/app/settings/" class="block px-4 py-2 text-sm text-gray-700" role="menuitem" tabindex="-1"
|
||||
id="user-menu-item-1">Paramètres</a>
|
||||
|
||||
<a href="/app/disconnect" class="block px-4 py-2 text-sm text-gray-700" role="menuitem" tabindex="-1"
|
||||
id="user-menu-item-2">Se déconnecter</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<main>
|
||||
<div class="py-6">
|
||||
{{ template "content" . }}
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
{{end}}
|
||||
@@ -0,0 +1,72 @@
|
||||
{{define "bookings_list"}}
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
|
||||
<div class="mt-8 flex flex-col">
|
||||
<div class="-my-2 -mx-4 overflow-x-auto sm:-mx-6 lg:-mx-8">
|
||||
<div class="inline-block min-w-full py-2 align-middle md:px-6 lg:px-8">
|
||||
<div class="overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg">
|
||||
<table class="min-w-full divide-y divide-gray-300">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th scope="col"
|
||||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
||||
Statut
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||
Type
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||
Immatriculation
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||
Beneficiaire
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||
Prescripteur
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||
Gestionnaire
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||
Dates
|
||||
</th>
|
||||
<th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6">
|
||||
<span class="sr-only">Actions</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-200 bg-white">
|
||||
<tr>
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||
<div class="text-gray-900" >aa</div>
|
||||
</td>
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||
<div class="text-gray-900" >aa</div>
|
||||
</td>
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||
<div class="text-gray-900" >aa</div>
|
||||
</td>
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||
<div class="text-gray-900" >aa</div>
|
||||
</td>
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||
<div class="text-gray-900" >aa</div>
|
||||
</td>
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||
<div class="text-gray-900" >aa</div>
|
||||
</td>
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||
<div class="text-gray-900" >aa</div>
|
||||
</td>
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||
<a :href="'/app/beneficiaries/' + beneficiary.id"
|
||||
class="text-co-blue hover:text-co-blue">Voir</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
@@ -0,0 +1,63 @@
|
||||
{{define "vehicle_type_select"}}
|
||||
<div x-data="{
|
||||
selectOpen: false,
|
||||
vehicle_type: 'car',
|
||||
vehicle_label: 'Voiture',
|
||||
selectType(type, label) {
|
||||
this.vehicle_type = type,
|
||||
this.vehicle_label = label
|
||||
this.selectOpen = false
|
||||
}
|
||||
}">
|
||||
<input type="hidden" name="vehicle_type" x-model="vehicle_type">
|
||||
<label id="listbox-label" class="block text-sm font-medium text-gray-700"> Type de véhicule </label>
|
||||
<div class="mt-1 relative">
|
||||
<button @click="selectOpen = ! selectOpen" type="button"
|
||||
class="relative w-full bg-white border border-gray-300 rounded-2xl shadow-sm pl-3 pr-10 py-2 text-left cursor-default focus:outline-none focus:ring-1 focus:ring-co-blue focus:border-co-blue sm:text-sm"
|
||||
aria-haspopup="listbox" aria-expanded="true" aria-labelledby="listbox-label">
|
||||
<span class="block truncate" x-text="vehicle_label"></span>
|
||||
<span class="absolute inset-y-0 right-0 flex items-center pr-2 pointer-events-none">
|
||||
{{$.IconSet.Icon "hero:solid/selector" "h-5 w-5 text-gray-400"}}
|
||||
</span>
|
||||
</button>
|
||||
|
||||
<ul class="absolute z-10 mt-1 w-full bg-white shadow-lg max-h-60 rounded-xl py-1 text-base ring-1 ring-black ring-opacity-5 overflow-auto focus:outline-none sm:text-sm"
|
||||
tabindex="-1" role="listbox" aria-labelledby="listbox-label" aria-activedescendant="listbox-option-3"
|
||||
x-show="selectOpen" x-transition:leave="transition ease-in duration-100"
|
||||
x-transition:leave-start="transform opacity-100" x-transition:leave-end="transform opacity-0">
|
||||
|
||||
<li class="text-gray-900 cursor-default select-none relative py-2 pl-8 pr-4 hover:bg-co-blue hover:text-white" id="listbox-option-0"
|
||||
role="option" @click="selectType('car', 'Voiture')">
|
||||
<!-- Selected: "font-semibold", Not Selected: "font-normal" -->
|
||||
<span class="font-normal block truncate "> Voiture </span>
|
||||
<span x-show="vehicle_type == 'car'"
|
||||
class="text-co-blue absolute inset-y-0 left-0 flex items-center pl-1.5">
|
||||
<svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"
|
||||
aria-hidden="true">
|
||||
<path fill-rule="evenodd"
|
||||
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
||||
clip-rule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
</li>
|
||||
<li class="text-gray-900 cursor-default select-none relative py-2 pl-8 pr-4 hover:bg-co-blue hover:text-white" id="listbox-option-0"
|
||||
role="option" @click="selectType('electric_bike', 'Vélo électrique')">
|
||||
<!-- Selected: "font-semibold", Not Selected: "font-normal" -->
|
||||
<span class="font-normal block truncate "> Vélo électrique </span>
|
||||
<span x-show="vehicle_type == 'electric_bike'"
|
||||
class="text-co-blue hover:text-inherit absolute inset-y-0 left-0 flex items-center pl-1.5">
|
||||
<svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"
|
||||
aria-hidden="true">
|
||||
<path fill-rule="evenodd"
|
||||
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
||||
clip-rule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
</li>
|
||||
|
||||
<!-- More items... -->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{end}}
|
||||
@@ -0,0 +1,54 @@
|
||||
{{define "vehicles_list"}}
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
|
||||
<div class="mt-8 flex flex-col">
|
||||
<div class="-my-2 -mx-4 overflow-x-auto sm:-mx-6 lg:-mx-8">
|
||||
<div class="inline-block min-w-full py-2 align-middle md:px-6 lg:px-8">
|
||||
<div class="overflow-hidden shadow ring-1 ring-black ring-opacity-5 md:rounded-lg">
|
||||
<table class="min-w-full divide-y divide-gray-300">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th scope="col"
|
||||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
||||
Immatriculation
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||
Gestionnaire
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||
Modèle
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||
Gestionnaire
|
||||
</th>
|
||||
<th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6">
|
||||
<span class="sr-only">Actions</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-200 bg-white">
|
||||
<tr>
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||
<div class="text-gray-900" >aa</div>
|
||||
</td>
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||
<div class="text-gray-900" >aa</div>
|
||||
</td>
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||
<div class="text-gray-900" >aa</div>
|
||||
</td>
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||
<div class="text-gray-900" >aa</div>
|
||||
</td>
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||
<a :href="'/app/beneficiaries/' + beneficiary.id"
|
||||
class="text-co-blue hover:text-co-blue">Voir</a>
|
||||
</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
106
themes/default/layouts/vehicles_management/fleet-add.html
Normal file
106
themes/default/layouts/vehicles_management/fleet-add.html
Normal file
@@ -0,0 +1,106 @@
|
||||
{{define "content"}}
|
||||
|
||||
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
|
||||
<h1 class="text-2xl font-semibold text-gray-900">Ajouter un véhicule</h1>
|
||||
</div>
|
||||
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-8" x-data="{
|
||||
fields: {
|
||||
licence_plate: null,
|
||||
name: null,
|
||||
},
|
||||
rules: {
|
||||
licence_plate: ['required', 'regexMatch:^[A-Z]{1,2}-[0-9]{1,3}-[A-Z]{1,2}$'],
|
||||
name: ['required'],
|
||||
},
|
||||
formValidation: {
|
||||
valid: false,
|
||||
fields: {
|
||||
name: {valid: null},
|
||||
licence_plate: {valid: null},
|
||||
}
|
||||
},
|
||||
isFormValid: true,
|
||||
validate() {
|
||||
this.formValidation = Iodine.assert(this.fields, this.rules)
|
||||
},
|
||||
validateField(field) {
|
||||
this.formValidation.fields[field] = Iodine.assert(this.fields[field], this.rules[field])
|
||||
},
|
||||
submit(event) {
|
||||
this.validate()
|
||||
if(!this.formValidation.valid) {
|
||||
this.isFormValid = false
|
||||
event.preventDefault()
|
||||
}
|
||||
return this.formValidation.valid
|
||||
}
|
||||
}">
|
||||
<form class="space-y-6" method="POST" @submit="submit">
|
||||
<div class="bg-white shadow px-4 py-5 sm:rounded-lg sm:p-6">
|
||||
<div class="md:grid md:grid-cols-3 md:gap-6">
|
||||
<div class="md:col-span-1">
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900">Identité du véhicule</h3>
|
||||
<p class="mt-1 text-sm text-gray-500">Informations de base sur le véhicule</p>
|
||||
</div>
|
||||
<div class="mt-5 md:mt-0 md:col-span-2">
|
||||
<div class="grid grid-cols-3 md:grid-cols-6 gap-6">
|
||||
<div class="col-span-5">
|
||||
<label for="name" class="block text-sm font-medium text-gray-700">Modèle (ou nom donné au
|
||||
véhicule)</label>
|
||||
<input type="text" name="name" id="name"
|
||||
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm rounded-2xl"
|
||||
x-model="fields.name" @blur="validateField('name')"
|
||||
:class="formValidation.fields.name.valid == false ? 'border-co-red border-2' : 'border-gray-300'">
|
||||
</div>
|
||||
<div class="col-span-3">
|
||||
{{template "vehicle_type_select" .}}
|
||||
</div>
|
||||
<div class="col-span-3">
|
||||
<label for="licence_plate"
|
||||
class="block text-sm font-medium text-gray-700">Immatriculation</label>
|
||||
<input type="text" name="licence_plate" id="licence_plate" placeholder="XX-123-YY"
|
||||
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm rounded-2xl"
|
||||
x-model="fields.licence_plate"
|
||||
@blur="fields.licence_plate = fields.licence_plate.toUpperCase(); validateField('licence_plate')"
|
||||
:class="formValidation.fields.licence_plate.valid == false ? 'border-co-red border-2' : 'border-gray-300'">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white shadow px-4 py-5 sm:rounded-lg sm:p-6">
|
||||
<div class="md:grid md:grid-cols-3 md:gap-6">
|
||||
<div class="md:col-span-1">
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900">Informations pratiques</h3>
|
||||
<p class="mt-1 text-sm text-gray-500">Informations pratiques pour la réservation</p>
|
||||
</div>
|
||||
<div class="mt-5 md:mt-0 md:col-span-2">
|
||||
{{ $fieldName := "address" }}
|
||||
{{ template "address_autocomplete" dict "FieldName" $fieldName }}
|
||||
|
||||
<div class="mt-5">
|
||||
<label for="informations" class="block text-sm font-medium text-gray-700">Informations pratiques pour le bénéficiaire</label>
|
||||
<div class="mt-1">
|
||||
<textarea rows="4" name="informations" id="informations"
|
||||
class="shadow-sm focus:ring-co-blue focus:border-co-blue block w-full sm:text-sm border-gray-300 rounded-2xl"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<p x-show="! isFormValid" class="px-4 py-2 text-sm text-co-red">Certains champs de sont pas valides.</p>
|
||||
<a href="/app/vehicles-management/">
|
||||
<button type="button"
|
||||
class="bg-white py-2 px-4 border border-gray-300 rounded-2xl shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">Annuler</button>
|
||||
</a>
|
||||
<button type="submit"
|
||||
class="ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-2xl text-white bg-co-blue hover:bg-co-blue focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">Ajouter
|
||||
le véhicule</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
||||
31
themes/default/layouts/vehicles_management/overview.html
Normal file
31
themes/default/layouts/vehicles_management/overview.html
Normal file
@@ -0,0 +1,31 @@
|
||||
{{define "content"}}
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
|
||||
<h1 class="text-2xl font-semibold text-gray-900">Gestion des véhicules et réservations</h1>
|
||||
|
||||
<h2 class="text-xl font-semibold text-gray-600 pt-8">Réservations</h2>
|
||||
</div>
|
||||
|
||||
{{template "bookings_list" .}}
|
||||
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
|
||||
<h2 class="text-xl font-semibold text-gray-600 pt-8">Véhicules</h2>
|
||||
|
||||
<div class="sm:flex sm:items-center">
|
||||
<div class="sm:flex-auto">
|
||||
<p class="mt-2 text-sm text-gray-700"></p>
|
||||
</div>
|
||||
<div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
|
||||
<a href="/app/vehicles-management/fleet/add">
|
||||
<button type="button"
|
||||
class="inline-flex items-center justify-center rounded-2xl border border-transparent bg-co-blue px-4 py-2 text-sm font-medium text-white shadow-sm focus:outline-none focus:ring-2 focus:ring-ci-blue focus:ring-offset-2 sm:w-auto">
|
||||
{{$.IconSet.Icon "hero:outline/plus-circle" "h-5 w-5 mr-3"}}
|
||||
Ajouter un véhicule
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{template "vehicles_list" .}}
|
||||
|
||||
{{end}}
|
||||
Reference in New Issue
Block a user