Add dispositifs
This commit is contained in:
		
							parent
							
								
									0bb915059d
								
							
						
					
					
						commit
						8aa8fc927b
					
				
							
								
								
									
										4
									
								
								go.mod
								
								
								
								
							
							
						
						
									
										4
									
								
								go.mod
								
								
								
								
							| 
						 | 
					@ -8,7 +8,10 @@ replace git.coopgo.io/coopgo-platform/groups-management => ../../coopgo-platform
 | 
				
			||||||
 | 
					
 | 
				
			||||||
replace git.coopgo.io/coopgo-platform/fleets => ../../coopgo-platform/fleets/
 | 
					replace git.coopgo.io/coopgo-platform/fleets => ../../coopgo-platform/fleets/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					replace git.coopgo.io/coopgo-platform/agenda => ../../coopgo-platform/agenda/
 | 
				
			||||||
 | 
					
 | 
				
			||||||
require (
 | 
					require (
 | 
				
			||||||
 | 
						git.coopgo.io/coopgo-platform/agenda v0.0.0-00010101000000-000000000000
 | 
				
			||||||
	git.coopgo.io/coopgo-platform/fleets v0.0.0-00010101000000-000000000000
 | 
						git.coopgo.io/coopgo-platform/fleets v0.0.0-00010101000000-000000000000
 | 
				
			||||||
	git.coopgo.io/coopgo-platform/groups-management v0.0.0-00010101000000-000000000000
 | 
						git.coopgo.io/coopgo-platform/groups-management v0.0.0-00010101000000-000000000000
 | 
				
			||||||
	git.coopgo.io/coopgo-platform/mobility-accounts v0.0.0-00010101000000-000000000000
 | 
						git.coopgo.io/coopgo-platform/mobility-accounts v0.0.0-00010101000000-000000000000
 | 
				
			||||||
| 
						 | 
					@ -71,6 +74,7 @@ require (
 | 
				
			||||||
	google.golang.org/appengine v1.6.7 // indirect
 | 
						google.golang.org/appengine v1.6.7 // indirect
 | 
				
			||||||
	google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd // indirect
 | 
						google.golang.org/genproto v0.0.0-20220519153652-3a47de7e79bd // indirect
 | 
				
			||||||
	gopkg.in/ini.v1 v1.66.4 // indirect
 | 
						gopkg.in/ini.v1 v1.66.4 // indirect
 | 
				
			||||||
 | 
						gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 // indirect
 | 
				
			||||||
	gopkg.in/square/go-jose.v2 v2.5.2-0.20210529014059-a5c7eec3c614 // indirect
 | 
						gopkg.in/square/go-jose.v2 v2.5.2-0.20210529014059-a5c7eec3c614 // indirect
 | 
				
			||||||
	gopkg.in/yaml.v2 v2.4.0 // indirect
 | 
						gopkg.in/yaml.v2 v2.4.0 // indirect
 | 
				
			||||||
	gopkg.in/yaml.v3 v3.0.1 // indirect
 | 
						gopkg.in/yaml.v3 v3.0.1 // indirect
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										2
									
								
								go.sum
								
								
								
								
							
							
						
						
									
										2
									
								
								go.sum
								
								
								
								
							| 
						 | 
					@ -667,6 +667,8 @@ gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EV
 | 
				
			||||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 | 
					gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
 | 
				
			||||||
gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4=
 | 
					gopkg.in/ini.v1 v1.66.4 h1:SsAcf+mM7mRZo2nJNGt8mZCjG8ZRaNGMURJw7BsIST4=
 | 
				
			||||||
gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 | 
					gopkg.in/ini.v1 v1.66.4/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k=
 | 
				
			||||||
 | 
					gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22 h1:VpOs+IwYnYBaFnrNAeB8UUWtL3vEUnzSCL1nVjPhqrw=
 | 
				
			||||||
 | 
					gopkg.in/mgo.v2 v2.0.0-20190816093944-a6b53ec6cb22/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA=
 | 
				
			||||||
gopkg.in/square/go-jose.v2 v2.5.2-0.20210529014059-a5c7eec3c614 h1:lwJmuuJQGclcankpPJwh8rorzB0bNbVALv8phDGh8TQ=
 | 
					gopkg.in/square/go-jose.v2 v2.5.2-0.20210529014059-a5c7eec3c614 h1:lwJmuuJQGclcankpPJwh8rorzB0bNbVALv8phDGh8TQ=
 | 
				
			||||||
gopkg.in/square/go-jose.v2 v2.5.2-0.20210529014059-a5c7eec3c614/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
 | 
					gopkg.in/square/go-jose.v2 v2.5.2-0.20210529014059-a5c7eec3c614/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI=
 | 
				
			||||||
gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
					gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,304 @@
 | 
				
			||||||
 | 
					package application
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"context"
 | 
				
			||||||
 | 
						"encoding/json"
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
						"sort"
 | 
				
			||||||
 | 
						"strconv"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						formvalidators "git.coopgo.io/coopgo-apps/parcoursmob/utils/form-validators"
 | 
				
			||||||
 | 
						"git.coopgo.io/coopgo-apps/parcoursmob/utils/identification"
 | 
				
			||||||
 | 
						agenda "git.coopgo.io/coopgo-platform/agenda/grpcapi"
 | 
				
			||||||
 | 
						agendastorage "git.coopgo.io/coopgo-platform/agenda/storage"
 | 
				
			||||||
 | 
						groupsmanagement "git.coopgo.io/coopgo-platform/groups-management/grpcapi"
 | 
				
			||||||
 | 
						"git.coopgo.io/coopgo-platform/groups-management/storage"
 | 
				
			||||||
 | 
						mobilityaccounts "git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi"
 | 
				
			||||||
 | 
						"github.com/gorilla/mux"
 | 
				
			||||||
 | 
						"google.golang.org/protobuf/types/known/structpb"
 | 
				
			||||||
 | 
						"google.golang.org/protobuf/types/known/timestamppb"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type EventsByStartdate []agendastorage.Event
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (e EventsByStartdate) Len() int           { return len(e) }
 | 
				
			||||||
 | 
					func (e EventsByStartdate) Less(i, j int) bool { return e[i].Startdate.Before(e[j].Startdate) }
 | 
				
			||||||
 | 
					func (e EventsByStartdate) Swap(i, j int)      { e[i], e[j] = e[j], e[i] }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type EventsForm struct {
 | 
				
			||||||
 | 
						Name           string     `json:"name" validate:"required"`
 | 
				
			||||||
 | 
						Type           string     `json:"type" validate:"required"`
 | 
				
			||||||
 | 
						Description    string     `json:"description"`
 | 
				
			||||||
 | 
						Address        any        `json:"address,omitempty"`
 | 
				
			||||||
 | 
						Allday         bool       `json:"allday"`
 | 
				
			||||||
 | 
						Startdate      *time.Time `json:"startdate"`
 | 
				
			||||||
 | 
						Enddate        *time.Time `json:"enddate"`
 | 
				
			||||||
 | 
						Starttime      string     `json:"starttime"`
 | 
				
			||||||
 | 
						Endtime        string     `json:"endtime"`
 | 
				
			||||||
 | 
						MaxSubscribers int        `json:"max_subscribers" validate:"required"`
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *ApplicationHandler) AgendaHome(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						resp, err := h.services.GRPC.Agenda.GetEvents(context.TODO(), &agenda.GetEventsRequest{
 | 
				
			||||||
 | 
							Namespaces: []string{"parcoursmob_dispositifs"},
 | 
				
			||||||
 | 
							Mindate:    timestamppb.New(time.Now().Add(-24 * time.Hour)),
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							fmt.Println(err)
 | 
				
			||||||
 | 
							w.WriteHeader(http.StatusInternalServerError)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						responses := []agendastorage.Event{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						groupids := []string{}
 | 
				
			||||||
 | 
						for _, e := range resp.Events {
 | 
				
			||||||
 | 
							groupids = append(groupids, e.Owners...)
 | 
				
			||||||
 | 
							responses = append(responses, e.ToStorageType())
 | 
				
			||||||
 | 
							// fmt.Println(e)
 | 
				
			||||||
 | 
							// fmt.Println(e.ToStorageType())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						sort.Sort(EventsByStartdate(responses))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						groupsresp, err := h.services.GRPC.GroupsManagement.GetGroupsBatch(context.TODO(), &groupsmanagement.GetGroupsBatchRequest{
 | 
				
			||||||
 | 
							Groupids: groupids,
 | 
				
			||||||
 | 
						})
 | 
				
			||||||
 | 
						groups := map[string]any{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							for _, g := range groupsresp.Groups {
 | 
				
			||||||
 | 
								groups[g.Id] = g.ToStorageType()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						h.Renderer.AgendaHome(w, r, responses, groups)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *ApplicationHandler) AgendaCreateEvent(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						if r.Method == "POST" {
 | 
				
			||||||
 | 
							// Get current group
 | 
				
			||||||
 | 
							g := r.Context().Value(identification.GroupKey)
 | 
				
			||||||
 | 
							if g == nil {
 | 
				
			||||||
 | 
								w.WriteHeader(http.StatusBadRequest)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							group := g.(storage.Group)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							eventForm, err := parseEventsForm(r)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								fmt.Println(err)
 | 
				
			||||||
 | 
								w.WriteHeader(http.StatusBadRequest)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							fmt.Println(eventForm)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							data, _ := structpb.NewStruct(map[string]any{
 | 
				
			||||||
 | 
								"address": eventForm.Address,
 | 
				
			||||||
 | 
							})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							request := &agenda.CreateEventRequest{
 | 
				
			||||||
 | 
								Event: &agenda.Event{
 | 
				
			||||||
 | 
									Namespace:      "parcoursmob_dispositifs",
 | 
				
			||||||
 | 
									Owners:         []string{group.ID},
 | 
				
			||||||
 | 
									Type:           eventForm.Type,
 | 
				
			||||||
 | 
									Name:           eventForm.Name,
 | 
				
			||||||
 | 
									Description:    eventForm.Description,
 | 
				
			||||||
 | 
									Startdate:      timestamppb.New(*eventForm.Startdate),
 | 
				
			||||||
 | 
									Enddate:        timestamppb.New(*eventForm.Enddate),
 | 
				
			||||||
 | 
									Starttime:      eventForm.Starttime,
 | 
				
			||||||
 | 
									Endtime:        eventForm.Endtime,
 | 
				
			||||||
 | 
									Allday:         eventForm.Allday,
 | 
				
			||||||
 | 
									MaxSubscribers: int64(eventForm.MaxSubscribers),
 | 
				
			||||||
 | 
									Data:           data,
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							resp, err := h.services.GRPC.Agenda.CreateEvent(context.TODO(), request)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								fmt.Println(err)
 | 
				
			||||||
 | 
								w.WriteHeader(http.StatusInternalServerError)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							http.Redirect(w, r, fmt.Sprintf("/app/agenda/%s", resp.Event.Id), http.StatusFound)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						h.Renderer.AgendaCreateEvent(w, r)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *ApplicationHandler) AgendaDisplayEvent(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						vars := mux.Vars(r)
 | 
				
			||||||
 | 
						eventid := vars["eventid"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						request := &agenda.GetEventRequest{
 | 
				
			||||||
 | 
							Id: eventid,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						resp, err := h.services.GRPC.Agenda.GetEvent(context.TODO(), request)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							fmt.Println(err)
 | 
				
			||||||
 | 
							w.WriteHeader(http.StatusInternalServerError)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						grouprequest := &groupsmanagement.GetGroupRequest{
 | 
				
			||||||
 | 
							Id: resp.Event.Owners[0],
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						groupresp, err := h.services.GRPC.GroupsManagement.GetGroup(context.TODO(), grouprequest)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							fmt.Println(err)
 | 
				
			||||||
 | 
							w.WriteHeader(http.StatusInternalServerError)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						subscribers := map[string]any{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						subscriberresp, err := h.services.GRPC.MobilityAccounts.GetAccountsBatch(
 | 
				
			||||||
 | 
							context.TODO(),
 | 
				
			||||||
 | 
							&mobilityaccounts.GetAccountsBatchRequest{
 | 
				
			||||||
 | 
								Accountids: resp.Event.Subscribers,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							for _, sub := range subscriberresp.Accounts {
 | 
				
			||||||
 | 
								subscribers[sub.Id] = sub.ToStorageType()
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						g := r.Context().Value(identification.GroupKey)
 | 
				
			||||||
 | 
						if g == nil {
 | 
				
			||||||
 | 
							fmt.Println(err)
 | 
				
			||||||
 | 
							w.WriteHeader(http.StatusInternalServerError)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						group := g.(storage.Group)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						accountids := []string{}
 | 
				
			||||||
 | 
						for _, m := range group.Members {
 | 
				
			||||||
 | 
							if !contains(resp.Event.Subscribers, m) {
 | 
				
			||||||
 | 
								accountids = append(accountids, m)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						accountresp, err := h.services.GRPC.MobilityAccounts.GetAccountsBatch(
 | 
				
			||||||
 | 
							context.TODO(),
 | 
				
			||||||
 | 
							&mobilityaccounts.GetAccountsBatchRequest{
 | 
				
			||||||
 | 
								Accountids: accountids,
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						accounts := []any{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err == nil {
 | 
				
			||||||
 | 
							for _, acc := range accountresp.Accounts {
 | 
				
			||||||
 | 
								accounts = append(accounts, acc)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						h.Renderer.AgendaDisplayEvent(w, r, resp.Event.ToStorageType(), groupresp.Group.ToStorageType(), subscribers, accounts)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h *ApplicationHandler) AgendaSubscribeEvent(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						vars := mux.Vars(r)
 | 
				
			||||||
 | 
						eventid := vars["eventid"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if err := r.ParseForm(); err != nil {
 | 
				
			||||||
 | 
							fmt.Println(err)
 | 
				
			||||||
 | 
							w.WriteHeader(http.StatusBadRequest)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						subscriber := r.FormValue("subscriber")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						request := &agenda.SubscribeEventRequest{
 | 
				
			||||||
 | 
							Eventid:    eventid,
 | 
				
			||||||
 | 
							Subscriber: subscriber,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						_, err := h.services.GRPC.Agenda.SubscribeEvent(context.TODO(), request)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							fmt.Println(err)
 | 
				
			||||||
 | 
							w.WriteHeader(http.StatusInternalServerError)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						http.Redirect(w, r, fmt.Sprintf("/app/agenda/%s", eventid), http.StatusFound)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseEventsForm(r *http.Request) (*EventsForm, error) {
 | 
				
			||||||
 | 
						if err := r.ParseForm(); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var startdate *time.Time
 | 
				
			||||||
 | 
						var enddate *time.Time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if r.PostFormValue("startdate") != "" {
 | 
				
			||||||
 | 
							d, err := time.Parse("2006-01-02", r.PostFormValue("startdate"))
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							startdate = &d
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if r.PostFormValue("enddate") != "" {
 | 
				
			||||||
 | 
							d, err := time.Parse("2006-01-02", r.PostFormValue("enddate"))
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							enddate = &d
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						max_subscribers, err := strconv.Atoi(r.PostFormValue("max_subscribers"))
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						formData := &EventsForm{
 | 
				
			||||||
 | 
							Name:           r.PostFormValue("name"),
 | 
				
			||||||
 | 
							Type:           r.PostFormValue("type"),
 | 
				
			||||||
 | 
							Description:    r.PostFormValue("description"),
 | 
				
			||||||
 | 
							Startdate:      startdate,
 | 
				
			||||||
 | 
							Enddate:        enddate,
 | 
				
			||||||
 | 
							Starttime:      r.PostFormValue("starttime"),
 | 
				
			||||||
 | 
							Endtime:        r.PostFormValue("endtime"),
 | 
				
			||||||
 | 
							MaxSubscribers: max_subscribers,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if r.PostFormValue("allday") == "true" {
 | 
				
			||||||
 | 
							formData.Allday = true
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if r.PostFormValue("address") != "" {
 | 
				
			||||||
 | 
							var a any
 | 
				
			||||||
 | 
							json.Unmarshal([]byte(r.PostFormValue("address")), &a)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							formData.Address = a
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						validate := formvalidators.New()
 | 
				
			||||||
 | 
						if err := validate.Struct(formData); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return formData, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func contains(s []string, e string) bool {
 | 
				
			||||||
 | 
						for _, a := range s {
 | 
				
			||||||
 | 
							if a == e {
 | 
				
			||||||
 | 
								return true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -16,6 +16,7 @@ import (
 | 
				
			||||||
	formvalidators "git.coopgo.io/coopgo-apps/parcoursmob/utils/form-validators"
 | 
						formvalidators "git.coopgo.io/coopgo-apps/parcoursmob/utils/form-validators"
 | 
				
			||||||
	"git.coopgo.io/coopgo-apps/parcoursmob/utils/identification"
 | 
						"git.coopgo.io/coopgo-apps/parcoursmob/utils/identification"
 | 
				
			||||||
	profilepictures "git.coopgo.io/coopgo-apps/parcoursmob/utils/profile-pictures"
 | 
						profilepictures "git.coopgo.io/coopgo-apps/parcoursmob/utils/profile-pictures"
 | 
				
			||||||
 | 
						fleets "git.coopgo.io/coopgo-platform/fleets/grpcapi"
 | 
				
			||||||
	groupsmanagement "git.coopgo.io/coopgo-platform/groups-management/grpcapi"
 | 
						groupsmanagement "git.coopgo.io/coopgo-platform/groups-management/grpcapi"
 | 
				
			||||||
	"git.coopgo.io/coopgo-platform/groups-management/storage"
 | 
						"git.coopgo.io/coopgo-platform/groups-management/storage"
 | 
				
			||||||
	mobilityaccounts "git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi"
 | 
						mobilityaccounts "git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi"
 | 
				
			||||||
| 
						 | 
					@ -61,7 +62,7 @@ func (h *ApplicationHandler) BeneficiaryCreate(w http.ResponseWriter, r *http.Re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if r.Method == "POST" {
 | 
						if r.Method == "POST" {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		dataMap, err := parseForm(r)
 | 
							dataMap, err := parseBeneficiariesForm(r)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			fmt.Println(err)
 | 
								fmt.Println(err)
 | 
				
			||||||
			w.WriteHeader(http.StatusBadRequest)
 | 
								w.WriteHeader(http.StatusBadRequest)
 | 
				
			||||||
| 
						 | 
					@ -128,7 +129,23 @@ func (h *ApplicationHandler) BeneficiaryDisplay(w http.ResponseWriter, r *http.R
 | 
				
			||||||
	//TODO filter namespaces
 | 
						//TODO filter namespaces
 | 
				
			||||||
	//TODO filter groups
 | 
						//TODO filter groups
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	h.Renderer.BeneficiaryDisplay(w, r, resp.Account.ToStorageType())
 | 
						bookingsrequest := &fleets.GetDriverBookingsRequest{
 | 
				
			||||||
 | 
							Driver: beneficiaryID,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						bookingsresp, err := h.services.GRPC.Fleets.GetDriverBookings(context.TODO(), bookingsrequest)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							fmt.Println(err)
 | 
				
			||||||
 | 
							w.WriteHeader(http.StatusInternalServerError)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bookings := []any{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, b := range bookingsresp.Bookings {
 | 
				
			||||||
 | 
							bookings = append(bookings, b.ToStorageType())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						h.Renderer.BeneficiaryDisplay(w, r, resp.Account.ToStorageType(), bookings)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (h *ApplicationHandler) BeneficiaryUpdate(w http.ResponseWriter, r *http.Request) {
 | 
					func (h *ApplicationHandler) BeneficiaryUpdate(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
| 
						 | 
					@ -137,7 +154,7 @@ func (h *ApplicationHandler) BeneficiaryUpdate(w http.ResponseWriter, r *http.Re
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if r.Method == "POST" {
 | 
						if r.Method == "POST" {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		dataMap, err := parseForm(r)
 | 
							dataMap, err := parseBeneficiariesForm(r)
 | 
				
			||||||
		if err != nil {
 | 
							if err != nil {
 | 
				
			||||||
			fmt.Println(err)
 | 
								fmt.Println(err)
 | 
				
			||||||
			w.WriteHeader(http.StatusBadRequest)
 | 
								w.WriteHeader(http.StatusBadRequest)
 | 
				
			||||||
| 
						 | 
					@ -189,56 +206,6 @@ func (h *ApplicationHandler) BeneficiaryUpdate(w http.ResponseWriter, r *http.Re
 | 
				
			||||||
	h.Renderer.BeneficiaryUpdate(w, r, resp.Account.ToStorageType())
 | 
						h.Renderer.BeneficiaryUpdate(w, r, resp.Account.ToStorageType())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func parseForm(r *http.Request) (map[string]any, error) {
 | 
					 | 
				
			||||||
	if err := r.ParseForm(); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var date *time.Time
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if r.PostFormValue("birthdate") != "" {
 | 
					 | 
				
			||||||
		d, err := time.Parse("2006-01-02", r.PostFormValue("birthdate"))
 | 
					 | 
				
			||||||
		if err != nil {
 | 
					 | 
				
			||||||
			return nil, err
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		date = &d
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	formData := BeneficiariesForm{
 | 
					 | 
				
			||||||
		FirstName:   r.PostFormValue("first_name"),
 | 
					 | 
				
			||||||
		LastName:    r.PostFormValue("last_name"),
 | 
					 | 
				
			||||||
		Email:       r.PostFormValue("email"),
 | 
					 | 
				
			||||||
		Birthdate:   date,
 | 
					 | 
				
			||||||
		PhoneNumber: r.PostFormValue("phone_number"),
 | 
					 | 
				
			||||||
		Gender:      r.PostFormValue("gender"),
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	if r.PostFormValue("address") != "" {
 | 
					 | 
				
			||||||
		var a any
 | 
					 | 
				
			||||||
		json.Unmarshal([]byte(r.PostFormValue("address")), &a)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
		formData.Address = a
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	validate := formvalidators.New()
 | 
					 | 
				
			||||||
	if err := validate.Struct(formData); err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	d, err := json.Marshal(formData)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	var dataMap map[string]any
 | 
					 | 
				
			||||||
	err = json.Unmarshal(d, &dataMap)
 | 
					 | 
				
			||||||
	if err != nil {
 | 
					 | 
				
			||||||
		return nil, err
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return dataMap, nil
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func (h *ApplicationHandler) BeneficiaryPicture(w http.ResponseWriter, r *http.Request) {
 | 
					func (h *ApplicationHandler) BeneficiaryPicture(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
	vars := mux.Vars(r)
 | 
						vars := mux.Vars(r)
 | 
				
			||||||
	beneficiaryID := vars["beneficiaryid"]
 | 
						beneficiaryID := vars["beneficiaryid"]
 | 
				
			||||||
| 
						 | 
					@ -312,3 +279,53 @@ func (h *ApplicationHandler) beneficiaries(r *http.Request) ([]any, error) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return accounts, err
 | 
						return accounts, err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func parseBeneficiariesForm(r *http.Request) (map[string]any, error) {
 | 
				
			||||||
 | 
						if err := r.ParseForm(); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var date *time.Time
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if r.PostFormValue("birthdate") != "" {
 | 
				
			||||||
 | 
							d, err := time.Parse("2006-01-02", r.PostFormValue("birthdate"))
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								return nil, err
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							date = &d
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						formData := BeneficiariesForm{
 | 
				
			||||||
 | 
							FirstName:   r.PostFormValue("first_name"),
 | 
				
			||||||
 | 
							LastName:    r.PostFormValue("last_name"),
 | 
				
			||||||
 | 
							Email:       r.PostFormValue("email"),
 | 
				
			||||||
 | 
							Birthdate:   date,
 | 
				
			||||||
 | 
							PhoneNumber: r.PostFormValue("phone_number"),
 | 
				
			||||||
 | 
							Gender:      r.PostFormValue("gender"),
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if r.PostFormValue("address") != "" {
 | 
				
			||||||
 | 
							var a any
 | 
				
			||||||
 | 
							json.Unmarshal([]byte(r.PostFormValue("address")), &a)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							formData.Address = a
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						validate := formvalidators.New()
 | 
				
			||||||
 | 
						if err := validate.Struct(formData); err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						d, err := json.Marshal(formData)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var dataMap map[string]any
 | 
				
			||||||
 | 
						err = json.Unmarshal(d, &dataMap)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return dataMap, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,6 +5,7 @@ import (
 | 
				
			||||||
	"encoding/json"
 | 
						"encoding/json"
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"git.coopgo.io/coopgo-apps/parcoursmob/utils/identification"
 | 
						"git.coopgo.io/coopgo-apps/parcoursmob/utils/identification"
 | 
				
			||||||
	fleets "git.coopgo.io/coopgo-platform/fleets/grpcapi"
 | 
						fleets "git.coopgo.io/coopgo-platform/fleets/grpcapi"
 | 
				
			||||||
| 
						 | 
					@ -14,6 +15,7 @@ import (
 | 
				
			||||||
	"github.com/google/uuid"
 | 
						"github.com/google/uuid"
 | 
				
			||||||
	"github.com/gorilla/mux"
 | 
						"github.com/gorilla/mux"
 | 
				
			||||||
	"google.golang.org/protobuf/types/known/structpb"
 | 
						"google.golang.org/protobuf/types/known/structpb"
 | 
				
			||||||
 | 
						"google.golang.org/protobuf/types/known/timestamppb"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (h *ApplicationHandler) VehiclesManagementOverview(w http.ResponseWriter, r *http.Request) {
 | 
					func (h *ApplicationHandler) VehiclesManagementOverview(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
| 
						 | 
					@ -182,6 +184,57 @@ func (h ApplicationHandler) VehicleManagementBookingDisplay(w http.ResponseWrite
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	booking := resp.Booking.ToStorageType()
 | 
						booking := resp.Booking.ToStorageType()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if r.Method == "POST" {
 | 
				
			||||||
 | 
							r.ParseForm()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							newbooking := resp.Booking
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							startdate := r.FormValue("startdate")
 | 
				
			||||||
 | 
							if startdate != "" {
 | 
				
			||||||
 | 
								newstartdate, _ := time.Parse("2006-01-02", startdate)
 | 
				
			||||||
 | 
								newbooking.Startdate = timestamppb.New(newstartdate)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if newstartdate.Before(newbooking.Unavailablefrom.AsTime()) {
 | 
				
			||||||
 | 
									newbooking.Unavailablefrom = timestamppb.New(newstartdate)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							enddate := r.FormValue("enddate")
 | 
				
			||||||
 | 
							if enddate != "" {
 | 
				
			||||||
 | 
								newenddate, _ := time.Parse("2006-01-02", enddate)
 | 
				
			||||||
 | 
								newbooking.Enddate = timestamppb.New(newenddate)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if newenddate.After(newbooking.Unavailableto.AsTime()) || newenddate.Equal(newbooking.Unavailableto.AsTime()) {
 | 
				
			||||||
 | 
									newbooking.Unavailableto = timestamppb.New(newenddate.Add(24 * time.Hour))
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							unavailablefrom := r.FormValue("unavailablefrom")
 | 
				
			||||||
 | 
							if unavailablefrom != "" {
 | 
				
			||||||
 | 
								newunavailablefrom, _ := time.Parse("2006-01-02", unavailablefrom)
 | 
				
			||||||
 | 
								newbooking.Unavailablefrom = timestamppb.New(newunavailablefrom)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							unavailableto := r.FormValue("unavailableto")
 | 
				
			||||||
 | 
							if unavailableto != "" {
 | 
				
			||||||
 | 
								newunavailableto, _ := time.Parse("2006-01-02", unavailableto)
 | 
				
			||||||
 | 
								newbooking.Unavailableto = timestamppb.New(newunavailableto)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							request := &fleets.UpdateBookingRequest{
 | 
				
			||||||
 | 
								Booking: newbooking,
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							_, err := h.services.GRPC.Fleets.UpdateBooking(context.TODO(), request)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								fmt.Println(err)
 | 
				
			||||||
 | 
								w.WriteHeader(http.StatusInternalServerError)
 | 
				
			||||||
 | 
								return
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							booking = newbooking.ToStorageType()
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	beneficiaryrequest := &mobilityaccounts.GetAccountRequest{
 | 
						beneficiaryrequest := &mobilityaccounts.GetAccountRequest{
 | 
				
			||||||
		Id: booking.Driver,
 | 
							Id: booking.Driver,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -6,10 +6,15 @@ import (
 | 
				
			||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"git.coopgo.io/coopgo-apps/parcoursmob/utils/identification"
 | 
				
			||||||
	fleets "git.coopgo.io/coopgo-platform/fleets/grpcapi"
 | 
						fleets "git.coopgo.io/coopgo-platform/fleets/grpcapi"
 | 
				
			||||||
 | 
						groupsmanagement "git.coopgo.io/coopgo-platform/groups-management/grpcapi"
 | 
				
			||||||
 | 
						"git.coopgo.io/coopgo-platform/groups-management/storage"
 | 
				
			||||||
	mobilityaccounts "git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi"
 | 
						mobilityaccounts "git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi"
 | 
				
			||||||
 | 
						"github.com/coreos/go-oidc"
 | 
				
			||||||
	"github.com/google/uuid"
 | 
						"github.com/google/uuid"
 | 
				
			||||||
	"github.com/gorilla/mux"
 | 
						"github.com/gorilla/mux"
 | 
				
			||||||
 | 
						"google.golang.org/protobuf/types/known/structpb"
 | 
				
			||||||
	"google.golang.org/protobuf/types/known/timestamppb"
 | 
						"google.golang.org/protobuf/types/known/timestamppb"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -71,6 +76,32 @@ func (h ApplicationHandler) VehiclesSearch(w http.ResponseWriter, r *http.Reques
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (h ApplicationHandler) Book(w http.ResponseWriter, r *http.Request) {
 | 
					func (h ApplicationHandler) Book(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						// Get Group
 | 
				
			||||||
 | 
						g := r.Context().Value(identification.GroupKey)
 | 
				
			||||||
 | 
						if g == nil {
 | 
				
			||||||
 | 
							fmt.Println("no current group")
 | 
				
			||||||
 | 
							w.WriteHeader(http.StatusInternalServerError)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						current_group := g.(storage.Group)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Get current user ID
 | 
				
			||||||
 | 
						u := r.Context().Value(identification.IdtokenKey)
 | 
				
			||||||
 | 
						if u == nil {
 | 
				
			||||||
 | 
							fmt.Println("no current user")
 | 
				
			||||||
 | 
							w.WriteHeader(http.StatusInternalServerError)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						current_user_token := u.(*oidc.IDToken)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Get current user claims
 | 
				
			||||||
 | 
						c := r.Context().Value(identification.ClaimsKey)
 | 
				
			||||||
 | 
						if c == nil {
 | 
				
			||||||
 | 
							fmt.Println("no current user claims")
 | 
				
			||||||
 | 
							w.WriteHeader(http.StatusInternalServerError)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						current_user_claims := c.(map[string]any)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	vars := mux.Vars(r)
 | 
						vars := mux.Vars(r)
 | 
				
			||||||
	vehicleid := vars["vehicleid"]
 | 
						vehicleid := vars["vehicleid"]
 | 
				
			||||||
| 
						 | 
					@ -84,6 +115,25 @@ func (h ApplicationHandler) Book(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
	startdate, _ := time.Parse("2006-01-02", start)
 | 
						startdate, _ := time.Parse("2006-01-02", start)
 | 
				
			||||||
	enddate, _ := time.Parse("2006-01-02", end)
 | 
						enddate, _ := time.Parse("2006-01-02", end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						data := map[string]any{
 | 
				
			||||||
 | 
							"booked_by": map[string]any{
 | 
				
			||||||
 | 
								"user": map[string]any{
 | 
				
			||||||
 | 
									"id":           current_user_token.Subject,
 | 
				
			||||||
 | 
									"display_name": current_user_claims["display_name"],
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
								"group": map[string]any{
 | 
				
			||||||
 | 
									"id":   current_group.ID,
 | 
				
			||||||
 | 
									"name": current_group.Data["name"],
 | 
				
			||||||
 | 
								},
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						datapb, err := structpb.NewStruct(data)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							fmt.Println(err)
 | 
				
			||||||
 | 
							w.WriteHeader(http.StatusInternalServerError)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	booking := &fleets.Booking{
 | 
						booking := &fleets.Booking{
 | 
				
			||||||
		Id:              uuid.NewString(),
 | 
							Id:              uuid.NewString(),
 | 
				
			||||||
		Vehicleid:       vehicleid,
 | 
							Vehicleid:       vehicleid,
 | 
				
			||||||
| 
						 | 
					@ -92,13 +142,14 @@ func (h ApplicationHandler) Book(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
		Enddate:         timestamppb.New(enddate),
 | 
							Enddate:         timestamppb.New(enddate),
 | 
				
			||||||
		Unavailablefrom: timestamppb.New(startdate),
 | 
							Unavailablefrom: timestamppb.New(startdate),
 | 
				
			||||||
		Unavailableto:   timestamppb.New(enddate.Add(72 * time.Hour)),
 | 
							Unavailableto:   timestamppb.New(enddate.Add(72 * time.Hour)),
 | 
				
			||||||
 | 
							Data:            datapb,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	request := &fleets.CreateBookingRequest{
 | 
						request := &fleets.CreateBookingRequest{
 | 
				
			||||||
		Booking: booking,
 | 
							Booking: booking,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	_, err := h.services.GRPC.Fleets.CreateBooking(context.TODO(), request)
 | 
						_, err = h.services.GRPC.Fleets.CreateBooking(context.TODO(), request)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		fmt.Println(err)
 | 
							fmt.Println(err)
 | 
				
			||||||
		w.WriteHeader(http.StatusBadRequest)
 | 
							w.WriteHeader(http.StatusBadRequest)
 | 
				
			||||||
| 
						 | 
					@ -136,16 +187,34 @@ func (h ApplicationHandler) VehicleBookingDisplay(w http.ResponseWriter, r *http
 | 
				
			||||||
		return
 | 
							return
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// grouprequest := &groupsmanagement.GetGroupRequest{
 | 
						grouprequest := &groupsmanagement.GetGroupRequest{
 | 
				
			||||||
	// 	Id: booking.Vehicle.Administrators[0],
 | 
							Id: booking.Vehicle.Administrators[0],
 | 
				
			||||||
	// }
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// groupresp, err := h.services.GRPC.GroupsManagement.GetGroup(context.TODO(), grouprequest)
 | 
						groupresp, err := h.services.GRPC.GroupsManagement.GetGroup(context.TODO(), grouprequest)
 | 
				
			||||||
	// if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
	// 	fmt.Println(err)
 | 
							fmt.Println(err)
 | 
				
			||||||
	// 	w.WriteHeader(http.StatusInternalServerError)
 | 
							w.WriteHeader(http.StatusInternalServerError)
 | 
				
			||||||
	// 	return
 | 
							return
 | 
				
			||||||
	// }
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	h.Renderer.VehicleBookingDisplay(w, r, booking, booking.Vehicle, beneficiaryresp.Account.ToStorageType(), "")
 | 
						h.Renderer.VehicleBookingDisplay(w, r, booking, booking.Vehicle, beneficiaryresp.Account.ToStorageType(), groupresp.Group.ToStorageType())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (h ApplicationHandler) VehiclesBookingsList(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						request := &fleets.GetBookingsRequest{}
 | 
				
			||||||
 | 
						resp, err := h.services.GRPC.Fleets.GetBookings(context.TODO(), request)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							fmt.Println(err)
 | 
				
			||||||
 | 
							w.WriteHeader(http.StatusNotFound)
 | 
				
			||||||
 | 
							return
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						bookings := []any{}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, b := range resp.Bookings {
 | 
				
			||||||
 | 
							bookings = append(bookings, b.ToStorageType())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						h.Renderer.VehicleBookingsList(w, r, bookings)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										11
									
								
								main.go
								
								
								
								
							
							
						
						
									
										11
									
								
								main.go
								
								
								
								
							| 
						 | 
					@ -54,6 +54,7 @@ func main() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	r.HandleFunc("/auth/groups/", authHandler.Groups)
 | 
						r.HandleFunc("/auth/groups/", authHandler.Groups)
 | 
				
			||||||
	r.HandleFunc("/auth/groups/switch", authHandler.GroupSwitch)
 | 
						r.HandleFunc("/auth/groups/switch", authHandler.GroupSwitch)
 | 
				
			||||||
 | 
						r.HandleFunc("/", redirectApp)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	api_router := r.PathPrefix("/api").Subrouter()
 | 
						api_router := r.PathPrefix("/api").Subrouter()
 | 
				
			||||||
	api_router.HandleFunc("/", apiHandler.NotFound)
 | 
						api_router.HandleFunc("/", apiHandler.NotFound)
 | 
				
			||||||
| 
						 | 
					@ -68,7 +69,9 @@ func main() {
 | 
				
			||||||
	application.HandleFunc("/beneficiaries/{beneficiaryid}", applicationHandler.BeneficiaryDisplay)
 | 
						application.HandleFunc("/beneficiaries/{beneficiaryid}", applicationHandler.BeneficiaryDisplay)
 | 
				
			||||||
	application.HandleFunc("/beneficiaries/{beneficiaryid}/update", applicationHandler.BeneficiaryUpdate)
 | 
						application.HandleFunc("/beneficiaries/{beneficiaryid}/update", applicationHandler.BeneficiaryUpdate)
 | 
				
			||||||
	application.HandleFunc("/beneficiaries/{beneficiaryid}/picture", applicationHandler.BeneficiaryPicture)
 | 
						application.HandleFunc("/beneficiaries/{beneficiaryid}/picture", applicationHandler.BeneficiaryPicture)
 | 
				
			||||||
 | 
						application.HandleFunc("/members/{beneficiaryid}/picture", applicationHandler.BeneficiaryPicture)
 | 
				
			||||||
	application.HandleFunc("/vehicles/", applicationHandler.VehiclesSearch)
 | 
						application.HandleFunc("/vehicles/", applicationHandler.VehiclesSearch)
 | 
				
			||||||
 | 
						application.HandleFunc("/vehicles/bookings/", applicationHandler.VehiclesBookingsList)
 | 
				
			||||||
	application.HandleFunc("/vehicles/bookings/{bookingid}", applicationHandler.VehicleBookingDisplay)
 | 
						application.HandleFunc("/vehicles/bookings/{bookingid}", applicationHandler.VehicleBookingDisplay)
 | 
				
			||||||
	application.HandleFunc("/vehicles/v/{vehicleid}/b/{beneficiaryid}", applicationHandler.Book)
 | 
						application.HandleFunc("/vehicles/v/{vehicleid}/b/{beneficiaryid}", applicationHandler.Book)
 | 
				
			||||||
	application.HandleFunc("/vehicles-management/", applicationHandler.VehiclesManagementOverview)
 | 
						application.HandleFunc("/vehicles-management/", applicationHandler.VehiclesManagementOverview)
 | 
				
			||||||
| 
						 | 
					@ -76,6 +79,10 @@ func main() {
 | 
				
			||||||
	application.HandleFunc("/vehicles-management/fleet/{vehicleid}", applicationHandler.VehiclesFleetDisplay)
 | 
						application.HandleFunc("/vehicles-management/fleet/{vehicleid}", applicationHandler.VehiclesFleetDisplay)
 | 
				
			||||||
	application.HandleFunc("/vehicles-management/fleet/{vehicleid}/update", applicationHandler.VehiclesFleetUpdate)
 | 
						application.HandleFunc("/vehicles-management/fleet/{vehicleid}/update", applicationHandler.VehiclesFleetUpdate)
 | 
				
			||||||
	application.HandleFunc("/vehicles-management/bookings/{bookingid}", applicationHandler.VehicleManagementBookingDisplay)
 | 
						application.HandleFunc("/vehicles-management/bookings/{bookingid}", applicationHandler.VehicleManagementBookingDisplay)
 | 
				
			||||||
 | 
						application.HandleFunc("/agenda/", applicationHandler.AgendaHome)
 | 
				
			||||||
 | 
						application.HandleFunc("/agenda/create-event", applicationHandler.AgendaCreateEvent)
 | 
				
			||||||
 | 
						application.HandleFunc("/agenda/{eventid}", applicationHandler.AgendaDisplayEvent)
 | 
				
			||||||
 | 
						application.HandleFunc("/agenda/{eventid}/subscribe", applicationHandler.AgendaSubscribeEvent)
 | 
				
			||||||
	//TODO Subrouters with middlewares checking security for each module ?
 | 
						//TODO Subrouters with middlewares checking security for each module ?
 | 
				
			||||||
	application.Use(idp.Middleware)
 | 
						application.Use(idp.Middleware)
 | 
				
			||||||
	application.Use(idp.GroupsMiddleware)
 | 
						application.Use(idp.GroupsMiddleware)
 | 
				
			||||||
| 
						 | 
					@ -98,3 +105,7 @@ func main() {
 | 
				
			||||||
	log.Fatal(srv.ListenAndServe())
 | 
						log.Fatal(srv.ListenAndServe())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func redirectApp(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						http.Redirect(w, r, "/app/", http.StatusFound)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,40 @@
 | 
				
			||||||
 | 
					package renderer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"net/http"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						agendastorage "git.coopgo.io/coopgo-platform/agenda/storage"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const agendaMenu = "events"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (renderer *Renderer) AgendaHome(w http.ResponseWriter, r *http.Request, events []agendastorage.Event, groups map[string]any) {
 | 
				
			||||||
 | 
						files := renderer.ThemeConfig.GetStringSlice("views.agenda.list.files")
 | 
				
			||||||
 | 
						state := NewState(r, renderer.ThemeConfig, agendaMenu)
 | 
				
			||||||
 | 
						state.ViewState = map[string]any{
 | 
				
			||||||
 | 
							"events": events,
 | 
				
			||||||
 | 
							"groups": groups,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						renderer.Render("agenda home", w, r, files, state)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (renderer *Renderer) AgendaCreateEvent(w http.ResponseWriter, r *http.Request) {
 | 
				
			||||||
 | 
						files := renderer.ThemeConfig.GetStringSlice("views.agenda.create_event.files")
 | 
				
			||||||
 | 
						state := NewState(r, renderer.ThemeConfig, agendaMenu)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						renderer.Render("agenda create event", w, r, files, state)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (renderer *Renderer) AgendaDisplayEvent(w http.ResponseWriter, r *http.Request, event any, group any, subscribers map[string]any, beneficiaries any) {
 | 
				
			||||||
 | 
						files := renderer.ThemeConfig.GetStringSlice("views.agenda.display_event.files")
 | 
				
			||||||
 | 
						state := NewState(r, renderer.ThemeConfig, agendaMenu)
 | 
				
			||||||
 | 
						state.ViewState = map[string]any{
 | 
				
			||||||
 | 
							"event":         event,
 | 
				
			||||||
 | 
							"group":         group,
 | 
				
			||||||
 | 
							"subscribers":   subscribers,
 | 
				
			||||||
 | 
							"beneficiaries": beneficiaries,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						renderer.Render("agenda create event", w, r, files, state)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -50,10 +50,13 @@ type BeneficiariesDisplayState struct {
 | 
				
			||||||
	Beneficiary any
 | 
						Beneficiary any
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (renderer *Renderer) BeneficiaryDisplay(w http.ResponseWriter, r *http.Request, beneficiary any) {
 | 
					func (renderer *Renderer) BeneficiaryDisplay(w http.ResponseWriter, r *http.Request, beneficiary any, bookings []any) {
 | 
				
			||||||
	files := renderer.ThemeConfig.GetStringSlice("views.beneficiaries.display.files")
 | 
						files := renderer.ThemeConfig.GetStringSlice("views.beneficiaries.display.files")
 | 
				
			||||||
	state := NewState(r, renderer.ThemeConfig, beneficiariesMenu)
 | 
						state := NewState(r, renderer.ThemeConfig, beneficiariesMenu)
 | 
				
			||||||
	state.ViewState = beneficiary
 | 
						state.ViewState = map[string]any{
 | 
				
			||||||
 | 
							"beneficiary": beneficiary,
 | 
				
			||||||
 | 
							"bookings":    bookings,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	renderer.Render("beneficiaries_display", w, r, files, state)
 | 
						renderer.Render("beneficiaries_display", w, r, files, state)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -122,6 +122,8 @@ func NewState(r *http.Request, themeConfig *viper.Viper, menuState string) Rende
 | 
				
			||||||
			Display: modules["administration"].(bool),
 | 
								Display: modules["administration"].(bool),
 | 
				
			||||||
			Active:  menuState == administrationMenu,
 | 
								Active:  menuState == administrationMenu,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							//TODO from configuration for icons at least
 | 
				
			||||||
		MenuItems: []MenuItem{
 | 
							MenuItems: []MenuItem{
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				Title:  "Tableau de bord",
 | 
									Title:  "Tableau de bord",
 | 
				
			||||||
| 
						 | 
					@ -155,7 +157,7 @@ func NewState(r *http.Request, themeConfig *viper.Viper, menuState string) Rende
 | 
				
			||||||
			Title:  "Véhicules partagés",
 | 
								Title:  "Véhicules partagés",
 | 
				
			||||||
			Link:   "/app/vehicles/",
 | 
								Link:   "/app/vehicles/",
 | 
				
			||||||
			Active: menuState == "vehicles",
 | 
								Active: menuState == "vehicles",
 | 
				
			||||||
			Icon:   "hero:outline/user-group",
 | 
								Icon:   "tabler-icons:car",
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -168,11 +170,11 @@ func NewState(r *http.Request, themeConfig *viper.Viper, menuState string) Rende
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if modules["events"].(bool) {
 | 
						if modules["agenda"].(bool) {
 | 
				
			||||||
		ls.MenuItems = append(ls.MenuItems, MenuItem{
 | 
							ls.MenuItems = append(ls.MenuItems, MenuItem{
 | 
				
			||||||
			Title:  "Dispositifs",
 | 
								Title:  "Agenda dispositifs",
 | 
				
			||||||
			Link:   "/app/events/",
 | 
								Link:   "/app/agenda/",
 | 
				
			||||||
			Active: menuState == "events",
 | 
								Active: menuState == "agenda",
 | 
				
			||||||
			Icon:   "hero:outline/calendar",
 | 
								Icon:   "hero:outline/calendar",
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -38,3 +38,13 @@ func (renderer *Renderer) VehicleBookingDisplay(w http.ResponseWriter, r *http.R
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	renderer.Render("vehicles search", w, r, files, state)
 | 
						renderer.Render("vehicles search", w, r, files, state)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func (renderer *Renderer) VehicleBookingsList(w http.ResponseWriter, r *http.Request, bookings []any) {
 | 
				
			||||||
 | 
						files := renderer.ThemeConfig.GetStringSlice("views.vehicles.bookings_list.files")
 | 
				
			||||||
 | 
						state := NewState(r, renderer.ThemeConfig, vehiclesMenu)
 | 
				
			||||||
 | 
						state.ViewState = map[string]any{
 | 
				
			||||||
 | 
							"bookings": bookings,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						renderer.Render("vehicles search", w, r, files, state)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,23 @@
 | 
				
			||||||
 | 
					package services
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						agenda "git.coopgo.io/coopgo-platform/agenda/grpcapi"
 | 
				
			||||||
 | 
						"google.golang.org/grpc"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					type AgendaService struct {
 | 
				
			||||||
 | 
						agenda.AgendaClient
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewAgendaService(dial string) (*AgendaService, error) {
 | 
				
			||||||
 | 
						conn, err := grpc.Dial(dial, grpc.WithInsecure())
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						client := agenda.NewAgendaClient(conn)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return &AgendaService{
 | 
				
			||||||
 | 
							AgendaClient: client,
 | 
				
			||||||
 | 
						}, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1,6 +1,7 @@
 | 
				
			||||||
package services
 | 
					package services
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						agenda "git.coopgo.io/coopgo-platform/agenda/grpcapi"
 | 
				
			||||||
	fleets "git.coopgo.io/coopgo-platform/fleets/grpcapi"
 | 
						fleets "git.coopgo.io/coopgo-platform/fleets/grpcapi"
 | 
				
			||||||
	groupsmanagement "git.coopgo.io/coopgo-platform/groups-management/grpcapi"
 | 
						groupsmanagement "git.coopgo.io/coopgo-platform/groups-management/grpcapi"
 | 
				
			||||||
	mobilityaccounts "git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi"
 | 
						mobilityaccounts "git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi"
 | 
				
			||||||
| 
						 | 
					@ -15,6 +16,7 @@ type GRPCServices struct {
 | 
				
			||||||
	MobilityAccounts mobilityaccounts.MobilityAccountsClient
 | 
						MobilityAccounts mobilityaccounts.MobilityAccountsClient
 | 
				
			||||||
	GroupsManagement groupsmanagement.GroupsManagementClient
 | 
						GroupsManagement groupsmanagement.GroupsManagementClient
 | 
				
			||||||
	Fleets           fleets.FleetsClient
 | 
						Fleets           fleets.FleetsClient
 | 
				
			||||||
 | 
						Agenda           agenda.AgendaClient
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func NewServicesHandler(cfg *viper.Viper) (*ServicesHandler, error) {
 | 
					func NewServicesHandler(cfg *viper.Viper) (*ServicesHandler, error) {
 | 
				
			||||||
| 
						 | 
					@ -22,6 +24,7 @@ func NewServicesHandler(cfg *viper.Viper) (*ServicesHandler, error) {
 | 
				
			||||||
		mobilityAccountsDial = cfg.GetString("services.grpc.mobilityaccounts.dial")
 | 
							mobilityAccountsDial = cfg.GetString("services.grpc.mobilityaccounts.dial")
 | 
				
			||||||
		groupsManagementDial = cfg.GetString("services.grpc.groupsmanagement.dial")
 | 
							groupsManagementDial = cfg.GetString("services.grpc.groupsmanagement.dial")
 | 
				
			||||||
		fleetsDial           = cfg.GetString("services.grpc.fleets.dial")
 | 
							fleetsDial           = cfg.GetString("services.grpc.fleets.dial")
 | 
				
			||||||
 | 
							agendaDial           = cfg.GetString("services.grpc.agenda.dial")
 | 
				
			||||||
	)
 | 
						)
 | 
				
			||||||
	mobilityAccounts, err := NewMobilityAccountService(mobilityAccountsDial)
 | 
						mobilityAccounts, err := NewMobilityAccountService(mobilityAccountsDial)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
| 
						 | 
					@ -38,11 +41,17 @@ func NewServicesHandler(cfg *viper.Viper) (*ServicesHandler, error) {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						agendaSvc, err := NewAgendaService(agendaDial)
 | 
				
			||||||
 | 
						if err != nil {
 | 
				
			||||||
 | 
							return nil, err
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return &ServicesHandler{
 | 
						return &ServicesHandler{
 | 
				
			||||||
		GRPC: GRPCServices{
 | 
							GRPC: GRPCServices{
 | 
				
			||||||
			MobilityAccounts: mobilityAccounts,
 | 
								MobilityAccounts: mobilityAccounts,
 | 
				
			||||||
			GroupsManagement: groupsManagement,
 | 
								GroupsManagement: groupsManagement,
 | 
				
			||||||
			Fleets:           fleetsSvc,
 | 
								Fleets:           fleetsSvc,
 | 
				
			||||||
 | 
								Agenda:           agendaSvc,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}, nil
 | 
						}, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -39,6 +39,10 @@ views:
 | 
				
			||||||
    booking_display: 
 | 
					    booking_display: 
 | 
				
			||||||
      files: 
 | 
					      files: 
 | 
				
			||||||
        - layouts/vehicles/booking-display.html
 | 
					        - layouts/vehicles/booking-display.html
 | 
				
			||||||
 | 
					    bookings_list: 
 | 
				
			||||||
 | 
					      files: 
 | 
				
			||||||
 | 
					        - layouts/vehicles_management/_partials/bookings-list.html
 | 
				
			||||||
 | 
					        - layouts/vehicles/bookings-list.html
 | 
				
			||||||
  vehicles_management:
 | 
					  vehicles_management:
 | 
				
			||||||
    overview:
 | 
					    overview:
 | 
				
			||||||
      files:
 | 
					      files:
 | 
				
			||||||
| 
						 | 
					@ -62,6 +66,17 @@ views:
 | 
				
			||||||
    booking_display: 
 | 
					    booking_display: 
 | 
				
			||||||
      files: 
 | 
					      files: 
 | 
				
			||||||
        - layouts/vehicles_management/booking-display.html
 | 
					        - layouts/vehicles_management/booking-display.html
 | 
				
			||||||
 | 
					  agenda: 
 | 
				
			||||||
 | 
					    list: 
 | 
				
			||||||
 | 
					      files: 
 | 
				
			||||||
 | 
					        - layouts/agenda/home.html
 | 
				
			||||||
 | 
					    display_event: 
 | 
				
			||||||
 | 
					      files: 
 | 
				
			||||||
 | 
					        - layouts/agenda/display-event.html
 | 
				
			||||||
 | 
					    create_event: 
 | 
				
			||||||
 | 
					      files: 
 | 
				
			||||||
 | 
					        - layouts/_partials/address_autocomplete.html
 | 
				
			||||||
 | 
					        - layouts/agenda/create-event.html
 | 
				
			||||||
  administration:
 | 
					  administration:
 | 
				
			||||||
    home:
 | 
					    home:
 | 
				
			||||||
      files:
 | 
					      files:
 | 
				
			||||||
| 
						 | 
					@ -96,4 +111,4 @@ icons:
 | 
				
			||||||
    hero:solid/search: <svg class="%s" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd" /></svg>
 | 
					    hero:solid/search: <svg class="%s" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path fill-rule="evenodd" d="M8 4a4 4 0 100 8 4 4 0 000-8zM2 8a6 6 0 1110.89 3.476l4.817 4.817a1 1 0 01-1.414 1.414l-4.816-4.816A6 6 0 012 8z" clip-rule="evenodd" /></svg>
 | 
				
			||||||
    hero:solid/selector: <svg class="%s" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path fill-rule="evenodd" d="M10 3a1 1 0 01.707.293l3 3a1 1 0 01-1.414 1.414L10 5.414 7.707 7.707a1 1 0 01-1.414-1.414l3-3A1 1 0 0110 3zm-3.707 9.293a1 1 0 011.414 0L10 14.586l2.293-2.293a1 1 0 011.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" clip-rule="evenodd" /></svg>
 | 
					    hero:solid/selector: <svg class="%s" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true"><path fill-rule="evenodd" d="M10 3a1 1 0 01.707.293l3 3a1 1 0 01-1.414 1.414L10 5.414 7.707 7.707a1 1 0 01-1.414-1.414l3-3A1 1 0 0110 3zm-3.707 9.293a1 1 0 011.414 0L10 14.586l2.293-2.293a1 1 0 011.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" clip-rule="evenodd" /></svg>
 | 
				
			||||||
    img:profile-picture-placeholder: <svg class="%s" fill="currentColor" viewBox="0 0 24 24"><path d="M24 20.993V24H0v-2.996A14.977 14.977 0 0112.004 15c4.904 0 9.26 2.354 11.996 5.993zM16.002 8.999a4 4 0 11-8 0 4 4 0 018 0z" /></svg>
 | 
					    img:profile-picture-placeholder: <svg class="%s" fill="currentColor" viewBox="0 0 24 24"><path d="M24 20.993V24H0v-2.996A14.977 14.977 0 0112.004 15c4.904 0 9.26 2.354 11.996 5.993zM16.002 8.999a4 4 0 11-8 0 4 4 0 018 0z" /></svg>
 | 
				
			||||||
 | 
					    tabler-icons:car: <svg xmlns="http://www.w3.org/2000/svg" class="icon icon-tabler icon-tabler-car %s" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><circle cx="7" cy="17" r="2"></circle><circle cx="17" cy="17" r="2"></circle><path d="M5 17h-2v-6l2 -5h9l4 5h1a2 2 0 0 1 2 2v4h-2m-4 0h-6m-6 -6h15m-6 0v-5"></path></svg>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -117,8 +117,8 @@
 | 
				
			||||||
                                        class="focus:ring-co-blue h-4 w-4 text-co-blue border-gray-300 rounded">
 | 
					                                        class="focus:ring-co-blue h-4 w-4 text-co-blue border-gray-300 rounded">
 | 
				
			||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
                                <div class="ml-3 text-sm">
 | 
					                                <div class="ml-3 text-sm">
 | 
				
			||||||
                                    <label for="modules.events" class="font-medium text-gray-700">Dispositifs</label>
 | 
					                                    <label for="modules.events" class="font-medium text-gray-700">Agenda dispositifs</label>
 | 
				
			||||||
                                    <p class="text-gray-500">Gestion des dispositifs pour les bénéficiaires (auto-écoles sociales, événements, ...)
 | 
					                                    <p class="text-gray-500">Agenda des dispositifs pour les bénéficiaires (sessions permis, événements, ...)
 | 
				
			||||||
                                    </p>
 | 
					                                    </p>
 | 
				
			||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
                            </div>
 | 
					                            </div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -88,8 +88,8 @@
 | 
				
			||||||
                                    class="focus:ring-co-blue h-4 w-4 text-co-blue border-gray-300 rounded">
 | 
					                                    class="focus:ring-co-blue h-4 w-4 text-co-blue border-gray-300 rounded">
 | 
				
			||||||
                            </div>
 | 
					                            </div>
 | 
				
			||||||
                            <div class="ml-3 text-sm">
 | 
					                            <div class="ml-3 text-sm">
 | 
				
			||||||
                                <label for="modules.events" class="font-medium text-gray-700">Dispositifs</label>
 | 
					                                <label for="modules.events" class="font-medium text-gray-700">Agenda dispositifs</label>
 | 
				
			||||||
                                <p class="text-gray-500">Gestion des dispositifs pour les bénéficiaires (auto-écoles sociales, événements, ...)
 | 
					                                <p class="text-gray-500">Agenda des dispositifs pour les bénéficiaires (sessions permis, événements, ...)
 | 
				
			||||||
                                </p>
 | 
					                                </p>
 | 
				
			||||||
                            </div>
 | 
					                            </div>
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,212 @@
 | 
				
			||||||
 | 
					{{ 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 à l'agenda</h1>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-8"
 | 
				
			||||||
 | 
					    x-data="{
 | 
				
			||||||
 | 
					        fields: {
 | 
				
			||||||
 | 
					            name: null,
 | 
				
			||||||
 | 
					            type: null,
 | 
				
			||||||
 | 
					            description: null,
 | 
				
			||||||
 | 
					            allday: false,
 | 
				
			||||||
 | 
					            startdate: null,
 | 
				
			||||||
 | 
					            enddate: null,
 | 
				
			||||||
 | 
					            starttime: null,
 | 
				
			||||||
 | 
					            endtime: null,
 | 
				
			||||||
 | 
					            max_subscribers: 0,
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        rules: {
 | 
				
			||||||
 | 
					            name: ['required'],
 | 
				
			||||||
 | 
					            type: ['required'],
 | 
				
			||||||
 | 
					            startdate: ['required'],
 | 
				
			||||||
 | 
					            enddate: ['required'],
 | 
				
			||||||
 | 
					            starttime: ['optional'],
 | 
				
			||||||
 | 
					            endtime: ['optional'],
 | 
				
			||||||
 | 
					            description: ['optional'],
 | 
				
			||||||
 | 
					            max_subscribers: ['required', 'min:0']
 | 
				
			||||||
 | 
					        },
 | 
				
			||||||
 | 
					        formValidation: {
 | 
				
			||||||
 | 
					            valid: false,
 | 
				
			||||||
 | 
					            fields: {
 | 
				
			||||||
 | 
					                name: {valid: null},
 | 
				
			||||||
 | 
					                type: {valid: null},
 | 
				
			||||||
 | 
					                description: {valid: null},
 | 
				
			||||||
 | 
					                startdate: {valid: null},
 | 
				
			||||||
 | 
					                enddate: {valid: null},
 | 
				
			||||||
 | 
					                starttime: {valid: null},
 | 
				
			||||||
 | 
					                endtime: {valid: null},
 | 
				
			||||||
 | 
					                allday: {valid: null},
 | 
				
			||||||
 | 
					                max_subscribers: {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 sur le dispositif</h3>
 | 
				
			||||||
 | 
					                    <p class="mt-1 text-sm text-gray-500">Informations générales sur le dispositif d'accompagnement à ajouter à l'agenda</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="name" class="block text-sm font-medium text-gray-700">Nom</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="sm:col-span-3">
 | 
				
			||||||
 | 
					                            <label for="type" class="block text-sm font-medium text-gray-700">Type de dispositif</label>
 | 
				
			||||||
 | 
					                            <select id="type" name="type" 
 | 
				
			||||||
 | 
					                                x-model="fields.type" @blur="validateField('type')"
 | 
				
			||||||
 | 
					                                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 rounded-2xl"
 | 
				
			||||||
 | 
					                                :class="formValidation.fields.type.valid == false ? 'border-co-red border-2' : 'border-gray-300'">
 | 
				
			||||||
 | 
					                                <option></option>
 | 
				
			||||||
 | 
					                                <option value="Permis accéléré">Permis accéléré</option>
 | 
				
			||||||
 | 
					                                <option value="Auto-école sociale (classique)">Auto-école sociale (classique)</option>
 | 
				
			||||||
 | 
					                                <option value="Information collective">Information collective</option>
 | 
				
			||||||
 | 
					                                <option value="Autres">Autres</option>
 | 
				
			||||||
 | 
					                            </select>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					                        <div class="col-span-6">
 | 
				
			||||||
 | 
					                            <label for="description" class="block text-sm font-medium text-gray-700">Description</label>
 | 
				
			||||||
 | 
					                            <div class="mt-1">
 | 
				
			||||||
 | 
					                                <textarea rows="4" name="description" id="descrpition" 
 | 
				
			||||||
 | 
					                                    x-model="fields.description" @blur="validateField('description')"
 | 
				
			||||||
 | 
					                                    :class="formValidation.fields.description.valid == false ? 'border-co-red border-2' : 'border-gray-300'"
 | 
				
			||||||
 | 
					                                    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>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        {{ $fieldName := "address" }}
 | 
				
			||||||
 | 
					                        {{ template "address_autocomplete" dict "FieldName" $fieldName }}
 | 
				
			||||||
 | 
					                    </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">Planification</h3>
 | 
				
			||||||
 | 
					                    <p class="mt-1 text-sm text-gray-500">Dates et horaires de l'événement</p>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <div class="mt-5 space-y-6 md:mt-0 md:col-span-2 align-middle">
 | 
				
			||||||
 | 
					                    <div class="grid grid-cols-6 gap-6">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        <div class="col-span-6">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                            <button type="button" class="relative inline-flex h-6 w-11 flex-shrink-0 cursor-pointer rounded-full border-2 border-transparent transition-colors duration-200 ease-in-out focus:outline-none focus:ring-2 focus:ring-co-blue focus:ring-offset-2" role="switch" aria-checked="false"
 | 
				
			||||||
 | 
					                                :class="fields.allday ? 'bg-co-blue' : 'bg-gray-200'"
 | 
				
			||||||
 | 
					                                @click="fields.allday = ! fields.allday">
 | 
				
			||||||
 | 
					                                <span class="sr-only">Use setting</span>
 | 
				
			||||||
 | 
					                                <!-- Enabled: "translate-x-5", Not Enabled: "translate-x-0" -->
 | 
				
			||||||
 | 
					                                <span aria-hidden="true" class="pointer-events-none inline-block h-5 w-5 transform rounded-full bg-white shadow ring-0 transition duration-200 ease-in-out"
 | 
				
			||||||
 | 
					                                    :class="fields.allday ? 'translate-x-5' : 'translate-x-0'"></span>
 | 
				
			||||||
 | 
					                            </button> <span class="text-md font-medium text-gray-700 ml-2">Toute la journée</span>
 | 
				
			||||||
 | 
					                            <input type="hidden" name="allday" x-model="fields.allday">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        <div class="sm:col-span-6">
 | 
				
			||||||
 | 
					                            <div class="inline-flex w-full">
 | 
				
			||||||
 | 
					                                <div class="flex-1">
 | 
				
			||||||
 | 
					                                    <label for="startdate" class="block text-sm font-medium text-gray-700">Date de début</label>
 | 
				
			||||||
 | 
					                                    <input type="date" name="startdate" id="startdate" placeholder="JJ/MM/AAAA"
 | 
				
			||||||
 | 
					                                            class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm rounded-l-2xl"
 | 
				
			||||||
 | 
					                                            x-model="fields.startdate" @blur="validateField('startdate')"
 | 
				
			||||||
 | 
					                                            :class="formValidation.fields.startdate.valid == false ? 'border-co-red border-2' : 'border-gray-300'">
 | 
				
			||||||
 | 
					                                </div>
 | 
				
			||||||
 | 
					                                <div class="flex-1">
 | 
				
			||||||
 | 
					                                    <label for="enddate" class="block text-sm font-medium text-gray-700">Date de fin</label>
 | 
				
			||||||
 | 
					                                    <input type="date" name="enddate" id="enddate" placeholder="JJ/MM/AAAA"
 | 
				
			||||||
 | 
					                                            class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm rounded-r-2xl"
 | 
				
			||||||
 | 
					                                            x-model="fields.enddate" @blur="validateField('enddate')"
 | 
				
			||||||
 | 
					                                            :class="formValidation.fields.enddate.valid == false ? 'border-co-red border-2' : 'border-gray-300'">
 | 
				
			||||||
 | 
					                                </div>
 | 
				
			||||||
 | 
					                                
 | 
				
			||||||
 | 
					                                
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                        </div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                        <div class="sm:col-span-6" x-show="!fields.allday">
 | 
				
			||||||
 | 
					                            <div class="inline-flex w-full">
 | 
				
			||||||
 | 
					                                <div class="flex-1">
 | 
				
			||||||
 | 
					                                    <label for="startdate" class="block text-sm font-medium text-gray-700">Horaire de début</label>
 | 
				
			||||||
 | 
					                                    <input type="time" name="starttime" id="starttime" placeholder="00:00"
 | 
				
			||||||
 | 
					                                            class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm rounded-l-2xl"
 | 
				
			||||||
 | 
					                                            x-model="fields.starttime" @blur="validateField('starttime')"
 | 
				
			||||||
 | 
					                                            :class="formValidation.fields.starttime.valid == false ? 'border-co-red border-2' : 'border-gray-300'">
 | 
				
			||||||
 | 
					                                </div>
 | 
				
			||||||
 | 
					                                <div class="flex-1">
 | 
				
			||||||
 | 
					                                    <label for="endtime" class="block text-sm font-medium text-gray-700">Horaire de fin</label>
 | 
				
			||||||
 | 
					                                    <input type="time" name="endtime" id="endtime" placeholder="00:00"
 | 
				
			||||||
 | 
					                                            class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm rounded-r-2xl"
 | 
				
			||||||
 | 
					                                            x-model="fields.endtime" @blur="validateField('endtime')"
 | 
				
			||||||
 | 
					                                            :class="formValidation.fields.endtime.valid == false ? 'border-co-red border-2' : 'border-gray-300'">
 | 
				
			||||||
 | 
					                                </div>
 | 
				
			||||||
 | 
					                                
 | 
				
			||||||
 | 
					                                
 | 
				
			||||||
 | 
					                            </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 du dispositift (nombre de places disponibles, etc...)</p>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                <div class="mt-5 space-y-6 md:mt-0 md:col-span-2 align-middle">
 | 
				
			||||||
 | 
					                    <div class="grid grid-cols-6 gap-6">
 | 
				
			||||||
 | 
					                        <div class="col-span-6 sm:col-span-3">
 | 
				
			||||||
 | 
					                            <label for="max_subscribers" class="block text-sm font-medium text-gray-700">Places disponibles (0 = illimité)</label>
 | 
				
			||||||
 | 
					                            <input type="number" name="max_subscribers" id="max_subscribers"
 | 
				
			||||||
 | 
					                                class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm  rounded-2xl"
 | 
				
			||||||
 | 
					                                x-model="fields.max_subscribers" @blur="validateField('max_subscribers')"
 | 
				
			||||||
 | 
					                                :class="formValidation.fields.max_subscribers.valid == false ? 'border-co-red border-2' : 'border-gray-300'">
 | 
				
			||||||
 | 
					                        </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/agenda/">
 | 
				
			||||||
 | 
					                <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</button>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </form>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{{end}}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,140 @@
 | 
				
			||||||
 | 
					{{ 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>
 | 
				
			||||||
 | 
					                <h1 class="text-2xl font-bold text-gray-900">{{.ViewState.event.Name}}</h1>
 | 
				
			||||||
 | 
					                <p class="text-m font-medium text-gray-500">
 | 
				
			||||||
 | 
					                    {{if eq .ViewState.event.Startdate .ViewState.event.Enddate}}
 | 
				
			||||||
 | 
					                    Le {{(timeFrom .ViewState.event.Startdate).Format "02/01/2006"}}
 | 
				
			||||||
 | 
					                    {{else}}
 | 
				
			||||||
 | 
					                    Du {{(timeFrom .ViewState.event.Startdate).Format "02/01/2006"}} au {{(timeFrom .ViewState.event.Enddate).Format "02/01/2006"}}
 | 
				
			||||||
 | 
					                    {{end}}
 | 
				
			||||||
 | 
					                </p>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </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="event-information-title">
 | 
				
			||||||
 | 
					                <div class="bg-white shadow sm:rounded-lg">
 | 
				
			||||||
 | 
					                    <div class="px-4 py-5 sm:px-6">
 | 
				
			||||||
 | 
					                        <h2 id="event-information-title" class="text-lg leading-6 font-medium text-gray-900">Informations</h2>
 | 
				
			||||||
 | 
					                        <p class="mt-1 max-w-2xl text-sm text-gray-500">Informations sur le dispositif.</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.event.Type}}
 | 
				
			||||||
 | 
					                            <div class="sm:col-span-1">
 | 
				
			||||||
 | 
					                                <dt class="text-sm font-medium text-gray-500">Type</dt>
 | 
				
			||||||
 | 
					                                <dd class="mt-1 text-sm text-gray-900">{{.ViewState.event.Type}}</dd>
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                            {{end}}
 | 
				
			||||||
 | 
					                            {{if .ViewState.group}}
 | 
				
			||||||
 | 
					                            <div class="sm:col-span-1">
 | 
				
			||||||
 | 
					                                <dt class="text-sm font-medium text-gray-500">Structure gestionnaire</dt>
 | 
				
			||||||
 | 
					                                <dd class="mt-1 text-sm text-gray-900">{{.ViewState.group.Data.name}}</dd>
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                            {{end}}
 | 
				
			||||||
 | 
					                            {{if .ViewState.event.MaxSubscribers}}
 | 
				
			||||||
 | 
					                            <div class="sm:col-span-1">
 | 
				
			||||||
 | 
					                                <dt class="text-sm font-medium text-gray-500">Total places</dt>
 | 
				
			||||||
 | 
					                                <dd class="mt-1 text-sm text-gray-900">{{.ViewState.event.MaxSubscribers}}</dd>
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                            {{end}}
 | 
				
			||||||
 | 
					                            {{if ne .ViewState.event.MaxSubscribers 0}}
 | 
				
			||||||
 | 
					                            <div class="sm:col-span-1">
 | 
				
			||||||
 | 
					                                <dt class="text-sm font-medium text-gray-500">Places restantes</dt>
 | 
				
			||||||
 | 
					                                <dd class="mt-1 text-sm text-gray-900">{{.ViewState.event.RemainingSubscriptions}}</dd>
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                            {{end}}
 | 
				
			||||||
 | 
					                            {{if .ViewState.event.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.event.Data.address.properties.label}}</dd>
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                            {{end}}
 | 
				
			||||||
 | 
					                            {{if .ViewState.event.Description}}
 | 
				
			||||||
 | 
					                            <div class="sm:col-span-2">
 | 
				
			||||||
 | 
					                                <dt class="text-sm font-medium text-gray-500">Description</dt>
 | 
				
			||||||
 | 
					                                <dd class="mt-1 text-sm text-gray-900">{{.ViewState.event.Description}}</dd>
 | 
				
			||||||
 | 
					                            </div>
 | 
				
			||||||
 | 
					                            {{end}}
 | 
				
			||||||
 | 
					                        </dl>
 | 
				
			||||||
 | 
					                    </div>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </section>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					        <section aria-labelledby="subscribers-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="subscribers-title" class="text-lg font-medium text-gray-900">Inscrire un bénéficiaire</h2>
 | 
				
			||||||
 | 
					                {{if gt .ViewState.event.RemainingSubscriptions 0}}
 | 
				
			||||||
 | 
					                <form class="mt-4" action="/app/agenda/{{.ViewState.event.ID}}/subscribe" method="POST">
 | 
				
			||||||
 | 
					                    <div class="relative mt-1 mb-4"  x-data="{
 | 
				
			||||||
 | 
					                        text: '',
 | 
				
			||||||
 | 
					                        beneficiariesListOpen: false,
 | 
				
			||||||
 | 
					                        beneficiaries: {{json .ViewState.beneficiaries}},
 | 
				
			||||||
 | 
					                        filteredBeneficiaries: (text) => {
 | 
				
			||||||
 | 
					                            if(text=='') return beneficiaries
 | 
				
			||||||
 | 
					                            return this.beneficiaries.filter(b => b['data']['first_name'].includes(text) || b['data']['last_name'].includes(text))
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                        fields: {
 | 
				
			||||||
 | 
					                            beneficiaryid: {{if .ViewState.search}}'{{.ViewState.search.beneficiary.ID}}'{{else}}null{{end}},
 | 
				
			||||||
 | 
					                        },
 | 
				
			||||||
 | 
					                        selectbeneficiary(beneficiary) {
 | 
				
			||||||
 | 
					                            console.log(beneficiary)
 | 
				
			||||||
 | 
					                            this.fields.beneficiaryid = beneficiary.id 
 | 
				
			||||||
 | 
					                            this.text = beneficiary.data.first_name + ' ' + beneficiary.data.last_name
 | 
				
			||||||
 | 
					                            this.beneficiariesListOpen = false
 | 
				
			||||||
 | 
					                        }
 | 
				
			||||||
 | 
					                    }">
 | 
				
			||||||
 | 
					                        <input @focus="beneficiariesListOpen = true" x-model="text" id="combobox" type="text" class="w-full rounded-2xl border border-gray-300 bg-white py-2 pl-3 pr-12 shadow-sm focus:border-co-blue focus:outline-none focus:ring-1 focus:ring-co-blue sm:text-sm" role="combobox" aria-controls="options" aria-expanded="false">
 | 
				
			||||||
 | 
					                        
 | 
				
			||||||
 | 
					                        <button @click="beneficiariesListOpen = ! beneficiariesListOpen" type="button" class="absolute inset-y-0 right-0 flex items-center rounded-r-2xl px-2 focus:outline-none">
 | 
				
			||||||
 | 
					                          <!-- Heroicon name: solid/selector -->
 | 
				
			||||||
 | 
					                          <svg class="h-5 w-5 text-gray-400" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
 | 
				
			||||||
 | 
					                            <path fill-rule="evenodd" d="M10 3a1 1 0 01.707.293l3 3a1 1 0 01-1.414 1.414L10 5.414 7.707 7.707a1 1 0 01-1.414-1.414l3-3A1 1 0 0110 3zm-3.707 9.293a1 1 0 011.414 0L10 14.586l2.293-2.293a1 1 0 011.414 1.414l-3 3a1 1 0 01-1.414 0l-3-3a1 1 0 010-1.414z" clip-rule="evenodd" />
 | 
				
			||||||
 | 
					                          </svg>
 | 
				
			||||||
 | 
					                        </button>
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
 | 
					                        <ul x-show="beneficiariesListOpen" class="absolute z-10 mt-1 max-h-60 w-full overflow-auto rounded-xl bg-white py-1 text-base shadow-lg ring-1 ring-black ring-opacity-5 focus:outline-none sm:text-sm" id="options" role="listbox">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                          <template x-for="beneficiary in beneficiaries">
 | 
				
			||||||
 | 
					                              <li @click="selectbeneficiary(beneficiary)" class="relative cursor-default hover:bg-gray-100 select-none py-2 pl-3 pr-9 text-gray-900" id="option-0" role="option" tabindex="-1">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                              <span class="truncate" x-text="beneficiary.data.first_name"></span> <span class="truncate" x-text="beneficiary.data.last_name"></span>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                              <span class="absolute inset-y-0 right-0 flex items-center pr-4 text-co-blue">
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                              </span>
 | 
				
			||||||
 | 
					                              </li>
 | 
				
			||||||
 | 
					                          </template>
 | 
				
			||||||
 | 
					                        </ul>
 | 
				
			||||||
 | 
					                        <input type="hidden" name="subscriber" x-model="fields.beneficiaryid">
 | 
				
			||||||
 | 
					                      </div>
 | 
				
			||||||
 | 
					                      <button type="submit"
 | 
				
			||||||
 | 
					                            class="rounded-2xl border border-transparent bg-co-blue px-4 py-2 w-full 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">
 | 
				
			||||||
 | 
					                            Inscrire le bénéficiaire
 | 
				
			||||||
 | 
					                        </button>
 | 
				
			||||||
 | 
					                </form>
 | 
				
			||||||
 | 
					                {{else}}
 | 
				
			||||||
 | 
					                <p class="p-12 text-gray-500 text-center text-md">Il n'y a plus de place disponible</p>
 | 
				
			||||||
 | 
					                {{end}}
 | 
				
			||||||
 | 
					                {{if .ViewState.subscribers}}
 | 
				
			||||||
 | 
					                <h2 id="subscribers-title" class="text-lg font-medium text-gray-900 mt-10">Inscrits</h2>
 | 
				
			||||||
 | 
					                <div class="mt-2">
 | 
				
			||||||
 | 
					                    {{range .ViewState.subscribers}}
 | 
				
			||||||
 | 
					                    <ul class="p-1">
 | 
				
			||||||
 | 
					                        <a href="/app/beneficiaries/{{.ID}}">
 | 
				
			||||||
 | 
					                        <li class="inline-flex text-sm p-2"><img class="h-6 w-6 rounded-co mr-2" src="/app/beneficiaries/{{.ID}}/picture"> {{.Data.first_name}} {{.Data.last_name}}</li>
 | 
				
			||||||
 | 
					                        </a>
 | 
				
			||||||
 | 
					                    </ul>
 | 
				
			||||||
 | 
					                    {{end}}
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					                {{end}}
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </section>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</main>
 | 
				
			||||||
 | 
					{{ end }}
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,110 @@
 | 
				
			||||||
 | 
					{{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">Agenda dispositifs</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/agenda/create-event">
 | 
				
			||||||
 | 
					                <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 dispositif
 | 
				
			||||||
 | 
					                </button>
 | 
				
			||||||
 | 
					            </a>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<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="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 sm:pl-6">
 | 
				
			||||||
 | 
					                                    Type de dispositif
 | 
				
			||||||
 | 
					                                </th>
 | 
				
			||||||
 | 
					                                <th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 sm:pl-6">
 | 
				
			||||||
 | 
					                                    Structure
 | 
				
			||||||
 | 
					                                </th>
 | 
				
			||||||
 | 
					                                <th scope="col" class="px-3 py-3.5 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 sm:pl-6">
 | 
				
			||||||
 | 
					                                    Lieu
 | 
				
			||||||
 | 
					                                </th>
 | 
				
			||||||
 | 
					                                <th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 sm:pl-6">
 | 
				
			||||||
 | 
					                                    Dates
 | 
				
			||||||
 | 
					                                </th>
 | 
				
			||||||
 | 
					                                <th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 sm:pl-6">
 | 
				
			||||||
 | 
					                                    Places disponibles
 | 
				
			||||||
 | 
					                                </th>
 | 
				
			||||||
 | 
					                                <th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 sm:pl-6">
 | 
				
			||||||
 | 
					                                    Bénéficiaires positionnés
 | 
				
			||||||
 | 
					                                </th>
 | 
				
			||||||
 | 
					                                <th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6">
 | 
				
			||||||
 | 
					                                    <span class="sr-only">Actions</span>
 | 
				
			||||||
 | 
					                                </th>
 | 
				
			||||||
 | 
					                            </tr>
 | 
				
			||||||
 | 
					                            <tbody class="divide-y divide-gray-200 bg-white">
 | 
				
			||||||
 | 
					                                {{range .ViewState.events}}
 | 
				
			||||||
 | 
					                                <tr>
 | 
				
			||||||
 | 
					                                    <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
 | 
				
			||||||
 | 
					                                        <div class="text-gray-900" >{{.Type}}</div>
 | 
				
			||||||
 | 
					                                    </td>
 | 
				
			||||||
 | 
					                                    <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                                        <div class="text-gray-900" >
 | 
				
			||||||
 | 
					                                            {{range .Owners}}
 | 
				
			||||||
 | 
					                                            {{if (index $.ViewState.groups .)}}
 | 
				
			||||||
 | 
					                                                {{(index $.ViewState.groups .).Data.name}}
 | 
				
			||||||
 | 
					                                            {{end}}
 | 
				
			||||||
 | 
					                                            {{end}}
 | 
				
			||||||
 | 
					                                        </div>
 | 
				
			||||||
 | 
					                                    </td>
 | 
				
			||||||
 | 
					                                    <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
 | 
				
			||||||
 | 
					                                        <div class="text-gray-900" >{{.Name}}</div>
 | 
				
			||||||
 | 
					                                    </td>
 | 
				
			||||||
 | 
					                                    <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
 | 
				
			||||||
 | 
					                                        <div class="text-gray-900" >{{if .Data.address}}{{.Data.address.properties.label}}{{end}}</div>
 | 
				
			||||||
 | 
					                                    </td>
 | 
				
			||||||
 | 
					                                    <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
 | 
				
			||||||
 | 
					                                        <div class="text-gray-900" >
 | 
				
			||||||
 | 
					                                            {{if eq .Startdate .Enddate}}
 | 
				
			||||||
 | 
					                                            Le {{(timeFrom .Startdate).Format "02/01/2006"}}
 | 
				
			||||||
 | 
					                                            {{else}}
 | 
				
			||||||
 | 
					                                            Du {{(timeFrom .Startdate).Format "02/01/2006"}} <br />Au {{(timeFrom .Enddate).Format "02/01/2006"}}
 | 
				
			||||||
 | 
					                                            {{end}}
 | 
				
			||||||
 | 
					                                        </div>
 | 
				
			||||||
 | 
					                                    </td>
 | 
				
			||||||
 | 
					                                    <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
 | 
				
			||||||
 | 
					                                        <div class="text-gray-900" >{{.RemainingSubscriptions}}</div>
 | 
				
			||||||
 | 
					                                    </td>
 | 
				
			||||||
 | 
					                                    <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
 | 
				
			||||||
 | 
					                                        <div class="flex -space-x-1 overflow-hidden" >
 | 
				
			||||||
 | 
					                                            {{range .Subscribers}}
 | 
				
			||||||
 | 
					                                            <img class="inline-block h-6 w-6 rounded-co ring-2 ring-white" src="/app/beneficiaries/{{.}}/picture" >
 | 
				
			||||||
 | 
					                                            {{end}}
 | 
				
			||||||
 | 
					                                        </div>
 | 
				
			||||||
 | 
					                                    </td>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                                    <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
 | 
				
			||||||
 | 
					                                        <a href="/app/agenda/{{.ID}}" class="text-co-blue hover:text-co-blue">Voir</a>
 | 
				
			||||||
 | 
					                                    </td>
 | 
				
			||||||
 | 
					                                </tr>
 | 
				
			||||||
 | 
					                                {{end}}
 | 
				
			||||||
 | 
					                            </tbody>
 | 
				
			||||||
 | 
					                        </thead>
 | 
				
			||||||
 | 
					                    </table>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					{{end}}
 | 
				
			||||||
| 
						 | 
					@ -1,8 +1,16 @@
 | 
				
			||||||
{{define "beneficiary_vehicles"}}
 | 
					{{define "beneficiary_vehicles"}}
 | 
				
			||||||
<div class="px-4 py-6 sm:px-6">
 | 
					<div class="px-4 py-6 sm:px-6">
 | 
				
			||||||
 | 
					    {{if .ViewState.bookings}}
 | 
				
			||||||
 | 
					    <h3 class="text-lg">Mises à disposition réalisées</h3>
 | 
				
			||||||
 | 
					    <ul class="my-8">
 | 
				
			||||||
 | 
					        {{range .ViewState.bookings}}
 | 
				
			||||||
 | 
					        <li class="text-sm">Du {{(timeFrom .Startdate).Format "02/01/2006"}} au {{(timeFrom .Enddate).Format "02/01/2006"}}</li>
 | 
				
			||||||
 | 
					        {{end}}
 | 
				
			||||||
 | 
					    </ul>
 | 
				
			||||||
 | 
					    {{end}}
 | 
				
			||||||
    <h3 class="text-lg">Réserver un véhicule</h3>
 | 
					    <h3 class="text-lg">Réserver un véhicule</h3>
 | 
				
			||||||
    <form method="GET" action="/app/vehicles/">
 | 
					    <form method="GET" action="/app/vehicles/">
 | 
				
			||||||
        <input type="hidden" name="beneficiaryid" value="{{.ViewState.ID}}">
 | 
					        <input type="hidden" name="beneficiaryid" value="{{.ViewState.beneficiary.ID}}">
 | 
				
			||||||
        <div class="py-4 grid grid-cols-2">
 | 
					        <div class="py-4 grid grid-cols-2">
 | 
				
			||||||
            <div class="lg:col-span-1">
 | 
					            <div class="lg:col-span-1">
 | 
				
			||||||
                <label for="startdate" class="block text-sm font-medium text-gray-700">Du</label>
 | 
					                <label for="startdate" class="block text-sm font-medium text-gray-700">Du</label>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5,24 +5,24 @@
 | 
				
			||||||
        <div class="flex items-center space-x-5">
 | 
					        <div class="flex items-center space-x-5">
 | 
				
			||||||
            <div class="flex-shrink-0">
 | 
					            <div class="flex-shrink-0">
 | 
				
			||||||
                <div class="relative">
 | 
					                <div class="relative">
 | 
				
			||||||
                    <img class="h-16 w-16 rounded-co" src="/app/beneficiaries/{{.ViewState.ID}}/picture" alt="">
 | 
					                    <img class="h-16 w-16 rounded-co" src="/app/beneficiaries/{{.ViewState.beneficiary.ID}}/picture" alt="">
 | 
				
			||||||
                    <span class="absolute inset-0 shadow-inner rounded-full" aria-hidden="true"></span>
 | 
					                    <span class="absolute inset-0 shadow-inner rounded-full" aria-hidden="true"></span>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
            <div>
 | 
					            <div>
 | 
				
			||||||
                <h1 class="text-2xl font-bold text-gray-900">{{.ViewState.Data.first_name}}
 | 
					                <h1 class="text-2xl font-bold text-gray-900">{{.ViewState.beneficiary.Data.first_name}}
 | 
				
			||||||
                    {{.ViewState.Data.last_name}}</h1>
 | 
					                    {{.ViewState.beneficiary.Data.last_name}}</h1>
 | 
				
			||||||
                <p class="text-sm font-medium text-gray-500">{{if .ViewState.Metadata.created}}Ajouté le <time
 | 
					                <p class="text-sm font-medium text-gray-500">{{if .ViewState.beneficiary.Metadata.created}}Ajouté le <time
 | 
				
			||||||
                        datetime="2022-07-25">{{.ViewState.Metadata.created}}</time> par
 | 
					                        datetime="2022-07-25">{{.ViewState.beneficiary.Metadata.created}}</time> par
 | 
				
			||||||
                    <a href="#" class="text-gray-900">Conseiller 1</a>{{end}}
 | 
					                    <a href="#" class="text-gray-900">Conseiller 1</a>{{end}}
 | 
				
			||||||
                </p>
 | 
					                </p>
 | 
				
			||||||
            </div>
 | 
					            </div>
 | 
				
			||||||
        </div>
 | 
					        </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">
 | 
					            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"
 | 
					            <!-- <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>
 | 
					                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"
 | 
					            <a href="/app/beneficiaries/{{.ViewState.beneficiary.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>
 | 
					                    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>
 | 
					    </div>
 | 
				
			||||||
| 
						 | 
					@ -38,44 +38,44 @@
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                    <div class="border-t border-gray-200 px-4 py-5 sm:px-6">
 | 
					                    <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">
 | 
					                        <dl class="grid grid-cols-1 gap-x-4 gap-y-8 sm:grid-cols-2">
 | 
				
			||||||
                            {{if .ViewState.Data.email}}
 | 
					                            {{if .ViewState.beneficiary.Data.email}}
 | 
				
			||||||
                            <div class="sm:col-span-1">
 | 
					                            <div class="sm:col-span-1">
 | 
				
			||||||
                                <dt class="text-sm font-medium text-gray-500">Email</dt>
 | 
					                                <dt class="text-sm font-medium text-gray-500">Email</dt>
 | 
				
			||||||
                                <dd class="mt-1 text-sm text-gray-900">{{.ViewState.Data.email}}</dd>
 | 
					                                <dd class="mt-1 text-sm text-gray-900">{{.ViewState.beneficiary.Data.email}}</dd>
 | 
				
			||||||
                            </div>
 | 
					                            </div>
 | 
				
			||||||
                            {{end}}
 | 
					                            {{end}}
 | 
				
			||||||
                            {{if .ViewState.Data.phone_number}}
 | 
					                            {{if .ViewState.beneficiary.Data.phone_number}}
 | 
				
			||||||
                            <div class="sm:col-span-1">
 | 
					                            <div class="sm:col-span-1">
 | 
				
			||||||
                                <dt class="text-sm font-medium text-gray-500">Téléphone</dt>
 | 
					                                <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>
 | 
					                                <dd class="mt-1 text-sm text-gray-900">{{.ViewState.beneficiary.Data.phone_number}}</dd>
 | 
				
			||||||
                            </div>
 | 
					                            </div>
 | 
				
			||||||
                            {{end}}
 | 
					                            {{end}}
 | 
				
			||||||
                            {{if .ViewState.Data.birthdate}}
 | 
					                            {{if .ViewState.beneficiary.Data.birthdate}}
 | 
				
			||||||
                            <div class="sm:col-span-1">
 | 
					                            <div class="sm:col-span-1">
 | 
				
			||||||
                                <dt class="text-sm font-medium text-gray-500">Date de naissance</dt>
 | 
					                                <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
 | 
					                                <dd class="mt-1 text-sm text-gray-900">{{(timeFrom .ViewState.beneficiary.Data.birthdate).Format
 | 
				
			||||||
                                    "02/01/2006"}}</dd>
 | 
					                                    "02/01/2006"}}</dd>
 | 
				
			||||||
                            </div>
 | 
					                            </div>
 | 
				
			||||||
                            {{end}}
 | 
					                            {{end}}
 | 
				
			||||||
                            {{if and .ViewState.Data.gender (ne .ViewState.Data.gender "0")}}
 | 
					                            {{if and .ViewState.beneficiary.Data.gender (ne .ViewState.beneficiary.Data.gender "0")}}
 | 
				
			||||||
                            <div class="sm:col-span-1">
 | 
					                            <div class="sm:col-span-1">
 | 
				
			||||||
                                <dt class="text-sm font-medium text-gray-500">Genre</dt>
 | 
					                                <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>
 | 
					                                <dd class="mt-1 text-sm text-gray-900">{{genderISO5218 .ViewState.beneficiary.Data.gender}}</dd>
 | 
				
			||||||
                            </div>
 | 
					                            </div>
 | 
				
			||||||
                            {{end}}
 | 
					                            {{end}}
 | 
				
			||||||
                            {{if .ViewState.Data.address}}
 | 
					                            {{if .ViewState.beneficiary.Data.address}}
 | 
				
			||||||
                            <div class="sm:col-span-1">
 | 
					                            <div class="sm:col-span-1">
 | 
				
			||||||
                                <dt class="text-sm font-medium text-gray-500">Adresse</dt>
 | 
					                                <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>
 | 
					                                <dd class="mt-1 text-sm text-gray-900">{{.ViewState.beneficiary.Data.address.properties.label}}</dd>
 | 
				
			||||||
                            </div>
 | 
					                            </div>
 | 
				
			||||||
                            {{end}}
 | 
					                            {{end}}
 | 
				
			||||||
 | 
					                        </dl>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </section>
 | 
					            </section>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            <section aria-labelledby="functionalities-title" x-data="{
 | 
					            <section aria-labelledby="functionalities-title" x-data="{
 | 
				
			||||||
                    tab: 'notes',
 | 
					                    tab: 'vehicles',
 | 
				
			||||||
                    to(event) {
 | 
					                    to(event) {
 | 
				
			||||||
                        this.tab = event.target.value
 | 
					                        this.tab = event.target.value
 | 
				
			||||||
                    }
 | 
					                    }
 | 
				
			||||||
| 
						 | 
					@ -87,7 +87,7 @@
 | 
				
			||||||
                                <label for="tabs" class="sr-only">Select a tab</label>
 | 
					                                <label for="tabs" class="sr-only">Select a tab</label>
 | 
				
			||||||
                                <select id="tabs" name="tabs" @change="to"
 | 
					                                <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">
 | 
					                                    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="notes">Notes</option> -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                    <option value="journeys">Déplacements</option>
 | 
					                                    <option value="journeys">Déplacements</option>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -100,10 +100,10 @@
 | 
				
			||||||
                                <div class="border-b border-gray-200 pl-4">
 | 
					                                <div class="border-b border-gray-200 pl-4">
 | 
				
			||||||
                                    <nav class="-mb-px flex space-x-8" aria-label="Tabs">
 | 
					                                    <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" -->
 | 
					                                        <!-- 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'"
 | 
					                                        <!-- <a href="#" @click="tab = 'notes'"
 | 
				
			||||||
                                            class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
 | 
					                                            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'">
 | 
					                                            :class="tab == 'notes' ? 'border-co-blue text-co-blue' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'">
 | 
				
			||||||
                                            Notes </a>
 | 
					                                            Notes </a> -->
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                                        <a href="#" @click="tab = 'journeys'"
 | 
					                                        <a href="#" @click="tab = 'journeys'"
 | 
				
			||||||
                                            class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
 | 
					                                            class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
 | 
				
			||||||
| 
						 | 
					@ -129,11 +129,11 @@
 | 
				
			||||||
                            </div>
 | 
					                            </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 == 'journeys'">{{template "beneficiary_journeys" .}}</div>
 | 
				
			||||||
                        <div x-show="tab == 'vehicles'">{{template "beneficiary_vehicles" .}}</div>
 | 
					                        <div x-show="tab == 'vehicles'">{{template "beneficiary_vehicles" .}}</div>
 | 
				
			||||||
                        <div x-show="tab == 'events'">{{template "beneficiary_events" .}}</div>
 | 
					                        <div x-show="tab == 'events'">{{template "beneficiary_events" .}}</div>
 | 
				
			||||||
                        <div x-show="tab == 'files'">{{template "beneficiary_files" .}}</div>
 | 
					                        <div x-show="tab == 'files'">{{template "beneficiary_files" .}}</div>
 | 
				
			||||||
 | 
					                        <div x-show="tab == 'notes'">{{template "beneficiary_notes" .}}</div>
 | 
				
			||||||
                    </div>
 | 
					                    </div>
 | 
				
			||||||
                </div>
 | 
					                </div>
 | 
				
			||||||
            </section>
 | 
					            </section>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -92,9 +92,24 @@
 | 
				
			||||||
                                <div class="sm:pb-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
					                                <div class="sm:pb-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
				
			||||||
                                    <dt class="text-sm font-medium text-gray-500">Gestionnaire</dt>
 | 
					                                    <dt class="text-sm font-medium text-gray-500">Gestionnaire</dt>
 | 
				
			||||||
                                    <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
 | 
					                                    <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
 | 
				
			||||||
                                        COOPGO
 | 
					                                        {{.ViewState.group.Data.name}}
 | 
				
			||||||
                                    </dd>
 | 
					                                    </dd>
 | 
				
			||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
 | 
					                                {{if .ViewState.booking.Data.booked_by}}
 | 
				
			||||||
 | 
					                                <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
				
			||||||
 | 
					                                <!-- <div class="sm:pb-5 sm:grid sm:grid-cols-3 sm:gap-4"> -->
 | 
				
			||||||
 | 
					                                    <dt class="text-sm font-medium text-gray-500">Réservé par</dt>
 | 
				
			||||||
 | 
					                                    <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
 | 
				
			||||||
 | 
					                                        {{if .ViewState.booking.Data.booked_by.user}}
 | 
				
			||||||
 | 
					                                            <a href="/app/members/{{.ViewState.booking.Data.booked_by.user.id}}" class="flex inline">
 | 
				
			||||||
 | 
					                                                <img class="h-5 w-5 rounded-co mr-1"
 | 
				
			||||||
 | 
					                                                    src="/app/members/{{.ViewState.booking.Data.booked_by.user.id}}/picture" alt="">
 | 
				
			||||||
 | 
					                                                {{.ViewState.booking.Data.booked_by.user.display_name}}
 | 
				
			||||||
 | 
					                                            </a>
 | 
				
			||||||
 | 
					                                        {{end}}
 | 
				
			||||||
 | 
					                                    </dd>
 | 
				
			||||||
 | 
					                                </div>
 | 
				
			||||||
 | 
					                                {{end}}
 | 
				
			||||||
                                <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
					                                <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
				
			||||||
                                    <dt class="text-sm font-medium text-gray-500">Véhicule</dt>
 | 
					                                    <dt class="text-sm font-medium text-gray-500">Véhicule</dt>
 | 
				
			||||||
                                    <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
 | 
					                                    <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
 | 
				
			||||||
| 
						 | 
					@ -122,7 +137,7 @@
 | 
				
			||||||
                                        "02/01/2006"}}</dd>
 | 
					                                        "02/01/2006"}}</dd>
 | 
				
			||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
                                <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
					                                <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
				
			||||||
                                    <dt class="text-sm font-medium text-gray-500">Date de fin</dt>
 | 
					                                    <dt class="text-sm font-medium text-gray-500">Date de retour</dt>
 | 
				
			||||||
                                    <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{(timeFrom .ViewState.booking.Enddate).Format
 | 
					                                    <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{(timeFrom .ViewState.booking.Enddate).Format
 | 
				
			||||||
                                        "02/01/2006"}}</dd>
 | 
					                                        "02/01/2006"}}</dd>
 | 
				
			||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -0,0 +1,68 @@
 | 
				
			||||||
 | 
					{{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">Réservations</h1>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<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 sm:pl-6">
 | 
				
			||||||
 | 
					                                    Type
 | 
				
			||||||
 | 
					                                </th>
 | 
				
			||||||
 | 
					                                <th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 sm:pl-6">
 | 
				
			||||||
 | 
					                                    Beneficiaire
 | 
				
			||||||
 | 
					                                </th>
 | 
				
			||||||
 | 
					                                <th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 sm:pl-6">
 | 
				
			||||||
 | 
					                                    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">
 | 
				
			||||||
 | 
					                            
 | 
				
			||||||
 | 
					                            {{range .ViewState.bookings}}
 | 
				
			||||||
 | 
					                            <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" >Voiture</div>
 | 
				
			||||||
 | 
					                                </td>
 | 
				
			||||||
 | 
					                                <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
 | 
				
			||||||
 | 
					                                    <div class="text-gray-900" ><img class="h-6 w-6 rounded-co"
 | 
				
			||||||
 | 
					                                        src="/app/beneficiaries/{{.Driver}}/picture" alt=""></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" >Du {{(timeFrom .Startdate).Format "02/01/2006"}} au {{(timeFrom .Enddate).Format "02/01/2006"}}</div>
 | 
				
			||||||
 | 
					                                </td>
 | 
				
			||||||
 | 
					                                <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
 | 
				
			||||||
 | 
					                                    <a href="/app/vehicles/bookings/{{.ID}}"
 | 
				
			||||||
 | 
					                                            class="text-co-blue hover:text-co-blue">Voir</a>
 | 
				
			||||||
 | 
					                                </td>
 | 
				
			||||||
 | 
					                            </tr>
 | 
				
			||||||
 | 
					                            {{end}}
 | 
				
			||||||
 | 
					                            
 | 
				
			||||||
 | 
					                        </tbody>
 | 
				
			||||||
 | 
					                    </table>
 | 
				
			||||||
 | 
					                </div>
 | 
				
			||||||
 | 
					            </div>
 | 
				
			||||||
 | 
					        </div>
 | 
				
			||||||
 | 
					    </div>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{{end}}
 | 
				
			||||||
| 
						 | 
					@ -7,7 +7,7 @@
 | 
				
			||||||
            <p class="mt-2 text-sm text-gray-700"></p>
 | 
					            <p class="mt-2 text-sm text-gray-700"></p>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
 | 
					        <div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
 | 
				
			||||||
            <a href="/app/vehicles-management/fleet/add">
 | 
					            <a href="/app/vehicles/bookings/">
 | 
				
			||||||
                <button type="button"
 | 
					                <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">
 | 
					                    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">
 | 
				
			||||||
                    Voir les prêts de véhicules
 | 
					                    Voir les prêts de véhicules
 | 
				
			||||||
| 
						 | 
					@ -33,7 +33,7 @@
 | 
				
			||||||
                            return this.beneficiaries.filter(b => b['data']['first_name'].includes(text) || b['data']['last_name'].includes(text))
 | 
					                            return this.beneficiaries.filter(b => b['data']['first_name'].includes(text) || b['data']['last_name'].includes(text))
 | 
				
			||||||
                        },
 | 
					                        },
 | 
				
			||||||
                        fields: {
 | 
					                        fields: {
 | 
				
			||||||
                            beneficiaryid: null,
 | 
					                            beneficiaryid: {{if .ViewState.search}}'{{.ViewState.search.beneficiary.ID}}'{{else}}null{{end}},
 | 
				
			||||||
                        },
 | 
					                        },
 | 
				
			||||||
                        selectbeneficiary(beneficiary) {
 | 
					                        selectbeneficiary(beneficiary) {
 | 
				
			||||||
                            console.log(beneficiary)
 | 
					                            console.log(beneficiary)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -46,7 +46,8 @@
 | 
				
			||||||
                                    <div class="text-gray-900" >{{$vehicle.Data.licence_plate}}</div>
 | 
					                                    <div class="text-gray-900" >{{$vehicle.Data.licence_plate}}</div>
 | 
				
			||||||
                                </td>
 | 
					                                </td>
 | 
				
			||||||
                                <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
 | 
					                                <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
 | 
				
			||||||
                                    <div class="text-gray-900" ></div>
 | 
					                                    <div class="text-gray-900" ><img class="h-6 w-6 rounded-co"
 | 
				
			||||||
 | 
					                                        src="/app/beneficiaries/{{.Driver}}/picture" alt=""></div>
 | 
				
			||||||
                                </td>
 | 
					                                </td>
 | 
				
			||||||
                                <!-- <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
 | 
					                                <!-- <td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
 | 
				
			||||||
                                    <div class="text-gray-900" >aa</div>
 | 
					                                    <div class="text-gray-900" >aa</div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -7,6 +7,10 @@
 | 
				
			||||||
            <p class="mt-2 text-sm text-gray-700"></p>
 | 
					            <p class="mt-2 text-sm text-gray-700"></p>
 | 
				
			||||||
        </div>
 | 
					        </div>
 | 
				
			||||||
        <div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
 | 
					        <div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
 | 
				
			||||||
 | 
					            <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">
 | 
				
			||||||
 | 
					                Changer de véhicule
 | 
				
			||||||
 | 
					            </button>
 | 
				
			||||||
            <a href="/app/vehicles-management/bookings/{{.ViewState.booking.ID}}/delete">
 | 
					            <a href="/app/vehicles-management/bookings/{{.ViewState.booking.ID}}/delete">
 | 
				
			||||||
                <button type="button"
 | 
					                <button type="button"
 | 
				
			||||||
                    class="inline-flex items-center justify-center rounded-2xl border border-transparent bg-co-red px-4 py-2 text-sm font-medium text-white shadow-sm focus:outline-none focus:ring-2 focus:ring-co-red focus:ring-offset-2 sm:w-auto">
 | 
					                    class="inline-flex items-center justify-center rounded-2xl border border-transparent bg-co-red px-4 py-2 text-sm font-medium text-white shadow-sm focus:outline-none focus:ring-2 focus:ring-co-red focus:ring-offset-2 sm:w-auto">
 | 
				
			||||||
| 
						 | 
					@ -58,7 +62,8 @@
 | 
				
			||||||
                                <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
					                                <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
				
			||||||
                                    <dt class="text-sm font-medium text-gray-500">Adresse</dt>
 | 
					                                    <dt class="text-sm font-medium text-gray-500">Adresse</dt>
 | 
				
			||||||
                                    <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
 | 
					                                    <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
 | 
				
			||||||
                                        {{.ViewState.Data.address.properties.label}}</dd>
 | 
					                                        {{.ViewState.Data.address.properties.label}}
 | 
				
			||||||
 | 
					                                    </dd>
 | 
				
			||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
                                {{end}}
 | 
					                                {{end}}
 | 
				
			||||||
                            </dl>
 | 
					                            </dl>
 | 
				
			||||||
| 
						 | 
					@ -89,12 +94,28 @@
 | 
				
			||||||
                    <div>
 | 
					                    <div>
 | 
				
			||||||
                        <div class="mt-5 border-gray-200">
 | 
					                        <div class="mt-5 border-gray-200">
 | 
				
			||||||
                            <dl class="sm:divide-y sm:divide-gray-200">
 | 
					                            <dl class="sm:divide-y sm:divide-gray-200">
 | 
				
			||||||
                                <div class="sm:pb-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
					                                <!-- <div class="sm:pb-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
				
			||||||
                                    <dt class="text-sm font-medium text-gray-500">Gestionnaire</dt>
 | 
					                                    <dt class="text-sm font-medium text-gray-500">Gestionnaire</dt>
 | 
				
			||||||
                                    <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
 | 
					                                    <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
 | 
				
			||||||
                                        COOPGO
 | 
					                                        COOPGO
 | 
				
			||||||
                                    </dd>
 | 
					                                    </dd>
 | 
				
			||||||
 | 
					                                </div> -->
 | 
				
			||||||
 | 
					                                {{if .ViewState.booking.Data.booked_by}}
 | 
				
			||||||
 | 
					                                <!-- <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4"> -->
 | 
				
			||||||
 | 
					                                <div class="sm:pb-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
				
			||||||
 | 
					                                    <dt class="text-sm font-medium text-gray-500">Prescripteur</dt>
 | 
				
			||||||
 | 
					                                    <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
 | 
				
			||||||
 | 
					                                        {{if .ViewState.booking.Data.booked_by.user}}
 | 
				
			||||||
 | 
					                                            <a href="/app/members/{{.ViewState.booking.Data.booked_by.user.id}}" class="flex inline">
 | 
				
			||||||
 | 
					                                                <img class="h-5 w-5 rounded-co mr-1"
 | 
				
			||||||
 | 
					                                                    src="/app/members/{{.ViewState.booking.Data.booked_by.user.id}}/picture" alt="">
 | 
				
			||||||
 | 
					                                                {{.ViewState.booking.Data.booked_by.user.display_name}}
 | 
				
			||||||
 | 
					                                            </a>
 | 
				
			||||||
 | 
					                                        {{end}}
 | 
				
			||||||
 | 
					                                        {{if .ViewState.booking.Data.booked_by.group}}{{.ViewState.booking.Data.booked_by.group.name}}{{end}}
 | 
				
			||||||
 | 
					                                    </dd>
 | 
				
			||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
 | 
					                                {{end}}
 | 
				
			||||||
                                <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
					                                <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
				
			||||||
                                    <dt class="text-sm font-medium text-gray-500">Véhicule</dt>
 | 
					                                    <dt class="text-sm font-medium text-gray-500">Véhicule</dt>
 | 
				
			||||||
                                    <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
 | 
					                                    <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
 | 
				
			||||||
| 
						 | 
					@ -118,23 +139,82 @@
 | 
				
			||||||
                                {{end}}
 | 
					                                {{end}}
 | 
				
			||||||
                                <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
					                                <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
				
			||||||
                                    <dt class="text-sm font-medium text-gray-500">Date de récupération</dt>
 | 
					                                    <dt class="text-sm font-medium text-gray-500">Date de récupération</dt>
 | 
				
			||||||
                                    <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{(timeFrom .ViewState.booking.Startdate).Format
 | 
					                                    <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2 inline-flex"
 | 
				
			||||||
                                        "02/01/2006"}}</dd>
 | 
					                                    x-data="{ updateOpen: false }">
 | 
				
			||||||
 | 
					                                    <div class="w-full inline-flex" x-show="!updateOpen">
 | 
				
			||||||
 | 
					                                        <div class="flex-1">{{(timeFrom .ViewState.booking.Startdate).Format "02/01/2006"}}</div>
 | 
				
			||||||
 | 
					                                        <a href="#" class="text-co-blue hover:text-co-blue ml-5" @click="updateOpen = ! updateOpen">Modifier</a>
 | 
				
			||||||
 | 
					                                    </div>
 | 
				
			||||||
 | 
					                                    <form method="POST" class="inline-flex" x-show="updateOpen">
 | 
				
			||||||
 | 
					                                        <div class="flex-1">
 | 
				
			||||||
 | 
					                                            <input type="date" name="startdate" value="{{(timeFrom .ViewState.booking.Startdate).Format "2006-01-02"}}"
 | 
				
			||||||
 | 
					                                            class="shadow-sm focus:ring-co-blue focus:border-co-blue block sm:text-sm border-gray-300 rounded-2xl">
 | 
				
			||||||
 | 
					                                        </div>
 | 
				
			||||||
 | 
					                                        <button 
 | 
				
			||||||
 | 
					                                            class=" justify-center text-co-blue px-4">
 | 
				
			||||||
 | 
					                                            OK
 | 
				
			||||||
 | 
					                                        </button>
 | 
				
			||||||
 | 
					                                    </form>
 | 
				
			||||||
 | 
					                                    </dd>
 | 
				
			||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
                                <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
					                                <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
				
			||||||
                                    <dt class="text-sm font-medium text-gray-500">Date de fin</dt>
 | 
					                                    <dt class="text-sm font-medium text-gray-500">Date de retour</dt>
 | 
				
			||||||
                                    <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{(timeFrom .ViewState.booking.Enddate).Format
 | 
					                                    <dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2"
 | 
				
			||||||
                                        "02/01/2006"}}</dd>
 | 
					                                        x-data="{ updateOpen: false }">
 | 
				
			||||||
 | 
					                                        <div class="w-full inline-flex" x-show="!updateOpen">
 | 
				
			||||||
 | 
					                                            <div class="flex-1">{{(timeFrom .ViewState.booking.Enddate).Format "02/01/2006"}}</div>
 | 
				
			||||||
 | 
					                                            <a href="#" class="text-co-blue hover:text-co-blue ml-5" @click="updateOpen = ! updateOpen">Modifier</a>
 | 
				
			||||||
 | 
					                                        </div>
 | 
				
			||||||
 | 
					                                        <form method="POST" class="inline-flex" x-show="updateOpen">
 | 
				
			||||||
 | 
					                                            <div class="flex-1">
 | 
				
			||||||
 | 
					                                                <input type="date" name="enddate" value="{{(timeFrom .ViewState.booking.Enddate).Format "2006-01-02"}}"
 | 
				
			||||||
 | 
					                                                class="shadow-sm focus:ring-co-blue focus:border-co-blue block sm:text-sm border-gray-300 rounded-2xl">
 | 
				
			||||||
 | 
					                                            </div>
 | 
				
			||||||
 | 
					                                            <button 
 | 
				
			||||||
 | 
					                                                class=" justify-center text-co-blue px-4">
 | 
				
			||||||
 | 
					                                                OK
 | 
				
			||||||
 | 
					                                            </button>
 | 
				
			||||||
 | 
					                                        </form>
 | 
				
			||||||
 | 
					                                    </dd>
 | 
				
			||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
                                <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
					                                <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
				
			||||||
                                    <dt class="text-sm font-medium text-gray-500">Indisponible à partir du</dt>
 | 
					                                    <dt class="text-sm font-medium text-gray-500">Indisponible à partir du</dt>
 | 
				
			||||||
                                    <dd class="mt-1 text-sm  font-bold text-co-red sm:mt-0 sm:col-span-2">{{(timeFrom .ViewState.booking.Unavailablefrom).Format
 | 
					                                    <dd class="mt-1 text-sm  font-bold text-co-red sm:mt-0 sm:col-span-2 inline-flex"
 | 
				
			||||||
                                        "02/01/2006"}}</dd>
 | 
					                                    x-data="{ updateOpen: false }">
 | 
				
			||||||
 | 
					                                    <div class="w-full inline-flex" x-show="!updateOpen">
 | 
				
			||||||
 | 
					                                        <div class="flex-1">{{(timeFrom .ViewState.booking.Unavailablefrom).Format "02/01/2006"}}</div>
 | 
				
			||||||
 | 
					                                        <a href="#" class="text-co-blue hover:text-co-blue ml-5" @click="updateOpen = ! updateOpen">Modifier</a>
 | 
				
			||||||
 | 
					                                    </div>
 | 
				
			||||||
 | 
					                                    <form method="POST" class="inline-flex" x-show="updateOpen">
 | 
				
			||||||
 | 
					                                        <div class="flex-1">
 | 
				
			||||||
 | 
					                                            <input type="date" name="unavailablefrom" value="{{(timeFrom .ViewState.booking.Unavailablefrom).Format "2006-01-02"}}"
 | 
				
			||||||
 | 
					                                            class="shadow-sm focus:ring-co-blue focus:border-co-blue block sm:text-sm border-gray-300 rounded-2xl">
 | 
				
			||||||
 | 
					                                        </div>
 | 
				
			||||||
 | 
					                                        <button 
 | 
				
			||||||
 | 
					                                            class=" justify-center text-co-blue px-4">
 | 
				
			||||||
 | 
					                                            OK
 | 
				
			||||||
 | 
					                                        </button>
 | 
				
			||||||
 | 
					                                    </form>
 | 
				
			||||||
 | 
					                                    </dd>
 | 
				
			||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
                                <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
					                                <div class="py-4 sm:py-5 sm:grid sm:grid-cols-3 sm:gap-4">
 | 
				
			||||||
                                    <dt class="text-sm font-medium text-gray-500">Sera à nouveau disponible le</dt>
 | 
					                                    <dt class="text-sm font-medium text-gray-500">Sera à nouveau disponible le</dt>
 | 
				
			||||||
                                    <dd class="mt-1 text-sm  font-bold text-co-green sm:mt-0 sm:col-span-2">{{(timeFrom .ViewState.booking.Unavailableto).Format
 | 
					                                    <dd class="mt-1 text-sm  font-bold text-co-green sm:mt-0 sm:col-span-2 inline-flex"
 | 
				
			||||||
                                        "02/01/2006"}}</dd>
 | 
					                                    x-data="{ updateOpen: false }">
 | 
				
			||||||
 | 
					                                    <div class="w-full inline-flex" x-show="!updateOpen">
 | 
				
			||||||
 | 
					                                        <div class="flex-1">{{(timeFrom .ViewState.booking.Unavailableto).Format "02/01/2006"}}</div>
 | 
				
			||||||
 | 
					                                        <a href="#" class="text-co-blue hover:text-co-blue ml-5" @click="updateOpen = ! updateOpen">Modifier</a>
 | 
				
			||||||
 | 
					                                    </div>
 | 
				
			||||||
 | 
					                                    <form method="POST" class="inline-flex" x-show="updateOpen">
 | 
				
			||||||
 | 
					                                        <div class="flex-1">
 | 
				
			||||||
 | 
					                                            <input type="date" name="unavailableto" value="{{(timeFrom .ViewState.booking.Unavailableto).Format "2006-01-02"}}"
 | 
				
			||||||
 | 
					                                            class="shadow-sm focus:ring-co-blue focus:border-co-blue block sm:text-sm border-gray-300 rounded-2xl">
 | 
				
			||||||
 | 
					                                        </div>
 | 
				
			||||||
 | 
					                                        <button 
 | 
				
			||||||
 | 
					                                            class=" justify-center text-co-blue px-4">
 | 
				
			||||||
 | 
					                                            OK
 | 
				
			||||||
 | 
					                                        </button>
 | 
				
			||||||
 | 
					                                    </dd>
 | 
				
			||||||
                                </div>
 | 
					                                </div>
 | 
				
			||||||
                            </dl>
 | 
					                            </dl>
 | 
				
			||||||
                        </div>
 | 
					                        </div>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -74,7 +74,7 @@
 | 
				
			||||||
                    {{range .ViewState.vehicle.Bookings}}
 | 
					                    {{range .ViewState.vehicle.Bookings}}
 | 
				
			||||||
                    <li class="py-4 flex">
 | 
					                    <li class="py-4 flex">
 | 
				
			||||||
                      <div class="ml-3">
 | 
					                      <div class="ml-3">
 | 
				
			||||||
                        <a href="/vehicles/bookings/{{.ID}}" class="hover:bg-gray-200">
 | 
					                        <a href="/app/vehicles-management/bookings/{{.ID}}" class="hover:bg-gray-200">
 | 
				
			||||||
                            <p class="text-sm font-medium text-gray-900">Du {{(timeFrom .Startdate).Format "02/01/2006"}} au {{(timeFrom .Enddate).Format "02/01/2006"}}</p>
 | 
					                            <p class="text-sm font-medium text-gray-900">Du {{(timeFrom .Startdate).Format "02/01/2006"}} au {{(timeFrom .Enddate).Format "02/01/2006"}}</p>
 | 
				
			||||||
                            <p class="text-sm text-gray-500"></p>
 | 
					                            <p class="text-sm text-gray-500"></p>
 | 
				
			||||||
                        </a>
 | 
					                        </a>
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -798,14 +798,6 @@ html {
 | 
				
			||||||
  left: 0px;
 | 
					  left: 0px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.top-4 {
 | 
					 | 
				
			||||||
  top: 1rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.left-4 {
 | 
					 | 
				
			||||||
  left: 1rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.z-40 {
 | 
					.z-40 {
 | 
				
			||||||
  z-index: 40;
 | 
					  z-index: 40;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -830,22 +822,10 @@ html {
 | 
				
			||||||
  grid-column: span 3 / span 3;
 | 
					  grid-column: span 3 / span 3;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.col-span-2 {
 | 
					 | 
				
			||||||
  grid-column: span 2 / span 2;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.col-span-4 {
 | 
					 | 
				
			||||||
  grid-column: span 4 / span 4;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.col-span-5 {
 | 
					.col-span-5 {
 | 
				
			||||||
  grid-column: span 5 / span 5;
 | 
					  grid-column: span 5 / span 5;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.m-auto {
 | 
					 | 
				
			||||||
  margin: auto;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.mx-auto {
 | 
					.mx-auto {
 | 
				
			||||||
  margin-left: auto;
 | 
					  margin-left: auto;
 | 
				
			||||||
  margin-right: auto;
 | 
					  margin-right: auto;
 | 
				
			||||||
| 
						 | 
					@ -861,6 +841,11 @@ html {
 | 
				
			||||||
  margin-right: -1rem;
 | 
					  margin-right: -1rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.my-4 {
 | 
				
			||||||
 | 
					  margin-top: 1rem;
 | 
				
			||||||
 | 
					  margin-bottom: 1rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.-my-1\.5 {
 | 
					.-my-1\.5 {
 | 
				
			||||||
  margin-top: -0.375rem;
 | 
					  margin-top: -0.375rem;
 | 
				
			||||||
  margin-bottom: -0.375rem;
 | 
					  margin-bottom: -0.375rem;
 | 
				
			||||||
| 
						 | 
					@ -871,9 +856,9 @@ html {
 | 
				
			||||||
  margin-bottom: -0.25rem;
 | 
					  margin-bottom: -0.25rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.my-4 {
 | 
					.my-8 {
 | 
				
			||||||
  margin-top: 1rem;
 | 
					  margin-top: 2rem;
 | 
				
			||||||
  margin-bottom: 1rem;
 | 
					  margin-bottom: 2rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.-mr-12 {
 | 
					.-mr-12 {
 | 
				
			||||||
| 
						 | 
					@ -952,18 +937,18 @@ html {
 | 
				
			||||||
  margin-bottom: -1px;
 | 
					  margin-bottom: -1px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.-mb-8 {
 | 
					 | 
				
			||||||
  margin-bottom: -2rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.-ml-px {
 | 
					 | 
				
			||||||
  margin-left: -1px;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.-ml-4 {
 | 
					.-ml-4 {
 | 
				
			||||||
  margin-left: -1rem;
 | 
					  margin-left: -1rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.-mt-4 {
 | 
				
			||||||
 | 
					  margin-top: -1rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.mb-4 {
 | 
				
			||||||
 | 
					  margin-bottom: 1rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.-mt-2 {
 | 
					.-mt-2 {
 | 
				
			||||||
  margin-top: -0.5rem;
 | 
					  margin-top: -0.5rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -980,12 +965,20 @@ html {
 | 
				
			||||||
  margin-right: -0.25rem;
 | 
					  margin-right: -0.25rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.mb-4 {
 | 
					.mr-2 {
 | 
				
			||||||
  margin-bottom: 1rem;
 | 
					  margin-right: 0.5rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.-mt-4 {
 | 
					.mr-0 {
 | 
				
			||||||
  margin-top: -1rem;
 | 
					  margin-right: 0px;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.mt-16 {
 | 
				
			||||||
 | 
					  margin-top: 4rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.mt-12 {
 | 
				
			||||||
 | 
					  margin-top: 3rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.block {
 | 
					.block {
 | 
				
			||||||
| 
						 | 
					@ -1012,10 +1005,6 @@ html {
 | 
				
			||||||
  display: table;
 | 
					  display: table;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.flow-root {
 | 
					 | 
				
			||||||
  display: flow-root;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.grid {
 | 
					.grid {
 | 
				
			||||||
  display: grid;
 | 
					  display: grid;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1060,10 +1049,6 @@ html {
 | 
				
			||||||
  height: 3rem;
 | 
					  height: 3rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.h-96 {
 | 
					 | 
				
			||||||
  height: 24rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.max-h-60 {
 | 
					.max-h-60 {
 | 
				
			||||||
  max-height: 15rem;
 | 
					  max-height: 15rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1116,12 +1101,8 @@ html {
 | 
				
			||||||
  width: 3rem;
 | 
					  width: 3rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.w-0\.5 {
 | 
					.w-11 {
 | 
				
			||||||
  width: 0.125rem;
 | 
					  width: 2.75rem;
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.w-0 {
 | 
					 | 
				
			||||||
  width: 0px;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.min-w-0 {
 | 
					.min-w-0 {
 | 
				
			||||||
| 
						 | 
					@ -1190,6 +1171,11 @@ html {
 | 
				
			||||||
  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
 | 
					  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.translate-x-5 {
 | 
				
			||||||
 | 
					  --tw-translate-x: 1.25rem;
 | 
				
			||||||
 | 
					  transform: translate(var(--tw-translate-x), var(--tw-translate-y)) rotate(var(--tw-rotate)) skewX(var(--tw-skew-x)) skewY(var(--tw-skew-y)) scaleX(var(--tw-scale-x)) scaleY(var(--tw-scale-y));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.scale-95 {
 | 
					.scale-95 {
 | 
				
			||||||
  --tw-scale-x: .95;
 | 
					  --tw-scale-x: .95;
 | 
				
			||||||
  --tw-scale-y: .95;
 | 
					  --tw-scale-y: .95;
 | 
				
			||||||
| 
						 | 
					@ -1221,10 +1207,6 @@ html {
 | 
				
			||||||
          user-select: none;
 | 
					          user-select: none;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.grid-flow-row {
 | 
					 | 
				
			||||||
  grid-auto-flow: row;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.grid-cols-6 {
 | 
					.grid-cols-6 {
 | 
				
			||||||
  grid-template-columns: repeat(6, minmax(0, 1fr));
 | 
					  grid-template-columns: repeat(6, minmax(0, 1fr));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1233,6 +1215,10 @@ html {
 | 
				
			||||||
  grid-template-columns: repeat(1, minmax(0, 1fr));
 | 
					  grid-template-columns: repeat(1, minmax(0, 1fr));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.grid-cols-2 {
 | 
				
			||||||
 | 
					  grid-template-columns: repeat(2, minmax(0, 1fr));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.grid-cols-3 {
 | 
					.grid-cols-3 {
 | 
				
			||||||
  grid-template-columns: repeat(3, minmax(0, 1fr));
 | 
					  grid-template-columns: repeat(3, minmax(0, 1fr));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1241,10 +1227,6 @@ html {
 | 
				
			||||||
  grid-template-columns: repeat(7, minmax(0, 1fr));
 | 
					  grid-template-columns: repeat(7, minmax(0, 1fr));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.grid-cols-2 {
 | 
					 | 
				
			||||||
  grid-template-columns: repeat(2, minmax(0, 1fr));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.flex-row {
 | 
					.flex-row {
 | 
				
			||||||
  flex-direction: row;
 | 
					  flex-direction: row;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1344,24 +1326,18 @@ html {
 | 
				
			||||||
  margin-left: calc(2rem * calc(1 - var(--tw-space-x-reverse)));
 | 
					  margin-left: calc(2rem * calc(1 - var(--tw-space-x-reverse)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.space-x-3 > :not([hidden]) ~ :not([hidden]) {
 | 
					 | 
				
			||||||
  --tw-space-x-reverse: 0;
 | 
					 | 
				
			||||||
  margin-right: calc(0.75rem * var(--tw-space-x-reverse));
 | 
					 | 
				
			||||||
  margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse)));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.space-x-4 > :not([hidden]) ~ :not([hidden]) {
 | 
					 | 
				
			||||||
  --tw-space-x-reverse: 0;
 | 
					 | 
				
			||||||
  margin-right: calc(1rem * var(--tw-space-x-reverse));
 | 
					 | 
				
			||||||
  margin-left: calc(1rem * calc(1 - var(--tw-space-x-reverse)));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.-space-x-px > :not([hidden]) ~ :not([hidden]) {
 | 
					.-space-x-px > :not([hidden]) ~ :not([hidden]) {
 | 
				
			||||||
  --tw-space-x-reverse: 0;
 | 
					  --tw-space-x-reverse: 0;
 | 
				
			||||||
  margin-right: calc(-1px * var(--tw-space-x-reverse));
 | 
					  margin-right: calc(-1px * var(--tw-space-x-reverse));
 | 
				
			||||||
  margin-left: calc(-1px * calc(1 - var(--tw-space-x-reverse)));
 | 
					  margin-left: calc(-1px * calc(1 - var(--tw-space-x-reverse)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.space-x-3 > :not([hidden]) ~ :not([hidden]) {
 | 
				
			||||||
 | 
					  --tw-space-x-reverse: 0;
 | 
				
			||||||
 | 
					  margin-right: calc(0.75rem * var(--tw-space-x-reverse));
 | 
				
			||||||
 | 
					  margin-left: calc(0.75rem * calc(1 - var(--tw-space-x-reverse)));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.space-y-8 > :not([hidden]) ~ :not([hidden]) {
 | 
					.space-y-8 > :not([hidden]) ~ :not([hidden]) {
 | 
				
			||||||
  --tw-space-y-reverse: 0;
 | 
					  --tw-space-y-reverse: 0;
 | 
				
			||||||
  margin-top: calc(2rem * calc(1 - var(--tw-space-y-reverse)));
 | 
					  margin-top: calc(2rem * calc(1 - var(--tw-space-y-reverse)));
 | 
				
			||||||
| 
						 | 
					@ -1374,12 +1350,6 @@ html {
 | 
				
			||||||
  margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
 | 
					  margin-left: calc(0.5rem * calc(1 - var(--tw-space-x-reverse)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.space-x-6 > :not([hidden]) ~ :not([hidden]) {
 | 
					 | 
				
			||||||
  --tw-space-x-reverse: 0;
 | 
					 | 
				
			||||||
  margin-right: calc(1.5rem * var(--tw-space-x-reverse));
 | 
					 | 
				
			||||||
  margin-left: calc(1.5rem * calc(1 - var(--tw-space-x-reverse)));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.space-y-reverse > :not([hidden]) ~ :not([hidden]) {
 | 
					.space-y-reverse > :not([hidden]) ~ :not([hidden]) {
 | 
				
			||||||
  --tw-space-y-reverse: 1;
 | 
					  --tw-space-y-reverse: 1;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1478,9 +1448,9 @@ html {
 | 
				
			||||||
  border-bottom-right-radius: 0.375rem;
 | 
					  border-bottom-right-radius: 0.375rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.rounded-b-2xl {
 | 
					.rounded-r-2xl {
 | 
				
			||||||
 | 
					  border-top-right-radius: 1rem;
 | 
				
			||||||
  border-bottom-right-radius: 1rem;
 | 
					  border-bottom-right-radius: 1rem;
 | 
				
			||||||
  border-bottom-left-radius: 1rem;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.rounded-l-2xl {
 | 
					.rounded-l-2xl {
 | 
				
			||||||
| 
						 | 
					@ -1488,9 +1458,9 @@ html {
 | 
				
			||||||
  border-bottom-left-radius: 1rem;
 | 
					  border-bottom-left-radius: 1rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.rounded-r-2xl {
 | 
					.rounded-b-2xl {
 | 
				
			||||||
  border-top-right-radius: 1rem;
 | 
					 | 
				
			||||||
  border-bottom-right-radius: 1rem;
 | 
					  border-bottom-right-radius: 1rem;
 | 
				
			||||||
 | 
					  border-bottom-left-radius: 1rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.border {
 | 
					.border {
 | 
				
			||||||
| 
						 | 
					@ -1501,10 +1471,6 @@ html {
 | 
				
			||||||
  border-width: 2px;
 | 
					  border-width: 2px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.border-4 {
 | 
					 | 
				
			||||||
  border-width: 4px;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.border-r {
 | 
					.border-r {
 | 
				
			||||||
  border-right-width: 1px;
 | 
					  border-right-width: 1px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1521,18 +1487,10 @@ html {
 | 
				
			||||||
  border-bottom-width: 2px;
 | 
					  border-bottom-width: 2px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.border-r-0 {
 | 
					 | 
				
			||||||
  border-right-width: 0px;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.border-l-0 {
 | 
					.border-l-0 {
 | 
				
			||||||
  border-left-width: 0px;
 | 
					  border-left-width: 0px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.border-dashed {
 | 
					 | 
				
			||||||
  border-style: dashed;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.border-gray-200 {
 | 
					.border-gray-200 {
 | 
				
			||||||
  --tw-border-opacity: 1;
 | 
					  --tw-border-opacity: 1;
 | 
				
			||||||
  border-color: rgb(229 231 235 / var(--tw-border-opacity));
 | 
					  border-color: rgb(229 231 235 / var(--tw-border-opacity));
 | 
				
			||||||
| 
						 | 
					@ -1602,31 +1560,6 @@ html {
 | 
				
			||||||
  background-color: rgb(249 250 251 / var(--tw-bg-opacity));
 | 
					  background-color: rgb(249 250 251 / var(--tw-bg-opacity));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.bg-gray-200 {
 | 
					 | 
				
			||||||
  --tw-bg-opacity: 1;
 | 
					 | 
				
			||||||
  background-color: rgb(229 231 235 / var(--tw-bg-opacity));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.bg-gray-400 {
 | 
					 | 
				
			||||||
  --tw-bg-opacity: 1;
 | 
					 | 
				
			||||||
  background-color: rgb(156 163 175 / var(--tw-bg-opacity));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.bg-blue-500 {
 | 
					 | 
				
			||||||
  --tw-bg-opacity: 1;
 | 
					 | 
				
			||||||
  background-color: rgb(59 130 246 / var(--tw-bg-opacity));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.bg-green-500 {
 | 
					 | 
				
			||||||
  --tw-bg-opacity: 1;
 | 
					 | 
				
			||||||
  background-color: rgb(34 197 94 / var(--tw-bg-opacity));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.bg-blue-600 {
 | 
					 | 
				
			||||||
  --tw-bg-opacity: 1;
 | 
					 | 
				
			||||||
  background-color: rgb(37 99 235 / var(--tw-bg-opacity));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.bg-green-100 {
 | 
					.bg-green-100 {
 | 
				
			||||||
  --tw-bg-opacity: 1;
 | 
					  --tw-bg-opacity: 1;
 | 
				
			||||||
  background-color: rgb(220 252 231 / var(--tw-bg-opacity));
 | 
					  background-color: rgb(220 252 231 / var(--tw-bg-opacity));
 | 
				
			||||||
| 
						 | 
					@ -1637,11 +1570,6 @@ html {
 | 
				
			||||||
  background-color: rgb(238 242 255 / var(--tw-bg-opacity));
 | 
					  background-color: rgb(238 242 255 / var(--tw-bg-opacity));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.bg-gray-300 {
 | 
					 | 
				
			||||||
  --tw-bg-opacity: 1;
 | 
					 | 
				
			||||||
  background-color: rgb(209 213 219 / var(--tw-bg-opacity));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.bg-indigo-600 {
 | 
					.bg-indigo-600 {
 | 
				
			||||||
  --tw-bg-opacity: 1;
 | 
					  --tw-bg-opacity: 1;
 | 
				
			||||||
  background-color: rgb(79 70 229 / var(--tw-bg-opacity));
 | 
					  background-color: rgb(79 70 229 / var(--tw-bg-opacity));
 | 
				
			||||||
| 
						 | 
					@ -1652,6 +1580,11 @@ html {
 | 
				
			||||||
  background-color: rgb(17 24 39 / var(--tw-bg-opacity));
 | 
					  background-color: rgb(17 24 39 / var(--tw-bg-opacity));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.bg-gray-200 {
 | 
				
			||||||
 | 
					  --tw-bg-opacity: 1;
 | 
				
			||||||
 | 
					  background-color: rgb(229 231 235 / var(--tw-bg-opacity));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.bg-opacity-75 {
 | 
					.bg-opacity-75 {
 | 
				
			||||||
  --tw-bg-opacity: 0.75;
 | 
					  --tw-bg-opacity: 0.75;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1660,8 +1593,8 @@ html {
 | 
				
			||||||
  padding: 1rem;
 | 
					  padding: 1rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.p-6 {
 | 
					.p-12 {
 | 
				
			||||||
  padding: 1.5rem;
 | 
					  padding: 3rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.p-2 {
 | 
					.p-2 {
 | 
				
			||||||
| 
						 | 
					@ -1676,14 +1609,6 @@ html {
 | 
				
			||||||
  padding: 0.25rem;
 | 
					  padding: 0.25rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.p-8 {
 | 
					 | 
				
			||||||
  padding: 2rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.p-12 {
 | 
					 | 
				
			||||||
  padding: 3rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.px-4 {
 | 
					.px-4 {
 | 
				
			||||||
  padding-left: 1rem;
 | 
					  padding-left: 1rem;
 | 
				
			||||||
  padding-right: 1rem;
 | 
					  padding-right: 1rem;
 | 
				
			||||||
| 
						 | 
					@ -1749,26 +1674,16 @@ html {
 | 
				
			||||||
  padding-bottom: 0.75rem;
 | 
					  padding-bottom: 0.75rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.px-6 {
 | 
					 | 
				
			||||||
  padding-left: 1.5rem;
 | 
					 | 
				
			||||||
  padding-right: 1.5rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.py-0\.5 {
 | 
					 | 
				
			||||||
  padding-top: 0.125rem;
 | 
					 | 
				
			||||||
  padding-bottom: 0.125rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.py-0 {
 | 
					 | 
				
			||||||
  padding-top: 0px;
 | 
					 | 
				
			||||||
  padding-bottom: 0px;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.py-8 {
 | 
					.py-8 {
 | 
				
			||||||
  padding-top: 2rem;
 | 
					  padding-top: 2rem;
 | 
				
			||||||
  padding-bottom: 2rem;
 | 
					  padding-bottom: 2rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.px-6 {
 | 
				
			||||||
 | 
					  padding-left: 1.5rem;
 | 
				
			||||||
 | 
					  padding-right: 1.5rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.pt-5 {
 | 
					.pt-5 {
 | 
				
			||||||
  padding-top: 1.25rem;
 | 
					  padding-top: 1.25rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1809,40 +1724,28 @@ html {
 | 
				
			||||||
  padding-left: 1rem;
 | 
					  padding-left: 1rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.pb-8 {
 | 
					 | 
				
			||||||
  padding-bottom: 2rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.pt-1\.5 {
 | 
					 | 
				
			||||||
  padding-top: 0.375rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.pt-1 {
 | 
					 | 
				
			||||||
  padding-top: 0.25rem;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.pr-4 {
 | 
					.pr-4 {
 | 
				
			||||||
  padding-right: 1rem;
 | 
					  padding-right: 1rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.pr-2 {
 | 
					.pr-12 {
 | 
				
			||||||
  padding-right: 0.5rem;
 | 
					  padding-right: 3rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.pt-8 {
 | 
					.pt-8 {
 | 
				
			||||||
  padding-top: 2rem;
 | 
					  padding-top: 2rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.pr-2 {
 | 
				
			||||||
 | 
					  padding-right: 0.5rem;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.pl-1\.5 {
 | 
					.pl-1\.5 {
 | 
				
			||||||
  padding-left: 0.375rem;
 | 
					  padding-left: 0.375rem;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.pl-3\.5 {
 | 
					.pb-1 {
 | 
				
			||||||
  padding-left: 0.875rem;
 | 
					  padding-bottom: 0.25rem;
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.pr-12 {
 | 
					 | 
				
			||||||
  padding-right: 3rem;
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.text-left {
 | 
					.text-left {
 | 
				
			||||||
| 
						 | 
					@ -1857,6 +1760,10 @@ html {
 | 
				
			||||||
  text-align: right;
 | 
					  text-align: right;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.text-justify {
 | 
				
			||||||
 | 
					  text-align: justify;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.align-middle {
 | 
					.align-middle {
 | 
				
			||||||
  vertical-align: middle;
 | 
					  vertical-align: middle;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1916,10 +1823,6 @@ html {
 | 
				
			||||||
  font-weight: 800;
 | 
					  font-weight: 800;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.font-black {
 | 
					 | 
				
			||||||
  font-weight: 900;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.uppercase {
 | 
					.uppercase {
 | 
				
			||||||
  text-transform: uppercase;
 | 
					  text-transform: uppercase;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -1989,16 +1892,16 @@ html {
 | 
				
			||||||
  color: rgb(22 101 52 / var(--tw-text-opacity));
 | 
					  color: rgb(22 101 52 / var(--tw-text-opacity));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.text-gray-600 {
 | 
					 | 
				
			||||||
  --tw-text-opacity: 1;
 | 
					 | 
				
			||||||
  color: rgb(75 85 99 / var(--tw-text-opacity));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.text-co-green {
 | 
					.text-co-green {
 | 
				
			||||||
  --tw-text-opacity: 1;
 | 
					  --tw-text-opacity: 1;
 | 
				
			||||||
  color: rgb(108 193 31 / var(--tw-text-opacity));
 | 
					  color: rgb(108 193 31 / var(--tw-text-opacity));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.text-gray-600 {
 | 
				
			||||||
 | 
					  --tw-text-opacity: 1;
 | 
				
			||||||
 | 
					  color: rgb(75 85 99 / var(--tw-text-opacity));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.placeholder-gray-500::-moz-placeholder {
 | 
					.placeholder-gray-500::-moz-placeholder {
 | 
				
			||||||
  --tw-placeholder-opacity: 1;
 | 
					  --tw-placeholder-opacity: 1;
 | 
				
			||||||
  color: rgb(107 114 128 / var(--tw-placeholder-opacity));
 | 
					  color: rgb(107 114 128 / var(--tw-placeholder-opacity));
 | 
				
			||||||
| 
						 | 
					@ -2058,9 +1961,9 @@ html {
 | 
				
			||||||
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
 | 
					  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.ring-8 {
 | 
					.ring-0 {
 | 
				
			||||||
  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
 | 
					  --tw-ring-offset-shadow: var(--tw-ring-inset) 0 0 0 var(--tw-ring-offset-width) var(--tw-ring-offset-color);
 | 
				
			||||||
  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(8px + var(--tw-ring-offset-width)) var(--tw-ring-color);
 | 
					  --tw-ring-shadow: var(--tw-ring-inset) 0 0 0 calc(0px + var(--tw-ring-offset-width)) var(--tw-ring-color);
 | 
				
			||||||
  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
 | 
					  box-shadow: var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow, 0 0 #0000);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -2101,6 +2004,14 @@ html {
 | 
				
			||||||
  transition-duration: 150ms;
 | 
					  transition-duration: 150ms;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.transition-colors {
 | 
				
			||||||
 | 
					  transition-property: color, background-color, border-color, fill, stroke, -webkit-text-decoration-color;
 | 
				
			||||||
 | 
					  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke;
 | 
				
			||||||
 | 
					  transition-property: color, background-color, border-color, text-decoration-color, fill, stroke, -webkit-text-decoration-color;
 | 
				
			||||||
 | 
					  transition-timing-function: cubic-bezier(0.4, 0, 0.2, 1);
 | 
				
			||||||
 | 
					  transition-duration: 150ms;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.duration-300 {
 | 
					.duration-300 {
 | 
				
			||||||
  transition-duration: 300ms;
 | 
					  transition-duration: 300ms;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2113,6 +2024,10 @@ html {
 | 
				
			||||||
  transition-duration: 75ms;
 | 
					  transition-duration: 75ms;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.duration-200 {
 | 
				
			||||||
 | 
					  transition-duration: 200ms;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.ease-linear {
 | 
					.ease-linear {
 | 
				
			||||||
  transition-timing-function: linear;
 | 
					  transition-timing-function: linear;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2188,21 +2103,16 @@ html {
 | 
				
			||||||
  background-color: rgb(36 56 135 / var(--tw-bg-opacity));
 | 
					  background-color: rgb(36 56 135 / var(--tw-bg-opacity));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.hover\:bg-blue-700:hover {
 | 
					 | 
				
			||||||
  --tw-bg-opacity: 1;
 | 
					 | 
				
			||||||
  background-color: rgb(29 78 216 / var(--tw-bg-opacity));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.hover\:bg-indigo-700:hover {
 | 
					 | 
				
			||||||
  --tw-bg-opacity: 1;
 | 
					 | 
				
			||||||
  background-color: rgb(67 56 202 / var(--tw-bg-opacity));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.hover\:bg-gray-100:hover {
 | 
					.hover\:bg-gray-100:hover {
 | 
				
			||||||
  --tw-bg-opacity: 1;
 | 
					  --tw-bg-opacity: 1;
 | 
				
			||||||
  background-color: rgb(243 244 246 / var(--tw-bg-opacity));
 | 
					  background-color: rgb(243 244 246 / var(--tw-bg-opacity));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.hover\:bg-blue-700:hover {
 | 
				
			||||||
 | 
					  --tw-bg-opacity: 1;
 | 
				
			||||||
 | 
					  background-color: rgb(29 78 216 / var(--tw-bg-opacity));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.hover\:bg-opacity-5:hover {
 | 
					.hover\:bg-opacity-5:hover {
 | 
				
			||||||
  --tw-bg-opacity: 0.05;
 | 
					  --tw-bg-opacity: 0.05;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2222,9 +2132,9 @@ html {
 | 
				
			||||||
  color: rgb(55 65 81 / var(--tw-text-opacity));
 | 
					  color: rgb(55 65 81 / var(--tw-text-opacity));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.hover\:text-indigo-900:hover {
 | 
					.hover\:text-co-blue:hover {
 | 
				
			||||||
  --tw-text-opacity: 1;
 | 
					  --tw-text-opacity: 1;
 | 
				
			||||||
  color: rgb(49 46 129 / var(--tw-text-opacity));
 | 
					  color: rgb(36 56 135 / var(--tw-text-opacity));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.hover\:text-gray-900:hover {
 | 
					.hover\:text-gray-900:hover {
 | 
				
			||||||
| 
						 | 
					@ -2232,23 +2142,13 @@ html {
 | 
				
			||||||
  color: rgb(17 24 39 / var(--tw-text-opacity));
 | 
					  color: rgb(17 24 39 / var(--tw-text-opacity));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.hover\:text-co-blue:hover {
 | 
					 | 
				
			||||||
  --tw-text-opacity: 1;
 | 
					 | 
				
			||||||
  color: rgb(36 56 135 / var(--tw-text-opacity));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.hover\:text-inherit:hover {
 | 
					 | 
				
			||||||
  color: inherit;
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.hover\:text-gray-500:hover {
 | 
					.hover\:text-gray-500:hover {
 | 
				
			||||||
  --tw-text-opacity: 1;
 | 
					  --tw-text-opacity: 1;
 | 
				
			||||||
  color: rgb(107 114 128 / var(--tw-text-opacity));
 | 
					  color: rgb(107 114 128 / var(--tw-text-opacity));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.hover\:text-indigo-500:hover {
 | 
					.hover\:text-inherit:hover {
 | 
				
			||||||
  --tw-text-opacity: 1;
 | 
					  color: inherit;
 | 
				
			||||||
  color: rgb(99 102 241 / var(--tw-text-opacity));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.focus\:border-transparent:focus {
 | 
					.focus\:border-transparent:focus {
 | 
				
			||||||
| 
						 | 
					@ -2327,16 +2227,16 @@ html {
 | 
				
			||||||
  --tw-ring-color: rgb(99 102 241 / var(--tw-ring-opacity));
 | 
					  --tw-ring-color: rgb(99 102 241 / var(--tw-ring-opacity));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.focus\:ring-blue-500:focus {
 | 
					 | 
				
			||||||
  --tw-ring-opacity: 1;
 | 
					 | 
				
			||||||
  --tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity));
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
.focus\:ring-co-red:focus {
 | 
					.focus\:ring-co-red:focus {
 | 
				
			||||||
  --tw-ring-opacity: 1;
 | 
					  --tw-ring-opacity: 1;
 | 
				
			||||||
  --tw-ring-color: rgb(255 19 0 / var(--tw-ring-opacity));
 | 
					  --tw-ring-color: rgb(255 19 0 / var(--tw-ring-opacity));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.focus\:ring-blue-500:focus {
 | 
				
			||||||
 | 
					  --tw-ring-opacity: 1;
 | 
				
			||||||
 | 
					  --tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
.focus\:ring-offset-2:focus {
 | 
					.focus\:ring-offset-2:focus {
 | 
				
			||||||
  --tw-ring-offset-width: 2px;
 | 
					  --tw-ring-offset-width: 2px;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					@ -2367,6 +2267,10 @@ html {
 | 
				
			||||||
    grid-column: span 1 / span 1;
 | 
					    grid-column: span 1 / span 1;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  .sm\:col-span-6 {
 | 
				
			||||||
 | 
					    grid-column: span 6 / span 6;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .sm\:mx-auto {
 | 
					  .sm\:mx-auto {
 | 
				
			||||||
    margin-left: auto;
 | 
					    margin-left: auto;
 | 
				
			||||||
    margin-right: auto;
 | 
					    margin-right: auto;
 | 
				
			||||||
| 
						 | 
					@ -2437,10 +2341,6 @@ html {
 | 
				
			||||||
    grid-template-columns: repeat(2, minmax(0, 1fr));
 | 
					    grid-template-columns: repeat(2, minmax(0, 1fr));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  .sm\:grid-cols-6 {
 | 
					 | 
				
			||||||
    grid-template-columns: repeat(6, minmax(0, 1fr));
 | 
					 | 
				
			||||||
  }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
  .sm\:grid-cols-3 {
 | 
					  .sm\:grid-cols-3 {
 | 
				
			||||||
    grid-template-columns: repeat(3, minmax(0, 1fr));
 | 
					    grid-template-columns: repeat(3, minmax(0, 1fr));
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -51,7 +51,7 @@ func NewIdentificationProvider(cfg *viper.Viper, services *services.ServicesHand
 | 
				
			||||||
		Endpoint: provider.Endpoint(),
 | 
							Endpoint: provider.Endpoint(),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// "openid" is a required scope for OpenID Connect flows.
 | 
							// "openid" is a required scope for OpenID Connect flows.
 | 
				
			||||||
		Scopes: []string{oidc.ScopeOpenID, "groups", "profile"},
 | 
							Scopes: []string{oidc.ScopeOpenID, "groups", "first_name", "last_name", "display_name"},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var store = sessions.NewCookieStore([]byte(sessionsSecret))
 | 
						var store = sessions.NewCookieStore([]byte(sessionsSecret))
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue