Administration, organizations access rights and véhicles booking
This commit is contained in:
parent
7225d027c9
commit
0bb915059d
|
@ -1,3 +1,3 @@
|
|||
config.yaml
|
||||
/config.yaml
|
||||
.vscode
|
||||
__debug_bin
|
11
README.md
11
README.md
|
@ -1,3 +1,12 @@
|
|||
# PARCOURSMOB
|
||||
|
||||
The PARCOURSMOB inclusive mobility platform.
|
||||
The PARCOURSMOB inclusive mobility platform.
|
||||
|
||||
## Differences with previous "RIDYGO Insertion Sociale"
|
||||
|
||||
This new version of PARCOURSMOB brings :
|
||||
|
||||
- A delegation on authentication and identification to an external OpenID Connect Provider like [COOPGO Mobility Accounts](https://git.coopgo.io/coopgo-platform/mobility-accounts)
|
||||
- A configurable and themeable approach of rendering web pages : the default theme is located in the folder [themes/default/](themes/default/)
|
||||
- A modular architecture based on groups and access rights, using [COOPGO Groups Management](https://git.coopgo.io/coopgo-groups-management)
|
||||
- A distributed cache system through [etcd](https://etcd.io/) to handle distributed state management like pagination in a cloud native way
|
3
go.mod
3
go.mod
|
@ -6,7 +6,10 @@ replace git.coopgo.io/coopgo-platform/mobility-accounts => ../../coopgo-platform
|
|||
|
||||
replace git.coopgo.io/coopgo-platform/groups-management => ../../coopgo-platform/groups-management/
|
||||
|
||||
replace git.coopgo.io/coopgo-platform/fleets => ../../coopgo-platform/fleets/
|
||||
|
||||
require (
|
||||
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/mobility-accounts v0.0.0-00010101000000-000000000000
|
||||
github.com/coreos/go-oidc v2.2.1+incompatible
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"image/png"
|
||||
"log"
|
||||
|
@ -34,34 +35,14 @@ type BeneficiariesForm struct {
|
|||
}
|
||||
|
||||
func (h *ApplicationHandler) BeneficiariesList(w http.ResponseWriter, r *http.Request) {
|
||||
g := r.Context().Value(identification.GroupKey)
|
||||
if g == nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
group := g.(storage.Group)
|
||||
|
||||
request := &mobilityaccounts.GetAccountsBatchRequest{
|
||||
Accountids: group.Members,
|
||||
}
|
||||
|
||||
resp, err := h.services.GRPC.MobilityAccounts.GetAccountsBatch(context.TODO(), request)
|
||||
accounts, err := h.beneficiaries(r)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var accounts = []any{}
|
||||
|
||||
for _, account := range resp.Accounts {
|
||||
if filterAccount(r, account) {
|
||||
a := account.ToStorageType()
|
||||
accounts = append(accounts, a)
|
||||
}
|
||||
}
|
||||
|
||||
cacheid := uuid.NewString()
|
||||
h.cache.PutWithTTL(cacheid, accounts, 1*time.Hour)
|
||||
|
||||
|
@ -303,3 +284,31 @@ func filterAccount(r *http.Request, a *mobilityaccounts.Account) bool {
|
|||
|
||||
return true
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) beneficiaries(r *http.Request) ([]any, error) {
|
||||
var accounts = []any{}
|
||||
g := r.Context().Value(identification.GroupKey)
|
||||
if g == nil {
|
||||
return accounts, errors.New("no group provided")
|
||||
}
|
||||
|
||||
group := g.(storage.Group)
|
||||
|
||||
request := &mobilityaccounts.GetAccountsBatchRequest{
|
||||
Accountids: group.Members,
|
||||
}
|
||||
|
||||
resp, err := h.services.GRPC.MobilityAccounts.GetAccountsBatch(context.TODO(), request)
|
||||
if err != nil {
|
||||
return accounts, err
|
||||
}
|
||||
|
||||
for _, account := range resp.Accounts {
|
||||
if filterAccount(r, account) {
|
||||
a := account.ToStorageType()
|
||||
accounts = append(accounts, a)
|
||||
}
|
||||
}
|
||||
|
||||
return accounts, err
|
||||
}
|
||||
|
|
|
@ -1,24 +1,208 @@
|
|||
package application
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"git.coopgo.io/coopgo-apps/parcoursmob/utils/identification"
|
||||
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"
|
||||
"github.com/google/uuid"
|
||||
"github.com/gorilla/mux"
|
||||
"google.golang.org/protobuf/types/known/structpb"
|
||||
)
|
||||
|
||||
func (h *ApplicationHandler) VehiclesManagementOverview(w http.ResponseWriter, r *http.Request) {
|
||||
h.Renderer.VehiclesManagementOverview(w, r)
|
||||
//Get Vehicles
|
||||
request := &fleets.GetVehiclesRequest{
|
||||
Namespaces: []string{"parcoursmob"},
|
||||
}
|
||||
resp, err := h.services.GRPC.Fleets.GetVehicles(context.TODO(), request)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
var vehicles = []any{}
|
||||
|
||||
for _, vehicle := range resp.Vehicles {
|
||||
if filterVehicle(r, vehicle) {
|
||||
v := vehicle.ToStorageType()
|
||||
vehicles = append(vehicles, v)
|
||||
}
|
||||
}
|
||||
h.Renderer.VehiclesManagementOverview(w, r, vehicles)
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) VehiclesFleetAdd(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == "POST" {
|
||||
g := r.Context().Value(identification.GroupKey)
|
||||
if g == nil {
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
group := g.(storage.Group)
|
||||
|
||||
if err := r.ParseForm(); err != nil {
|
||||
fmt.Println(err)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Println(r.Form)
|
||||
dataMap := map[string]any{}
|
||||
if v := r.FormValue("name"); v != "" {
|
||||
dataMap["name"] = v
|
||||
}
|
||||
if v := r.FormValue("address"); v != "" {
|
||||
var address map[string]any
|
||||
err := json.Unmarshal([]byte(v), &address)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
dataMap["address"] = address
|
||||
}
|
||||
if v := r.FormValue("informations"); v != "" {
|
||||
dataMap["informations"] = v
|
||||
}
|
||||
if v := r.FormValue("licence_plate"); v != "" {
|
||||
dataMap["licence_plate"] = v
|
||||
}
|
||||
|
||||
data, err := structpb.NewValue(dataMap)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
vehicle := &fleets.Vehicle{
|
||||
Id: uuid.NewString(),
|
||||
Namespace: "parcoursmob",
|
||||
Type: r.FormValue("type"),
|
||||
Administrators: []string{group.ID},
|
||||
Data: data.GetStructValue(),
|
||||
}
|
||||
|
||||
request := &fleets.AddVehicleRequest{
|
||||
Vehicle: vehicle,
|
||||
}
|
||||
|
||||
_, err = h.services.GRPC.Fleets.AddVehicle(context.TODO(), request)
|
||||
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, fmt.Sprintf("/app/vehicles-management/fleet/%s", vehicle.Id), http.StatusFound)
|
||||
return
|
||||
}
|
||||
h.Renderer.VehiclesFleetAdd(w, r)
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) VehiclesFleetDisplay(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
vehicleid := vars["vehicleid"]
|
||||
|
||||
request := &fleets.GetVehicleRequest{
|
||||
Vehicleid: vehicleid,
|
||||
}
|
||||
|
||||
resp, err := h.services.GRPC.Fleets.GetVehicle(context.TODO(), request)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
h.Renderer.VehiclesFleetDisplay(w, r, resp.Vehicle.ToStorageType())
|
||||
}
|
||||
|
||||
func (h *ApplicationHandler) VehiclesFleetUpdate(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
vehicleid := vars["vehicleid"]
|
||||
|
||||
if r.Method == "POST" {
|
||||
w.WriteHeader(http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
|
||||
request := &fleets.GetVehicleRequest{
|
||||
Vehicleid: vehicleid,
|
||||
}
|
||||
|
||||
resp, err := h.services.GRPC.Fleets.GetVehicle(context.TODO(), request)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
h.Renderer.VehiclesFleetUpdate(w, r, resp.Vehicle.ToStorageType())
|
||||
}
|
||||
|
||||
func filterVehicle(r *http.Request, v *fleets.Vehicle) bool {
|
||||
g := r.Context().Value(identification.GroupKey)
|
||||
if g == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
group := g.(storage.Group)
|
||||
|
||||
for _, n := range v.Administrators {
|
||||
if n == group.ID {
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (h ApplicationHandler) VehicleManagementBookingDisplay(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
bookingid := vars["bookingid"]
|
||||
|
||||
request := &fleets.GetBookingRequest{
|
||||
Bookingid: bookingid,
|
||||
}
|
||||
resp, err := h.services.GRPC.Fleets.GetBooking(context.TODO(), request)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
booking := resp.Booking.ToStorageType()
|
||||
|
||||
beneficiaryrequest := &mobilityaccounts.GetAccountRequest{
|
||||
Id: booking.Driver,
|
||||
}
|
||||
|
||||
beneficiaryresp, err := h.services.GRPC.MobilityAccounts.GetAccount(context.TODO(), beneficiaryrequest)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
grouprequest := &groupsmanagement.GetGroupRequest{
|
||||
Id: booking.Vehicle.Administrators[0],
|
||||
}
|
||||
|
||||
groupresp, err := h.services.GRPC.GroupsManagement.GetGroup(context.TODO(), grouprequest)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
h.Renderer.VehicleManagementBookingDisplay(w, r, booking, booking.Vehicle, beneficiaryresp.Account.ToStorageType(), groupresp.Group.ToStorageType())
|
||||
}
|
||||
|
|
|
@ -0,0 +1,151 @@
|
|||
package application
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
fleets "git.coopgo.io/coopgo-platform/fleets/grpcapi"
|
||||
mobilityaccounts "git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi"
|
||||
"github.com/google/uuid"
|
||||
"github.com/gorilla/mux"
|
||||
"google.golang.org/protobuf/types/known/timestamppb"
|
||||
)
|
||||
|
||||
func (h ApplicationHandler) VehiclesSearch(w http.ResponseWriter, r *http.Request) {
|
||||
r.ParseForm()
|
||||
|
||||
var beneficiary any
|
||||
|
||||
vehicles := []any{}
|
||||
searched := false
|
||||
start := r.FormValue("startdate")
|
||||
end := r.FormValue("enddate")
|
||||
|
||||
startdate, _ := time.Parse("2006-01-02", start)
|
||||
enddate, _ := time.Parse("2006-01-02", end)
|
||||
|
||||
if r.FormValue("beneficiaryid") != "" {
|
||||
// Handler form
|
||||
searched = true
|
||||
|
||||
requestbeneficiary := &mobilityaccounts.GetAccountRequest{
|
||||
Id: r.FormValue("beneficiaryid"),
|
||||
}
|
||||
|
||||
respbeneficiary, err := h.services.GRPC.MobilityAccounts.GetAccount(context.TODO(), requestbeneficiary)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
beneficiary = respbeneficiary.Account.ToStorageType()
|
||||
|
||||
request := &fleets.GetVehiclesRequest{
|
||||
Namespaces: []string{"parcoursmob"},
|
||||
}
|
||||
resp, err := h.services.GRPC.Fleets.GetVehicles(context.TODO(), request)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
}
|
||||
|
||||
for _, vehicle := range resp.Vehicles {
|
||||
v := vehicle.ToStorageType()
|
||||
if v.Free(startdate, enddate) {
|
||||
vehicles = append(vehicles, v)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
accounts, err := h.beneficiaries(r)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
h.Renderer.VehiclesSearch(w, r, accounts, searched, vehicles, beneficiary, r.FormValue("startdate"), r.FormValue("enddate"))
|
||||
}
|
||||
|
||||
func (h ApplicationHandler) Book(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
vars := mux.Vars(r)
|
||||
vehicleid := vars["vehicleid"]
|
||||
beneficiaryid := vars["beneficiaryid"]
|
||||
|
||||
r.ParseForm()
|
||||
|
||||
start := r.FormValue("startdate")
|
||||
end := r.FormValue("enddate")
|
||||
|
||||
startdate, _ := time.Parse("2006-01-02", start)
|
||||
enddate, _ := time.Parse("2006-01-02", end)
|
||||
|
||||
booking := &fleets.Booking{
|
||||
Id: uuid.NewString(),
|
||||
Vehicleid: vehicleid,
|
||||
Driver: beneficiaryid,
|
||||
Startdate: timestamppb.New(startdate),
|
||||
Enddate: timestamppb.New(enddate),
|
||||
Unavailablefrom: timestamppb.New(startdate),
|
||||
Unavailableto: timestamppb.New(enddate.Add(72 * time.Hour)),
|
||||
}
|
||||
|
||||
request := &fleets.CreateBookingRequest{
|
||||
Booking: booking,
|
||||
}
|
||||
|
||||
_, err := h.services.GRPC.Fleets.CreateBooking(context.TODO(), request)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
w.WriteHeader(http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
http.Redirect(w, r, fmt.Sprintf("/app/vehicles/bookings/%s", booking.Id), http.StatusFound)
|
||||
|
||||
}
|
||||
|
||||
func (h ApplicationHandler) VehicleBookingDisplay(w http.ResponseWriter, r *http.Request) {
|
||||
vars := mux.Vars(r)
|
||||
bookingid := vars["bookingid"]
|
||||
|
||||
request := &fleets.GetBookingRequest{
|
||||
Bookingid: bookingid,
|
||||
}
|
||||
resp, err := h.services.GRPC.Fleets.GetBooking(context.TODO(), request)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
booking := resp.Booking.ToStorageType()
|
||||
|
||||
beneficiaryrequest := &mobilityaccounts.GetAccountRequest{
|
||||
Id: booking.Driver,
|
||||
}
|
||||
|
||||
beneficiaryresp, err := h.services.GRPC.MobilityAccounts.GetAccount(context.TODO(), beneficiaryrequest)
|
||||
if err != nil {
|
||||
fmt.Println(err)
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
// grouprequest := &groupsmanagement.GetGroupRequest{
|
||||
// Id: booking.Vehicle.Administrators[0],
|
||||
// }
|
||||
|
||||
// groupresp, err := h.services.GRPC.GroupsManagement.GetGroup(context.TODO(), grouprequest)
|
||||
// if err != nil {
|
||||
// fmt.Println(err)
|
||||
// w.WriteHeader(http.StatusInternalServerError)
|
||||
// return
|
||||
// }
|
||||
|
||||
h.Renderer.VehicleBookingDisplay(w, r, booking, booking.Vehicle, beneficiaryresp.Account.ToStorageType(), "")
|
||||
}
|
6
main.go
6
main.go
|
@ -68,8 +68,14 @@ func main() {
|
|||
application.HandleFunc("/beneficiaries/{beneficiaryid}", applicationHandler.BeneficiaryDisplay)
|
||||
application.HandleFunc("/beneficiaries/{beneficiaryid}/update", applicationHandler.BeneficiaryUpdate)
|
||||
application.HandleFunc("/beneficiaries/{beneficiaryid}/picture", applicationHandler.BeneficiaryPicture)
|
||||
application.HandleFunc("/vehicles/", applicationHandler.VehiclesSearch)
|
||||
application.HandleFunc("/vehicles/bookings/{bookingid}", applicationHandler.VehicleBookingDisplay)
|
||||
application.HandleFunc("/vehicles/v/{vehicleid}/b/{beneficiaryid}", applicationHandler.Book)
|
||||
application.HandleFunc("/vehicles-management/", applicationHandler.VehiclesManagementOverview)
|
||||
application.HandleFunc("/vehicles-management/fleet/add", applicationHandler.VehiclesFleetAdd)
|
||||
application.HandleFunc("/vehicles-management/fleet/{vehicleid}", applicationHandler.VehiclesFleetDisplay)
|
||||
application.HandleFunc("/vehicles-management/fleet/{vehicleid}/update", applicationHandler.VehiclesFleetUpdate)
|
||||
application.HandleFunc("/vehicles-management/bookings/{bookingid}", applicationHandler.VehicleManagementBookingDisplay)
|
||||
//TODO Subrouters with middlewares checking security for each module ?
|
||||
application.Use(idp.Middleware)
|
||||
application.Use(idp.GroupsMiddleware)
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
package renderer
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"html/template"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
@ -47,6 +49,11 @@ func GenderISO5218(d any) string {
|
|||
return ""
|
||||
}
|
||||
|
||||
func JSON(v any) template.JS {
|
||||
result, _ := json.Marshal(v)
|
||||
return template.JS(result)
|
||||
}
|
||||
|
||||
func Dict(v ...interface{}) map[string]interface{} {
|
||||
dict := map[string]interface{}{}
|
||||
lenv := len(v)
|
||||
|
|
|
@ -49,6 +49,7 @@ func (renderer *Renderer) Render(name string, w http.ResponseWriter, r *http.Req
|
|||
"timeFrom": TimeFrom,
|
||||
"genderISO5218": GenderISO5218,
|
||||
"dict": Dict,
|
||||
"json": JSON,
|
||||
},
|
||||
)
|
||||
t = template.Must(t.ParseFiles(prefixed_files...))
|
||||
|
@ -70,6 +71,7 @@ func (renderer *Renderer) RenderNoLayout(name string, w http.ResponseWriter, r *
|
|||
"timeFrom": TimeFrom,
|
||||
"genderISO5218": GenderISO5218,
|
||||
"dict": Dict,
|
||||
"json": JSON,
|
||||
},
|
||||
)
|
||||
|
||||
|
@ -144,13 +146,13 @@ func NewState(r *http.Request, themeConfig *viper.Viper, menuState string) Rende
|
|||
Title: "Déplacements",
|
||||
Link: "/app/journeys/",
|
||||
Active: menuState == "journeys",
|
||||
Icon: "hero:outline/user-group",
|
||||
Icon: "hero:outline/map",
|
||||
})
|
||||
}
|
||||
|
||||
if modules["vehicles"].(bool) {
|
||||
ls.MenuItems = append(ls.MenuItems, MenuItem{
|
||||
Title: "Véhicules",
|
||||
Title: "Véhicules partagés",
|
||||
Link: "/app/vehicles/",
|
||||
Active: menuState == "vehicles",
|
||||
Icon: "hero:outline/user-group",
|
||||
|
@ -162,7 +164,7 @@ func NewState(r *http.Request, themeConfig *viper.Viper, menuState string) Rende
|
|||
Title: "Gestion des véhicules",
|
||||
Link: "/app/vehicles-management/",
|
||||
Active: menuState == "vehicles_management",
|
||||
Icon: "hero:outline/user-group",
|
||||
Icon: "hero:outline/briefcase",
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -171,7 +173,7 @@ func NewState(r *http.Request, themeConfig *viper.Viper, menuState string) Rende
|
|||
Title: "Dispositifs",
|
||||
Link: "/app/events/",
|
||||
Active: menuState == "events",
|
||||
Icon: "hero:outline/user-group",
|
||||
Icon: "hero:outline/calendar",
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -4,16 +4,52 @@ import "net/http"
|
|||
|
||||
const vehiclesmanagementMenu = "vehicles_management"
|
||||
|
||||
func (renderer *Renderer) VehiclesManagementOverview(w http.ResponseWriter, r *http.Request) {
|
||||
func (renderer *Renderer) VehiclesManagementOverview(w http.ResponseWriter, r *http.Request, vehicles []any) {
|
||||
files := renderer.ThemeConfig.GetStringSlice("views.vehicles_management.overview.files")
|
||||
state := NewState(r, renderer.ThemeConfig, vehiclesmanagementMenu)
|
||||
state.ViewState = map[string]any{
|
||||
"vehicles": vehicles,
|
||||
}
|
||||
|
||||
renderer.Render("fleet", w, r, files, state)
|
||||
renderer.Render("fleet overview", w, r, files, state)
|
||||
}
|
||||
|
||||
func (renderer *Renderer) VehiclesFleetAdd(w http.ResponseWriter, r *http.Request) {
|
||||
files := renderer.ThemeConfig.GetStringSlice("views.vehicles_management.fleet_add.files")
|
||||
state := NewState(r, renderer.ThemeConfig, vehiclesmanagementMenu)
|
||||
|
||||
renderer.Render("fleet", w, r, files, state)
|
||||
renderer.Render("fleet add vehicle", w, r, files, state)
|
||||
}
|
||||
|
||||
func (renderer *Renderer) VehiclesFleetDisplay(w http.ResponseWriter, r *http.Request, vehicle any) {
|
||||
files := renderer.ThemeConfig.GetStringSlice("views.vehicles_management.fleet_display.files")
|
||||
state := NewState(r, renderer.ThemeConfig, vehiclesmanagementMenu)
|
||||
state.ViewState = map[string]any{
|
||||
"vehicle": vehicle,
|
||||
}
|
||||
|
||||
renderer.Render("fleet display vehicle", w, r, files, state)
|
||||
}
|
||||
|
||||
func (renderer *Renderer) VehiclesFleetUpdate(w http.ResponseWriter, r *http.Request, vehicle any) {
|
||||
files := renderer.ThemeConfig.GetStringSlice("views.vehicles_management.fleet_update.files")
|
||||
state := NewState(r, renderer.ThemeConfig, vehiclesmanagementMenu)
|
||||
state.ViewState = map[string]any{
|
||||
"vehicle": vehicle,
|
||||
}
|
||||
|
||||
renderer.Render("fleet display vehicle", w, r, files, state)
|
||||
}
|
||||
|
||||
func (renderer *Renderer) VehicleManagementBookingDisplay(w http.ResponseWriter, r *http.Request, booking any, vehicle any, beneficiary any, group any) {
|
||||
files := renderer.ThemeConfig.GetStringSlice("views.vehicles_management.booking_display.files")
|
||||
state := NewState(r, renderer.ThemeConfig, vehiclesmanagementMenu)
|
||||
state.ViewState = map[string]any{
|
||||
"booking": booking,
|
||||
"vehicle": vehicle,
|
||||
"beneficiary": beneficiary,
|
||||
"group": group,
|
||||
}
|
||||
|
||||
renderer.Render("vehicles search", w, r, files, state)
|
||||
}
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
package renderer
|
||||
|
||||
import "net/http"
|
||||
|
||||
const vehiclesMenu = "vehicles"
|
||||
|
||||
func (renderer *Renderer) VehiclesSearch(w http.ResponseWriter, r *http.Request, beneficiaries []any, searched bool, vehicles []any, beneficiary any, startdate any, enddate any) {
|
||||
files := renderer.ThemeConfig.GetStringSlice("views.vehicles.search.files")
|
||||
state := NewState(r, renderer.ThemeConfig, vehiclesMenu)
|
||||
viewstate := map[string]any{
|
||||
"beneficiaries": beneficiaries,
|
||||
"searched": searched,
|
||||
}
|
||||
|
||||
if searched {
|
||||
viewstate["search"] = map[string]any{
|
||||
"startdate": startdate,
|
||||
"enddate": enddate,
|
||||
"vehicles": vehicles,
|
||||
"beneficiary": beneficiary,
|
||||
}
|
||||
}
|
||||
|
||||
state.ViewState = viewstate
|
||||
|
||||
renderer.Render("vehicles search", w, r, files, state)
|
||||
}
|
||||
|
||||
func (renderer *Renderer) VehicleBookingDisplay(w http.ResponseWriter, r *http.Request, booking any, vehicle any, beneficiary any, group any) {
|
||||
files := renderer.ThemeConfig.GetStringSlice("views.vehicles.booking_display.files")
|
||||
state := NewState(r, renderer.ThemeConfig, vehiclesMenu)
|
||||
state.ViewState = map[string]any{
|
||||
"booking": booking,
|
||||
"vehicle": vehicle,
|
||||
"beneficiary": beneficiary,
|
||||
"group": group,
|
||||
}
|
||||
|
||||
renderer.Render("vehicles search", w, r, files, state)
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
package services
|
||||
|
||||
import (
|
||||
fleets "git.coopgo.io/coopgo-platform/fleets/grpcapi"
|
||||
"google.golang.org/grpc"
|
||||
)
|
||||
|
||||
type FleetsService struct {
|
||||
fleets.FleetsClient
|
||||
}
|
||||
|
||||
func NewFleetsService(dial string) (*FleetsService, error) {
|
||||
conn, err := grpc.Dial(dial, grpc.WithInsecure())
|
||||
|
||||
client := fleets.NewFleetsClient(conn)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &FleetsService{
|
||||
FleetsClient: client,
|
||||
}, nil
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package services
|
||||
|
||||
import (
|
||||
fleets "git.coopgo.io/coopgo-platform/fleets/grpcapi"
|
||||
groupsmanagement "git.coopgo.io/coopgo-platform/groups-management/grpcapi"
|
||||
mobilityaccounts "git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi"
|
||||
"github.com/spf13/viper"
|
||||
|
@ -13,12 +14,14 @@ type ServicesHandler struct {
|
|||
type GRPCServices struct {
|
||||
MobilityAccounts mobilityaccounts.MobilityAccountsClient
|
||||
GroupsManagement groupsmanagement.GroupsManagementClient
|
||||
Fleets fleets.FleetsClient
|
||||
}
|
||||
|
||||
func NewServicesHandler(cfg *viper.Viper) (*ServicesHandler, error) {
|
||||
var (
|
||||
mobilityAccountsDial = cfg.GetString("services.grpc.mobilityaccounts.dial")
|
||||
groupsManagementDial = cfg.GetString("services.grpc.groupsmanagement.dial")
|
||||
fleetsDial = cfg.GetString("services.grpc.fleets.dial")
|
||||
)
|
||||
mobilityAccounts, err := NewMobilityAccountService(mobilityAccountsDial)
|
||||
if err != nil {
|
||||
|
@ -30,10 +33,16 @@ func NewServicesHandler(cfg *viper.Viper) (*ServicesHandler, error) {
|
|||
return nil, err
|
||||
}
|
||||
|
||||
fleetsSvc, err := NewFleetsService(fleetsDial)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &ServicesHandler{
|
||||
GRPC: GRPCServices{
|
||||
MobilityAccounts: mobilityAccounts,
|
||||
GroupsManagement: groupsManagement,
|
||||
Fleets: fleetsSvc,
|
||||
},
|
||||
}, nil
|
||||
}
|
||||
|
|
|
@ -0,0 +1,99 @@
|
|||
name: PARCOURSMOB
|
||||
|
||||
views:
|
||||
generic:
|
||||
files:
|
||||
- layouts/layout.html
|
||||
- layouts/_partials/mainmenu.html
|
||||
dashboard:
|
||||
files:
|
||||
- layouts/dashboard/_partials/beneficiaries-widget.html
|
||||
- layouts/dashboard/dashboard.html
|
||||
beneficiaries:
|
||||
list:
|
||||
files:
|
||||
- layouts/beneficiaries/list.html
|
||||
create:
|
||||
files:
|
||||
- layouts/_partials/address_autocomplete.html
|
||||
- layouts/beneficiaries/create.html
|
||||
display:
|
||||
files:
|
||||
- layouts/vehicles_management/_partials/vehicle-type-select.html
|
||||
- layouts/beneficiaries/_partials/beneficiary-vehicles.html
|
||||
- layouts/beneficiaries/_partials/beneficiary-notes.html
|
||||
- layouts/beneficiaries/_partials/beneficiary-journeys.html
|
||||
- layouts/beneficiaries/_partials/beneficiary-events.html
|
||||
- layouts/beneficiaries/_partials/beneficiary-files.html
|
||||
- layouts/beneficiaries/display.html
|
||||
update:
|
||||
files:
|
||||
- layouts/_partials/address_autocomplete.html
|
||||
- layouts/beneficiaries/update.html
|
||||
vehicles:
|
||||
search:
|
||||
files:
|
||||
- layouts/_partials/address_autocomplete.html
|
||||
- layouts/vehicles_management/_partials/vehicle-type-select.html
|
||||
- layouts/vehicles/search.html
|
||||
booking_display:
|
||||
files:
|
||||
- layouts/vehicles/booking-display.html
|
||||
vehicles_management:
|
||||
overview:
|
||||
files:
|
||||
- layouts/vehicles_management/_partials/bookings-list.html
|
||||
- layouts/vehicles_management/_partials/vehicles-list.html
|
||||
- layouts/vehicles_management/overview.html
|
||||
fleet_add:
|
||||
files:
|
||||
- layouts/_partials/address_autocomplete.html
|
||||
- layouts/vehicles_management/_partials/vehicle-type-select.html
|
||||
- layouts/vehicles_management/fleet-add.html
|
||||
fleet_display:
|
||||
files:
|
||||
- layouts/vehicles_management/_partials/calendar.html
|
||||
- layouts/vehicles_management/fleet-display.html
|
||||
fleet_update:
|
||||
files:
|
||||
- layouts/_partials/address_autocomplete.html
|
||||
- layouts/vehicles_management/_partials/vehicle-type-select.html
|
||||
- layouts/vehicles_management/fleet-update.html
|
||||
booking_display:
|
||||
files:
|
||||
- layouts/vehicles_management/booking-display.html
|
||||
administration:
|
||||
home:
|
||||
files:
|
||||
- layouts/administration/home.html
|
||||
create_group:
|
||||
files:
|
||||
- layouts/administration/create_group.html
|
||||
display_group:
|
||||
files:
|
||||
- layouts/administration/_partials/groups_admins.html
|
||||
- layouts/administration/display_group.html
|
||||
auth:
|
||||
groups:
|
||||
files:
|
||||
- layouts/auth/groups.html
|
||||
|
||||
icons:
|
||||
svg:
|
||||
coopgo:parcoursmob/monogram: <svg xmlns="http://www.w3.org/2000/svg" class="%s" viewBox="0 0 61.85 33.58"><defs><style>.cls-1{fill:#ff1300;}.cls-2{fill:#243887;}</style></defs><g id="Calque_2" data-name="Calque 2"><g id="Calque_1-2" data-name="Calque 1"><path class="cls-1" d="M44.978,0C31.337,0,28.1,6.824,27.875,15.505H39.536V9.434a.727.727,0,0,1,1.123-.607L52.6,16.453,40.659,24.08a.729.729,0,0,1-1.123-.608v-6.1H27.865c.075,8.427,1.527,16.213,17.113,16.213,14.867,0,16.872-7.764,16.872-17.032C61.85,7.91,59.894,0,44.978,0Z"/><polygon class="cls-1" points="41.412 21.385 49.133 16.453 41.412 11.521 41.412 21.385"/><path class="cls-2" d="M14.175,11.4l-.019,4.151H26.311a14.781,14.781,0,0,0,.819-5.141C27.046,3.767,22.545,0,14.764,0H1.052A1.147,1.147,0,0,0,0,1.24V31.87a1.149,1.149,0,0,0,1.094,1.239H11.525a1.145,1.145,0,0,0,1.051-1.239V10.41h.758C13.88,10.41,14.175,10.756,14.175,11.4Z"/><path class="cls-2" d="M14.148,17.3l-.015,3.514H18.97A7.521,7.521,0,0,0,25.458,17.3Z"/></g></g></svg>
|
||||
hero:outline/briefcase: <svg xmlns="http://www.w3.org/2000/svg" class="%s" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M21 13.255A23.931 23.931 0 0112 15c-3.183 0-6.22-.62-9-1.745M16 6V4a2 2 0 00-2-2h-4a2 2 0 00-2 2v2m4 6h.01M5 20h14a2 2 0 002-2V8a2 2 0 00-2-2H5a2 2 0 00-2 2v10a2 2 0 002 2z" /></svg>
|
||||
hero:outline/calendar: <svg xmlns="http://www.w3.org/2000/svg" class="%s" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z" /></svg>
|
||||
hero:outline/cog: <svg xmlns="http://www.w3.org/2000/svg" class="%s" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M10.325 4.317c.426-1.756 2.924-1.756 3.35 0a1.724 1.724 0 002.573 1.066c1.543-.94 3.31.826 2.37 2.37a1.724 1.724 0 001.065 2.572c1.756.426 1.756 2.924 0 3.35a1.724 1.724 0 00-1.066 2.573c.94 1.543-.826 3.31-2.37 2.37a1.724 1.724 0 00-2.572 1.065c-.426 1.756-2.924 1.756-3.35 0a1.724 1.724 0 00-2.573-1.066c-1.543.94-3.31-.826-2.37-2.37a1.724 1.724 0 00-1.065-2.572c-1.756-.426-1.756-2.924 0-3.35a1.724 1.724 0 001.066-2.573c-.94-1.543.826-3.31 2.37-2.37.996.608 2.296.07 2.572-1.065z" /><path stroke-linecap="round" stroke-linejoin="round" d="M15 12a3 3 0 11-6 0 3 3 0 016 0z" /></svg>
|
||||
hero:outline/home: <svg xmlns="http://www.w3.org/2000/svg" class="%s" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M3 12l2-2m0 0l7-7 7 7M5 10v10a1 1 0 001 1h3m10-11l2 2m-2-2v10a1 1 0 01-1 1h-3m-6 0a1 1 0 001-1v-4a1 1 0 011-1h2a1 1 0 011 1v4a1 1 0 001 1m-6 0h6" /></svg>
|
||||
hero:outline/map: <svg xmlns="http://www.w3.org/2000/svg" class="%s" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 20l-5.447-2.724A1 1 0 013 16.382V5.618a1 1 0 011.447-.894L9 7m0 13l6-3m-6 3V7m6 10l4.553 2.276A1 1 0 0021 18.382V7.618a1 1 0 00-.553-.894L15 4m0 13V4m0 0L9 7" /></svg>
|
||||
hero:outline/office-building: <svg xmlns="http://www.w3.org/2000/svg" class="%s" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M19 21V5a2 2 0 00-2-2H7a2 2 0 00-2 2v16m14 0h2m-2 0h-5m-9 0H3m2 0h5M9 7h1m-1 4h1m4-4h1m-1 4h1m-5 10v-5a1 1 0 011-1h2a1 1 0 011 1v5m-4 0h4" /></svg>
|
||||
hero:outline/plus-circle: <svg xmlns="http://www.w3.org/2000/svg" class="%s" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M12 9v3m0 0v3m0-3h3m-3 0H9m12 0a9 9 0 11-18 0 9 9 0 0118 0z" /></svg>
|
||||
hero:outline/shield-check: <svg xmlns="http://www.w3.org/2000/svg" class="%s" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 4-4m5.618-4.016A11.955 11.955 0 0112 2.944a11.955 11.955 0 01-8.618 3.04A12.02 12.02 0 003 9c0 5.591 3.824 10.29 9 11.622 5.176-1.332 9-6.03 9-11.622 0-1.042-.133-2.052-.382-3.016z" /></svg>
|
||||
hero:outline/user-group: <svg xmlns="http://www.w3.org/2000/svg" class="%s" fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2"><path stroke-linecap="round" stroke-linejoin="round" d="M17 20h5v-2a3 3 0 00-5.356-1.857M17 20H7m10 0v-2c0-.656-.126-1.283-.356-1.857M7 20H2v-2a3 3 0 015.356-1.857M7 20v-2c0-.656.126-1.283.356-1.857m0 0a5.002 5.002 0 019.288 0M15 7a3 3 0 11-6 0 3 3 0 016 0zm6 3a2 2 0 11-4 0 2 2 0 014 0zM7 10a2 2 0 11-4 0 2 2 0 014 0z" /></svg>
|
||||
hero:outline/x: <svg class="%s text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" aria-hidden="true"><path stroke-linecap="round" stroke-linejoin="round" d="M6 18L18 6M6 6l12 12" /></svg>
|
||||
hero:solid/chevron-right: <svg class="%s 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="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" /></svg>
|
||||
hero:solid/question-mark-icon: <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="M18 10a8 8 0 11-16 0 8 8 0 0116 0zm-8-3a1 1 0 00-.867.5 1 1 0 11-1.731-1A3 3 0 0113 8a3.001 3.001 0 01-2 2.83V11a1 1 0 11-2 0v-1a1 1 0 011-1 1 1 0 100-2zm0 8a1 1 0 100-2 1 1 0 000 2z" 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>
|
||||
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>
|
||||
|
|
@ -7,13 +7,13 @@
|
|||
|
||||
<div class="relative rounded-lg bg-white px-6 py-5 flex items-center space-x-3 focus-within:ring-2 focus-within:ring-offset-2 focus-within:ring-co-blue">
|
||||
<div class="flex-shrink-0">
|
||||
<img class="h-10 w-10 rounded-co" src="https://images.unsplash.com/photo-1494790108377-be9c29b29330?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80" alt="">
|
||||
<img class="h-10 w-10 rounded-co" src="http://localhost:9000/app/beneficiaries/e7616eac-4a87-4396-a505-23e0421b9c4c/picture" alt="">
|
||||
</div>
|
||||
<div class="flex-1 min-w-0">
|
||||
<a href="#" class="focus:outline-none">
|
||||
<span class="absolute inset-0" aria-hidden="true"></span>
|
||||
<p class="text-sm font-medium text-gray-900">Leslie Alexander</p>
|
||||
<p class="text-sm text-gray-500 truncate">aaa@bbb.fr</p>
|
||||
<p class="text-sm font-medium text-gray-900">Arnaud Delcasse</p>
|
||||
<p class="text-sm text-gray-500 truncate">arnaud.delcasse@coopgo.fr</p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -14,10 +14,10 @@
|
|||
</div>
|
||||
<div
|
||||
class="mt-6 flex flex-col-reverse justify-stretch space-y-4 space-y-reverse sm:flex-row-reverse sm:justify-end sm:space-x-reverse sm:space-y-0 sm:space-x-3 md:mt-0 md:flex-row md:space-x-3">
|
||||
<button type="button"
|
||||
<!-- <button type="button"
|
||||
class="inline-flex items-center justify-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-2xl text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-co-blue">Supprimer</button>
|
||||
<a href="/app/administration/groups/{{.ViewState.group.ID}}/update" class="inline-flex"><button type="button"
|
||||
class="w-full px-4 py-2 border border-transparent text-sm font-medium rounded-2xl shadow-sm text-white bg-co-blue hover:bg-co-blue focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-co-blue">Modifier</button></a>
|
||||
class="w-full px-4 py-2 border border-transparent text-sm font-medium rounded-2xl shadow-sm text-white bg-co-blue hover:bg-co-blue focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-co-blue">Modifier</button></a> -->
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-8 max-w-3xl mx-auto grid grid-cols-1 gap-6 sm:px-6 lg:max-w-7xl lg:grid-flow-col-dense lg:grid-cols-3">
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
class="flex-1 flex items-center justify-between border-t border-r border-b border-gray-200 bg-white rounded-r-3xl truncate">
|
||||
<div class="flex-1 px-4 py-2 text-sm truncate">
|
||||
<a href="#" class="text-gray-900 font-medium hover:text-gray-600">Bénéficiaires</a>
|
||||
<p class="text-gray-500">160 bénéficiaires</p>
|
||||
<p class="text-gray-500">{{len (index .ViewState.groups 0).Members}} bénéficiaires</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
@ -29,7 +29,7 @@
|
|||
class="flex-1 flex items-center justify-between border-t border-r border-b border-gray-200 bg-white rounded-r-3xl truncate">
|
||||
<div class="flex-1 px-4 py-2 text-sm truncate">
|
||||
<a href="#" class="text-gray-900 font-medium hover:text-gray-600">Organisations</a>
|
||||
<p class="text-gray-500">12 organisations</p>
|
||||
<p class="text-gray-500">{{len .ViewState.groups}} organisations</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
@ -43,7 +43,7 @@
|
|||
class="flex-1 flex items-center justify-between border-t border-r border-b border-gray-200 bg-white rounded-r-3xl truncate">
|
||||
<div class="flex-1 px-4 py-2 text-sm truncate">
|
||||
<a href="#" class="text-gray-900 font-medium hover:text-gray-600">Référents</a>
|
||||
<p class="text-gray-500">53 membres</p>
|
||||
<p class="text-gray-500">1 membres</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
@ -57,7 +57,7 @@
|
|||
class="flex-1 flex items-center justify-between border-t border-r border-b border-gray-200 bg-white rounded-r-3xl truncate">
|
||||
<div class="flex-1 px-4 py-2 text-sm truncate">
|
||||
<a href="#" class="text-gray-900 font-medium hover:text-gray-600">Accompagnement</a>
|
||||
<p class="text-gray-500">363 actions réalisées</p>
|
||||
<p class="text-gray-500">0 actions réalisées</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
@ -106,10 +106,10 @@
|
|||
<div class="mt-4 flex-shrink-0 sm:mt-0 sm:ml-5">
|
||||
<div class="flex overflow-hidden -space-x-1">
|
||||
<img class="inline-block h-6 w-6 rounded-full ring-2 ring-white"
|
||||
src="https://images.unsplash.com/photo-1506794778202-cad84cf45f1d?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
|
||||
src="http://localhost:9000/app/beneficiaries/e7616eac-4a87-4396-a505-23e0421b9c4c/picture"
|
||||
alt="Dries Vincent">
|
||||
|
||||
<img class="inline-block h-6 w-6 rounded-full ring-2 ring-white"
|
||||
<!-- <img class="inline-block h-6 w-6 rounded-full ring-2 ring-white"
|
||||
src="https://images.unsplash.com/photo-1517841905240-472988babdf9?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
|
||||
alt="Lindsay Walton">
|
||||
|
||||
|
@ -119,7 +119,7 @@
|
|||
|
||||
<img class="inline-block h-6 w-6 rounded-full ring-2 ring-white"
|
||||
src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
|
||||
alt="Tom Cook">
|
||||
alt="Tom Cook"> -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
{{define "beneficiary_events"}}
|
||||
<div class="px-4 py-6 sm:px-6">
|
||||
TODO Dispositifs
|
||||
</div>
|
||||
{{end}}
|
|
@ -1,5 +1,4 @@
|
|||
{{define "beneficiary_journeys"}}
|
||||
<div class="px-4 py-6 sm:px-6">
|
||||
TODO Déplacements
|
||||
</div>
|
||||
{{end}}
|
|
@ -1,7 +1,7 @@
|
|||
{{define "beneficiary_notes"}}
|
||||
<div class="px-4 py-6 sm:px-6">
|
||||
<ul role="list" class="space-y-8">
|
||||
<li>
|
||||
<!-- <li>
|
||||
<div class="flex space-x-3">
|
||||
<div class="flex-shrink-0">
|
||||
<img class="h-10 w-10 rounded-full"
|
||||
|
@ -73,7 +73,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</li> -->
|
||||
</ul>
|
||||
</div>
|
||||
<div class="bg-gray-50 px-4 py-6 sm:px-6">
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
{{define "beneficiary_vehicles"}}
|
||||
<div class="px-4 py-6 sm:px-6">
|
||||
<h3 class="text-lg">Réserver un véhicule</h3>
|
||||
<form method="GET" action="/app/vehicles/">
|
||||
<input type="hidden" name="beneficiaryid" value="{{.ViewState.ID}}">
|
||||
<div class="py-4 grid grid-cols-2">
|
||||
<div class="lg:col-span-1">
|
||||
<label for="startdate" class="block text-sm font-medium text-gray-700">Du</label>
|
||||
<div class="mt-1">
|
||||
<input type="date" id="startdate" name="startdate"
|
||||
class="shadow-sm focus:ring-co-blue focus:border-co-blue block w-full sm:text-sm border-gray-300 rounded-l-2xl border-r-1">
|
||||
</div>
|
||||
</div>
|
||||
<div class="lg:col-span-1">
|
||||
<label for="enddate" class="block text-sm font-medium text-gray-700">Au</label>
|
||||
<div class="mt-1">
|
||||
<input type="date" id="enddate" name="enddate"
|
||||
class="shadow-sm focus:ring-co-blue focus:border-co-blue block w-full sm:text-sm border-gray-300 rounded-r-2xl border-l-0">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{{template "vehicle_type_select" .}}
|
||||
|
||||
<button type="submit"
|
||||
class="rounded-2xl border border-transparent bg-co-blue px-4 py-2 my-4 mt-8 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">
|
||||
Chercher
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
|
@ -120,10 +120,10 @@
|
|||
:class="tab == 'events' ? 'border-co-blue text-co-blue' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'">
|
||||
Dispositifs </a>
|
||||
|
||||
<a href="#" @click="tab = 'files'"
|
||||
<!-- <a href="#" @click="tab = 'files'"
|
||||
class="whitespace-nowrap py-4 px-1 border-b-2 font-medium text-sm"
|
||||
:class="tab == 'files' ? 'border-co-blue text-co-blue' : 'border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300'">
|
||||
Documents </a>
|
||||
Documents </a> -->
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -131,6 +131,7 @@
|
|||
|
||||
<div x-show="tab == 'notes'">{{template "beneficiary_notes" .}}</div>
|
||||
<div x-show="tab == 'journeys'">{{template "beneficiary_journeys" .}}</div>
|
||||
<div x-show="tab == 'vehicles'">{{template "beneficiary_vehicles" .}}</div>
|
||||
<div x-show="tab == 'events'">{{template "beneficiary_events" .}}</div>
|
||||
<div x-show="tab == 'files'">{{template "beneficiary_files" .}}</div>
|
||||
</div>
|
||||
|
@ -141,162 +142,7 @@
|
|||
<section aria-labelledby="timeline-title" class="lg:col-start-3 lg:col-span-1">
|
||||
<div class="bg-white px-4 py-5 shadow sm:rounded-lg sm:px-6">
|
||||
<h2 id="timeline-title" class="text-lg font-medium text-gray-900">Actions réalisées</h2>
|
||||
|
||||
<!-- Activity Feed -->
|
||||
<div class="mt-6 flow-root">
|
||||
<ul role="list" class="-mb-8">
|
||||
<li>
|
||||
<div class="relative pb-8">
|
||||
<span class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200"
|
||||
aria-hidden="true"></span>
|
||||
<div class="relative flex space-x-3">
|
||||
<div>
|
||||
<span
|
||||
class="h-8 w-8 rounded-full bg-gray-400 flex items-center justify-center ring-8 ring-white">
|
||||
<!-- Heroicon name: solid/user -->
|
||||
<svg class="w-5 h-5 text-white" xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd"
|
||||
d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z"
|
||||
clip-rule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4">
|
||||
<div>
|
||||
<p class="text-sm text-gray-500">Applied to <a href="#"
|
||||
class="font-medium text-gray-900">Front End Developer</a></p>
|
||||
</div>
|
||||
<div class="text-right text-sm whitespace-nowrap text-gray-500">
|
||||
<time datetime="2020-09-20">Sep 20</time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div class="relative pb-8">
|
||||
<span class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200"
|
||||
aria-hidden="true"></span>
|
||||
<div class="relative flex space-x-3">
|
||||
<div>
|
||||
<span
|
||||
class="h-8 w-8 rounded-full bg-blue-500 flex items-center justify-center ring-8 ring-white">
|
||||
<!-- Heroicon name: solid/thumb-up -->
|
||||
<svg class="w-5 h-5 text-white" xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path
|
||||
d="M2 10.5a1.5 1.5 0 113 0v6a1.5 1.5 0 01-3 0v-6zM6 10.333v5.43a2 2 0 001.106 1.79l.05.025A4 4 0 008.943 18h5.416a2 2 0 001.962-1.608l1.2-6A2 2 0 0015.56 8H12V4a2 2 0 00-2-2 1 1 0 00-1 1v.667a4 4 0 01-.8 2.4L6.8 7.933a4 4 0 00-.8 2.4z" />
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4">
|
||||
<div>
|
||||
<p class="text-sm text-gray-500">Advanced to phone screening by <a href="#"
|
||||
class="font-medium text-gray-900">Bethany Blake</a></p>
|
||||
</div>
|
||||
<div class="text-right text-sm whitespace-nowrap text-gray-500">
|
||||
<time datetime="2020-09-22">Sep 22</time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div class="relative pb-8">
|
||||
<span class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200"
|
||||
aria-hidden="true"></span>
|
||||
<div class="relative flex space-x-3">
|
||||
<div>
|
||||
<span
|
||||
class="h-8 w-8 rounded-full bg-green-500 flex items-center justify-center ring-8 ring-white">
|
||||
<!-- Heroicon name: solid/check -->
|
||||
<svg class="w-5 h-5 text-white" xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd"
|
||||
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
||||
clip-rule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4">
|
||||
<div>
|
||||
<p class="text-sm text-gray-500">Completed phone screening with <a href="#"
|
||||
class="font-medium text-gray-900">Martha Gardner</a></p>
|
||||
</div>
|
||||
<div class="text-right text-sm whitespace-nowrap text-gray-500">
|
||||
<time datetime="2020-09-28">Sep 28</time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div class="relative pb-8">
|
||||
<span class="absolute top-4 left-4 -ml-px h-full w-0.5 bg-gray-200"
|
||||
aria-hidden="true"></span>
|
||||
<div class="relative flex space-x-3">
|
||||
<div>
|
||||
<span
|
||||
class="h-8 w-8 rounded-full bg-blue-500 flex items-center justify-center ring-8 ring-white">
|
||||
<!-- Heroicon name: solid/thumb-up -->
|
||||
<svg class="w-5 h-5 text-white" xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path
|
||||
d="M2 10.5a1.5 1.5 0 113 0v6a1.5 1.5 0 01-3 0v-6zM6 10.333v5.43a2 2 0 001.106 1.79l.05.025A4 4 0 008.943 18h5.416a2 2 0 001.962-1.608l1.2-6A2 2 0 0015.56 8H12V4a2 2 0 00-2-2 1 1 0 00-1 1v.667a4 4 0 01-.8 2.4L6.8 7.933a4 4 0 00-.8 2.4z" />
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4">
|
||||
<div>
|
||||
<p class="text-sm text-gray-500">Advanced to interview by <a href="#"
|
||||
class="font-medium text-gray-900">Bethany Blake</a></p>
|
||||
</div>
|
||||
<div class="text-right text-sm whitespace-nowrap text-gray-500">
|
||||
<time datetime="2020-09-30">Sep 30</time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li>
|
||||
<div class="relative pb-8">
|
||||
<div class="relative flex space-x-3">
|
||||
<div>
|
||||
<span
|
||||
class="h-8 w-8 rounded-full bg-green-500 flex items-center justify-center ring-8 ring-white">
|
||||
<!-- Heroicon name: solid/check -->
|
||||
<svg class="w-5 h-5 text-white" xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd"
|
||||
d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z"
|
||||
clip-rule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
</div>
|
||||
<div class="min-w-0 flex-1 pt-1.5 flex justify-between space-x-4">
|
||||
<div>
|
||||
<p class="text-sm text-gray-500">Completed interview with <a href="#"
|
||||
class="font-medium text-gray-900">Katherine Snyder</a></p>
|
||||
</div>
|
||||
<div class="text-right text-sm whitespace-nowrap text-gray-500">
|
||||
<time datetime="2020-10-04">Oct 4</time>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="mt-6 flex flex-col justify-stretch">
|
||||
<button type="button"
|
||||
class="inline-flex items-center justify-center px-4 py-2 border border-transparent text-sm font-medium rounded-md shadow-sm text-white bg-blue-600 hover:bg-blue-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-blue-500">Advance
|
||||
to offer</button>
|
||||
</div>
|
||||
<p class="p-12 text-gray-500 text-center text-md">Aucune action réalisée pour le moment</p>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
|
|
@ -3,6 +3,67 @@
|
|||
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
|
||||
<h1 class="text-2xl font-semibold text-gray-900">Tableau de bord</h1>
|
||||
</div>
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-8">
|
||||
<h2 class="text-gray-500 text-xs font-medium uppercase tracking-wide">Statistiques de votre organisation</h2>
|
||||
<ul role="list" class="mt-3 grid grid-cols-1 gap-5 sm:gap-6 sm:grid-cols-2 lg:grid-cols-4">
|
||||
<li class="col-span-1 flex shadow-sm rounded-3xl">
|
||||
<div
|
||||
class="flex-shrink-0 flex items-center justify-center w-16 bg-co-blue text-white text-sm font-medium rounded-l-3xl">
|
||||
{{.IconSet.Icon "hero:outline/user-group" "h-6 w-6"}}
|
||||
</div>
|
||||
<div
|
||||
class="flex-1 flex items-center justify-between border-t border-r border-b border-gray-200 bg-white rounded-r-3xl truncate">
|
||||
<div class="flex-1 px-4 py-2 text-sm truncate">
|
||||
<a href="#" class="text-gray-900 font-medium hover:text-gray-600">Bénéficiaires</a>
|
||||
<p class="text-gray-500">{{.ViewState.beneficiaries.count}} bénéficiaires</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="col-span-1 flex shadow-sm rounded-3xl">
|
||||
<div
|
||||
class="flex-shrink-0 flex items-center justify-center w-16 bg-co-green text-white text-sm font-medium rounded-l-3xl">
|
||||
{{.IconSet.Icon "hero:outline/shield-check" "h-6 w-6"}}
|
||||
</div>
|
||||
<div
|
||||
class="flex-1 flex items-center justify-between border-t border-r border-b border-gray-200 bg-white rounded-r-3xl truncate">
|
||||
<div class="flex-1 px-4 py-2 text-sm truncate">
|
||||
<a href="#" class="text-gray-900 font-medium hover:text-gray-600">Accompagnement</a>
|
||||
<p class="text-gray-500">0 actions réalisées</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="col-span-1 flex shadow-sm rounded-3xl">
|
||||
<div
|
||||
class="flex-shrink-0 flex items-center justify-center w-16 bg-co-yellow text-white text-sm font-medium rounded-l-3xl">
|
||||
{{.IconSet.Icon "hero:outline/office-building" "h-6 w-6"}}
|
||||
</div>
|
||||
<div
|
||||
class="flex-1 flex items-center justify-between border-t border-r border-b border-gray-200 bg-white rounded-r-3xl truncate">
|
||||
<div class="flex-1 px-4 py-2 text-sm truncate">
|
||||
<a href="#" class="text-gray-900 font-medium hover:text-gray-600">Groupes</a>
|
||||
<p class="text-gray-500">0 groupes créés</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
|
||||
<li class="col-span-1 flex shadow-sm rounded-3xl">
|
||||
<div
|
||||
class="flex-shrink-0 flex items-center justify-center w-16 bg-co-red text-white text-sm font-medium rounded-l-3xl">
|
||||
{{.IconSet.Icon "hero:outline/briefcase" "h-6 w-6"}}
|
||||
</div>
|
||||
<div
|
||||
class="flex-1 flex items-center justify-between border-t border-r border-b border-gray-200 bg-white rounded-r-3xl truncate">
|
||||
<div class="flex-1 px-4 py-2 text-sm truncate">
|
||||
<a href="#" class="text-gray-900 font-medium hover:text-gray-600">Référents</a>
|
||||
<p class="text-gray-500">53 membres</p>
|
||||
</div>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="max-w-7xl mx-auto py-8 px-4 sm:px-6 md:px-8">
|
||||
<div class="py-4 grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
|
||||
|
|
|
@ -118,8 +118,8 @@
|
|||
x-transition:leave-start="transform opacity-100 scale-100"
|
||||
x-transition:leave-end="transform opacity-0 scale-95">
|
||||
<!-- Active: "bg-gray-100", Not Active: "" -->
|
||||
<a href="/app/group/settings" class="block px-4 py-2 text-sm text-gray-700" role="menuitem" tabindex="-1"
|
||||
id="user-menu-item-1">Paramètres</a>
|
||||
<!-- <a href="/app/group/settings" class="block px-4 py-2 text-sm text-gray-700" role="menuitem" tabindex="-1"
|
||||
id="user-menu-item-1">Paramètres</a> -->
|
||||
|
||||
<a href="/auth/groups/switch" class="block px-4 py-2 text-sm text-gray-700" role="menuitem" tabindex="-1"
|
||||
id="user-menu-item-2">Changer d'organisation</a>
|
||||
|
@ -135,7 +135,7 @@
|
|||
id="user-menu-button" aria-expanded="false" aria-haspopup="true">
|
||||
<span class="sr-only">Open user menu</span>
|
||||
<img class="h-8 w-8 rounded-co"
|
||||
src="https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=facearea&facepad=2&w=256&h=256&q=80"
|
||||
src="http://localhost:9000/app/beneficiaries/e7616eac-4a87-4396-a505-23e0421b9c4c/picture"
|
||||
alt="Menu utilisateur">
|
||||
</button>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,137 @@
|
|||
{{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éservation de véhicule</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/vehicles-management/fleet/add">
|
||||
<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">
|
||||
Annuler
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-8 max-w-3xl mx-auto grid grid-cols-1 gap-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-1">
|
||||
<div class="bg-white shadow sm:rounded-2xl">
|
||||
<h2 id="timeline-title" class="text-lg font-medium text-gray-900 p-4 sm:px-6">Bénéficiaire</h2>
|
||||
<div class="border-t border-gray-200 px-4 py-5 sm:px-6">
|
||||
<div>
|
||||
<div class="mt-5 border-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">
|
||||
<dt class="text-sm font-medium text-gray-500">Nom</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
{{.ViewState.beneficiary.Data.first_name}}
|
||||
{{.ViewState.beneficiary.Data.last_name}}</dd>
|
||||
</div>
|
||||
<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">Email</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
{{.ViewState.beneficiary.Data.email}}</dd>
|
||||
</div>
|
||||
<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">Téléphone</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
{{.ViewState.beneficiary.Data.phone_number}}</dd>
|
||||
</div>
|
||||
{{if .ViewState.Data.birthdate}}
|
||||
<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 naissance</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{(timeFrom
|
||||
.ViewState.Data.birthdate).Format
|
||||
"02/01/2006"}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if and .ViewState.Data.gender (ne .ViewState.Data.gender "0")}}
|
||||
<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 naissance</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{genderISO5218
|
||||
.ViewState.Data.gender}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if .ViewState.Data.address}}
|
||||
<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>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
{{.ViewState.Data.address.properties.label}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="lg:col-start-2 lg:col-span-2">
|
||||
<div class="bg-white shadow sm:rounded-2xl sm:px-6">
|
||||
<div class="bg-white px-4 py-5 border-b border-gray-200 sm:px-6">
|
||||
<div class="-ml-4 -mt-4 flex justify-between items-center flex-wrap sm:flex-nowrap">
|
||||
<div class="ml-4 mt-4">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">Réservation</h3>
|
||||
<p class="mt-1 text-sm text-gray-500">Informations utiles sur la réservation.</p>
|
||||
</div>
|
||||
<div class="ml-4 mt-4 flex-shrink-0">
|
||||
<button type="button"
|
||||
class="relative inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-xs font-medium rounded-2xl text-co-blue bg-gray-100 hover:bg-co-blue hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">SMS</button>
|
||||
<button type="button"
|
||||
class="relative inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-xs font-medium rounded-2xl text-co-blue bg-gray-100 hover:bg-co-blue hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">Email</button>
|
||||
<button type="button"
|
||||
class="relative inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-xs font-medium rounded-2xl text-co-blue bg-gray-100 hover:bg-co-blue hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">Imprimer</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-4 py-5 sm:px-6">
|
||||
<div>
|
||||
<div class="mt-5 border-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">
|
||||
<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">
|
||||
COOPGO
|
||||
</dd>
|
||||
</div>
|
||||
<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>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
{{.ViewState.vehicle.Data.name}}</dd>
|
||||
</div>
|
||||
<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">Immatriculation</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
{{.ViewState.vehicle.Data.licence_plate}}</dd>
|
||||
</div>
|
||||
<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">Type</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
Voiture</dd>
|
||||
</div>
|
||||
{{if .ViewState.vehicle.Data.address}}
|
||||
<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">Lieu de récupération</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{.ViewState.vehicle.Data.address.properties.label}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
<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>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{(timeFrom .ViewState.booking.Startdate).Format
|
||||
"02/01/2006"}}</dd>
|
||||
</div>
|
||||
<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>
|
||||
<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>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
|
@ -0,0 +1,158 @@
|
|||
{{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">Véhicules partagés</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/vehicles-management/fleet/add">
|
||||
<button type="button"
|
||||
class="inline-flex items-center justify-center rounded-2xl border border-transparent bg-co-blue px-4 py-2 text-sm font-medium text-white shadow-sm focus:outline-none focus:ring-2 focus:ring-co-blue focus:ring-offset-2 sm:w-auto">
|
||||
Voir les prêts de véhicules
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="mt-8 max-w-3xl mx-auto grid grid-cols-1 gap-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-1">
|
||||
<div class="bg-white shadow sm:rounded-2xl">
|
||||
<h2 id="timeline-title" class="text-lg font-medium text-gray-900 p-4 sm:px-6">Chercher un véhicule</h2>
|
||||
<div class="border-t border-gray-200 px-4 py-5 sm:px-6">
|
||||
<form method="GET">
|
||||
|
||||
|
||||
<div x-data="{
|
||||
text: '{{if .ViewState.search}}{{.ViewState.search.beneficiary.Data.first_name}} {{.ViewState.search.beneficiary.Data.last_name}}{{end}}',
|
||||
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: null,
|
||||
},
|
||||
selectbeneficiary(beneficiary) {
|
||||
console.log(beneficiary)
|
||||
this.fields.beneficiaryid = beneficiary.id
|
||||
this.text = beneficiary.data.first_name + ' ' + beneficiary.data.last_name
|
||||
this.beneficiariesListOpen = false
|
||||
}
|
||||
}">
|
||||
<input type="hidden" name="beneficiaryid" x-model="fields.beneficiaryid">
|
||||
<label for="combobox" class="block text-sm font-medium text-gray-700">Bénéficiaire</label>
|
||||
<div class="relative mt-1 mb-4">
|
||||
<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">
|
||||
<!--
|
||||
Combobox option, manage highlight styles based on mouseenter/mouseleave and keyboard navigation.
|
||||
|
||||
Active: "text-white bg-indigo-600", Not Active: "text-gray-900"
|
||||
-->
|
||||
<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">
|
||||
<!-- Selected: "font-semibold" -->
|
||||
<span class="truncate" x-text="beneficiary.data.first_name"></span> <span class="truncate" x-text="beneficiary.data.last_name"></span>
|
||||
|
||||
<!--
|
||||
Checkmark, only display for selected option.
|
||||
|
||||
Active: "text-white", Not Active: "text-indigo-600"
|
||||
-->
|
||||
<span class="absolute inset-y-0 right-0 flex items-center pr-4 text-co-blue">
|
||||
<!-- Heroicon name: solid/check -->
|
||||
<!-- <svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z" clip-rule="evenodd" />
|
||||
</svg> -->
|
||||
</span>
|
||||
</li>
|
||||
</template>
|
||||
|
||||
<!-- More items... -->
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- {{ $fieldName := "address" }}
|
||||
{{ template "address_autocomplete" dict "FieldName" $fieldName }} -->
|
||||
<div class="py-4 grid grid-cols-2">
|
||||
<div class="lg:col-span-1">
|
||||
<label for="startdate" class="block text-sm font-medium text-gray-700">Du</label>
|
||||
<div class="mt-1">
|
||||
<input type="date" id="startdate" name="startdate" value="{{.ViewState.search.startdate}}"
|
||||
class="shadow-sm focus:ring-co-blue focus:border-co-blue block w-full sm:text-sm border-gray-300 rounded-l-2xl border-r-1">
|
||||
</div>
|
||||
</div>
|
||||
<div class="lg:col-span-1">
|
||||
<label for="enddate" class="block text-sm font-medium text-gray-700">Au</label>
|
||||
<div class="mt-1">
|
||||
<input type="date" id="enddate" name="enddate" value="{{.ViewState.search.enddate}}"
|
||||
class="shadow-sm focus:ring-co-blue focus:border-co-blue block w-full sm:text-sm border-gray-300 rounded-r-2xl border-l-0">
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
{{template "vehicle_type_select" .}}
|
||||
|
||||
<button type="submit"
|
||||
class="rounded-2xl border border-transparent bg-co-blue px-4 py-2 my-4 mt-8 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">
|
||||
Chercher
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="lg:col-start-2 lg:col-span-2">
|
||||
{{if .ViewState.searched}}
|
||||
<div class="bg-white px-4 py-5 shadow sm:rounded-2xl sm:px-6">
|
||||
<h2 id="timeline-title" class="text-lg font-medium text-gray-900">Véhicules disponibles</h2>
|
||||
<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">
|
||||
<table class="min-w-full divide-y divide-gray-300">
|
||||
<thead>
|
||||
<tr>
|
||||
<th scope="col" class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6 md:pl-0">Véhicule</th>
|
||||
<th scope="col" class="py-3.5 px-3 text-left text-sm font-semibold text-gray-900">Numéro</th>
|
||||
<th scope="col" class="py-3.5 px-3 text-left text-sm font-semibold text-gray-900">Gestionnaire</th>
|
||||
<th scope="col" class="py-3.5 px-3 text-left text-sm font-semibold text-gray-900">Lieu</th>
|
||||
<th scope="col" class="relative py-3.5 pl-3 pr-4 sm:pr-6 md:pr-0">
|
||||
<span class="sr-only">Réserver</span>
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-200">
|
||||
{{range .ViewState.search.vehicles}}
|
||||
<tr>
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm font-medium text-gray-900 sm:pl-6 md:pl-0">{{.Data.name}}</td>
|
||||
<td class="whitespace-nowrap py-4 px-3 text-sm text-gray-500">{{.Data.licence_plate}}</td>
|
||||
<td class="whitespace-nowrap py-4 px-3 text-sm text-gray-500">COOPGO</td>
|
||||
<td class="whitespace-nowrap py-4 px-3 text-sm text-gray-500">{{if .Data.address}}{{.Data.address.properties.label}}{{end}}</td>
|
||||
<td class="relative whitespace-nowrap py-4 pl-3 pr-4 text-right text-sm font-medium sm:pr-6 md:pr-0">
|
||||
<a href="/app/vehicles/v/{{.ID}}/b/{{$.ViewState.search.beneficiary.ID}}?startdate={{$.ViewState.search.startdate}}&enddate={{$.ViewState.search.enddate}}" class="text-co-blue hover:text-co-blue">Réserver<span class="sr-only"> pour {{$.ViewState.search.beneficiary.Data.first_name}} {{$.ViewState.search.beneficiary.Data.last_name}}</span></a>
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
|
@ -7,26 +7,23 @@
|
|||
<table class="min-w-full divide-y divide-gray-300">
|
||||
<thead class="bg-gray-50">
|
||||
<tr>
|
||||
<th scope="col"
|
||||
<!-- <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">
|
||||
</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">
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
||||
Immatriculation
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||
<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">
|
||||
Prescripteur
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
||||
Gestionnaire
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||
<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">
|
||||
|
@ -35,33 +32,38 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-200 bg-white">
|
||||
{{range .ViewState.vehicles}}
|
||||
{{$vehicle := .}}
|
||||
{{range .Bookings}}
|
||||
<tr>
|
||||
<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>
|
||||
</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" >aa</div>
|
||||
<div class="text-gray-900" >{{$vehicle.Data.licence_plate}}</div>
|
||||
</td>
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||
<div class="text-gray-900" ></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" >COOPGO</div>
|
||||
</td>
|
||||
<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" >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">
|
||||
<div class="text-gray-900" >aa</div>
|
||||
</td>
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||
<div class="text-gray-900" >aa</div>
|
||||
</td>
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||
<div class="text-gray-900" >aa</div>
|
||||
</td>
|
||||
<td class="whitespace-nowrap py-4 pl-4 pr-3 text-sm sm:pl-6">
|
||||
<a :href="'/app/beneficiaries/' + beneficiary.id"
|
||||
<a href="/app/vehicles-management/bookings/{{.ID}}"
|
||||
class="text-co-blue hover:text-co-blue">Voir</a>
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,259 @@
|
|||
{{define "calendar"}}
|
||||
<div class="flex items-center">
|
||||
<h2 class="flex-auto font-semibold text-gray-900">Août 2022</h2>
|
||||
<button type="button"
|
||||
class="-my-1.5 flex flex-none items-center justify-center p-1.5 text-gray-400 hover:text-gray-500">
|
||||
<span class="sr-only">Mois précédent</span>
|
||||
<!-- Heroicon name: solid/chevron-left -->
|
||||
<svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"
|
||||
aria-hidden="true">
|
||||
<path fill-rule="evenodd"
|
||||
d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
|
||||
clip-rule="evenodd" />
|
||||
</svg>
|
||||
</button>
|
||||
<button type="button"
|
||||
class="-my-1.5 -mr-1.5 ml-2 flex flex-none items-center justify-center p-1.5 text-gray-400 hover:text-gray-500">
|
||||
<span class="sr-only">Mois suivant</span>
|
||||
<!-- Heroicon name: solid/chevron-right -->
|
||||
<svg class="h-5 w-5" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 20 20" fill="currentColor"
|
||||
aria-hidden="true">
|
||||
<path fill-rule="evenodd"
|
||||
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
|
||||
clip-rule="evenodd" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
<div class="mt-10 grid grid-cols-7 text-center text-xs leading-6 text-gray-500">
|
||||
<div>L</div>
|
||||
<div>M</div>
|
||||
<div>M</div>
|
||||
<div>J</div>
|
||||
<div>V</div>
|
||||
<div>S</div>
|
||||
<div>D</div>
|
||||
</div>
|
||||
<div class="mt-2 grid grid-cols-7 text-sm">
|
||||
<div class="py-2">
|
||||
<!--
|
||||
Always include: "mx-auto flex h-8 w-8 items-center justify-center rounded-full"
|
||||
Is selected, include: "text-white"
|
||||
Is not selected and is today, include: "text-indigo-600"
|
||||
Is not selected and is not today and is current month, include: "text-gray-900"
|
||||
Is not selected and is not today and is not current month, include: "text-gray-400"
|
||||
Is selected and is today, include: "bg-indigo-600"
|
||||
Is selected and is not today, include: "bg-gray-900"
|
||||
Is not selected, include: "hover:bg-gray-200"
|
||||
Is selected or is today, include: "font-semibold"
|
||||
-->
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-01">1</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-02">2</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-03">3</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-04">4</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-05">5</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-06">6</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-07">7</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-08">8</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-09">9</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-10">10</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-11">11</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full bg-gray-900 font-semibold text-white">
|
||||
<time datetime="2022-08-12">12</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-13">13</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-14">14</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-15">15</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-16">16</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-17">17</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-18">18</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-19">19</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-20">20</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-21">21</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-22">22</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-23">23</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-24">24</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-25">25</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-26">26</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-27">27</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-28">28</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-29">29</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-30">30</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-900 hover:bg-gray-200">
|
||||
<time datetime="2022-08-31">31</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-400 hover:bg-gray-200">
|
||||
<time datetime="2022-09-01">1</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-400 hover:bg-gray-200">
|
||||
<time datetime="2022-09-02">2</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-400 hover:bg-gray-200">
|
||||
<time datetime="2022-09-03">3</time>
|
||||
</button>
|
||||
</div>
|
||||
<div class="border-t border-gray-200 py-2">
|
||||
<button type="button"
|
||||
class="mx-auto flex h-8 w-8 items-center justify-center rounded-full text-gray-400 hover:bg-gray-200">
|
||||
<time datetime="2022-09-04">4</time>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
|
@ -9,16 +9,16 @@
|
|||
<tr>
|
||||
<th scope="col"
|
||||
class="py-3.5 pl-4 pr-3 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
||||
Immatriculation
|
||||
Numéro (Immat / Bicycode)
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||
Gestionnaire
|
||||
<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">
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900 sm:pl-6">
|
||||
Modèle
|
||||
</th>
|
||||
<th scope="col" class="px-3 py-3.5 text-left text-sm font-semibold text-gray-900">
|
||||
Gestionnaire
|
||||
<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="relative py-3.5 pl-3 pr-4 sm:pr-6">
|
||||
<span class="sr-only">Actions</span>
|
||||
|
@ -26,24 +26,26 @@
|
|||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-gray-200 bg-white">
|
||||
{{range .ViewState.vehicles}}
|
||||
<tr>
|
||||
<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" >{{.Data.licence_plate}}</div>
|
||||
</td>
|
||||
<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" >{{if eq .Type "electric_bike"}}Vélo électrique{{else}}Voiture{{end}}</div>
|
||||
</td>
|
||||
<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" >{{.Data.name}}</div>
|
||||
</td>
|
||||
<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" >{{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">
|
||||
<a :href="'/app/beneficiaries/' + beneficiary.id"
|
||||
<a href="/app/vehicles-management/fleet/{{.ID}}"
|
||||
class="text-co-blue hover:text-co-blue">Voir</a>
|
||||
</td>
|
||||
</tr>
|
||||
{{end}}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
|
|
@ -0,0 +1,147 @@
|
|||
{{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éservation de véhicule</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/vehicles-management/bookings/{{.ViewState.booking.ID}}/delete">
|
||||
<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">
|
||||
Annuler
|
||||
</button>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-8 max-w-3xl mx-auto grid grid-cols-1 gap-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-1">
|
||||
<div class="bg-white shadow sm:rounded-2xl">
|
||||
<h2 id="timeline-title" class="text-lg font-medium text-gray-900 p-4 sm:px-6">Bénéficiaire</h2>
|
||||
<div class="border-t border-gray-200 px-4 py-5 sm:px-6">
|
||||
<div>
|
||||
<div class="mt-5 border-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">
|
||||
<dt class="text-sm font-medium text-gray-500">Nom</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
{{.ViewState.beneficiary.Data.first_name}}
|
||||
{{.ViewState.beneficiary.Data.last_name}}</dd>
|
||||
</div>
|
||||
<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">Email</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
{{.ViewState.beneficiary.Data.email}}</dd>
|
||||
</div>
|
||||
<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">Téléphone</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
{{.ViewState.beneficiary.Data.phone_number}}</dd>
|
||||
</div>
|
||||
{{if .ViewState.Data.birthdate}}
|
||||
<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 naissance</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{(timeFrom
|
||||
.ViewState.Data.birthdate).Format
|
||||
"02/01/2006"}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if and .ViewState.Data.gender (ne .ViewState.Data.gender "0")}}
|
||||
<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 naissance</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{genderISO5218
|
||||
.ViewState.Data.gender}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if .ViewState.Data.address}}
|
||||
<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>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
{{.ViewState.Data.address.properties.label}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="lg:col-start-2 lg:col-span-2">
|
||||
<div class="bg-white shadow sm:rounded-2xl sm:px-6">
|
||||
<div class="bg-white px-4 py-5 border-b border-gray-200 sm:px-6">
|
||||
<div class="-ml-4 -mt-4 flex justify-between items-center flex-wrap sm:flex-nowrap">
|
||||
<div class="ml-4 mt-4">
|
||||
<h3 class="text-lg leading-6 font-medium text-gray-900">Réservation</h3>
|
||||
<p class="mt-1 text-sm text-gray-500">Informations utiles sur la réservation.</p>
|
||||
</div>
|
||||
<div class="ml-4 mt-4 flex-shrink-0">
|
||||
<button type="button"
|
||||
class="relative inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-xs font-medium rounded-2xl text-co-blue bg-gray-100 hover:bg-co-blue hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">SMS</button>
|
||||
<button type="button"
|
||||
class="relative inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-xs font-medium rounded-2xl text-co-blue bg-gray-100 hover:bg-co-blue hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">Email</button>
|
||||
<button type="button"
|
||||
class="relative inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-xs font-medium rounded-2xl text-co-blue bg-gray-100 hover:bg-co-blue hover:text-white focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">Imprimer</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="px-4 py-5 sm:px-6">
|
||||
<div>
|
||||
<div class="mt-5 border-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">
|
||||
<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">
|
||||
COOPGO
|
||||
</dd>
|
||||
</div>
|
||||
<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>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
{{.ViewState.vehicle.Data.name}}</dd>
|
||||
</div>
|
||||
<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">Immatriculation</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
{{.ViewState.vehicle.Data.licence_plate}}</dd>
|
||||
</div>
|
||||
<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">Type</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">
|
||||
Voiture</dd>
|
||||
</div>
|
||||
{{if .ViewState.vehicle.Data.address}}
|
||||
<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">Lieu de récupération</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{.ViewState.vehicle.Data.address.properties.label}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
<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>
|
||||
<dd class="mt-1 text-sm text-gray-900 sm:mt-0 sm:col-span-2">{{(timeFrom .ViewState.booking.Startdate).Format
|
||||
"02/01/2006"}}</dd>
|
||||
</div>
|
||||
<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>
|
||||
<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>
|
||||
</div>
|
||||
<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>
|
||||
<dd class="mt-1 text-sm font-bold text-co-red sm:mt-0 sm:col-span-2">{{(timeFrom .ViewState.booking.Unavailablefrom).Format
|
||||
"02/01/2006"}}</dd>
|
||||
</div>
|
||||
<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>
|
||||
<dd class="mt-1 text-sm font-bold text-co-green sm:mt-0 sm:col-span-2">{{(timeFrom .ViewState.booking.Unavailableto).Format
|
||||
"02/01/2006"}}</dd>
|
||||
</div>
|
||||
</dl>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{{end}}
|
|
@ -0,0 +1,90 @@
|
|||
{{define "content"}}
|
||||
<main class="py-10">
|
||||
<div class="max-w-3xl mx-auto px-4 sm:px-6 md:flex md:items-center md:justify-between md:space-x-5 lg:max-w-7xl lg:px-8">
|
||||
<div class="flex items-center space-x-5">
|
||||
<!-- <div class="flex-shrink-0">
|
||||
<div class="relative">
|
||||
<img class="h-16 w-16 rounded-co" src="/app/beneficiaries/{{.ViewState.ID}}/picture" alt="">
|
||||
<span class="absolute inset-0 shadow-inner rounded-full" aria-hidden="true"></span>
|
||||
</div>
|
||||
</div> -->
|
||||
<div>
|
||||
<h1 class="text-2xl font-bold text-gray-900">{{.ViewState.vehicle.Data.name}}</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="mt-6 flex flex-col-reverse justify-stretch space-y-4 space-y-reverse sm:flex-row-reverse sm:justify-end sm:space-x-reverse sm:space-y-0 sm:space-x-3 md:mt-0 md:flex-row md:space-x-3">
|
||||
<button type="button"
|
||||
class="inline-flex items-center justify-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-2xl text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-co-blue">Retirer de la flotte</button>
|
||||
<a href="/app/vehicles-management/fleet/{{.ViewState.vehicle.ID}}/update" class="inline-flex"><button type="button"
|
||||
class="w-full px-4 py-2 border border-transparent text-sm font-medium rounded-2xl shadow-sm text-white bg-co-blue hover:bg-co-blue focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-co-blue">Modifier</button></a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="mt-8 max-w-3xl mx-auto grid grid-cols-1 gap-6 sm:px-6 lg:max-w-7xl lg:grid-flow-col-dense lg:grid-cols-3">
|
||||
<div class="space-y-6 lg:col-start-1 lg:col-span-2">
|
||||
<section aria-labelledby="vehicle-information-title">
|
||||
<div class="bg-white shadow sm:rounded-lg">
|
||||
<div class="px-4 py-5 sm:px-6">
|
||||
<h2 id="vehicle-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 véhicule</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.vehicle.Data.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">{{if eq .ViewState.vehicle.Data.type "electric_bike"}}Vélo électrique{{else}}Voiture{{end}}</dd>
|
||||
</div>
|
||||
{{else}}
|
||||
<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">Voiture</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if .ViewState.vehicle.Data.licence_plate}}
|
||||
<div class="sm:col-span-1">
|
||||
<dt class="text-sm font-medium text-gray-500">Numéro (Immatriculation, bicycode, ...)</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900">{{.ViewState.vehicle.Data.licence_plate}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if .ViewState.vehicle.Data.address}}
|
||||
<div class="sm:col-span-1">
|
||||
<dt class="text-sm font-medium text-gray-500">Lieu</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900">{{.ViewState.vehicle.Data.address.properties.label}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
{{if .ViewState.vehicle.Data.informations}}
|
||||
<div class="sm:col-span-2">
|
||||
<dt class="text-sm font-medium text-gray-500">Informations pratiques pour le bénéficiaire</dt>
|
||||
<dd class="mt-1 text-sm text-gray-900">{{.ViewState.vehicle.Data.informations}}</dd>
|
||||
</div>
|
||||
{{end}}
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
<section aria-labelledby="timeline-title" class="lg:col-start-3 lg:col-span-1">
|
||||
<div class="bg-white px-4 py-5 shadow sm:rounded-lg sm:px-6">
|
||||
<h2 id="timeline-title" class="text-lg font-medium text-gray-900">Réservations à venir</h2>
|
||||
{{if eq (len .ViewState.vehicle.Bookings) 0}}
|
||||
<p class="p-12 text-gray-500 text-center text-md">Aucune réservation à venir</p>
|
||||
{{end}}
|
||||
<ul role="list" class="divide-y divide-gray-200">
|
||||
{{range .ViewState.vehicle.Bookings}}
|
||||
<li class="py-4 flex">
|
||||
<div class="ml-3">
|
||||
<a href="/vehicles/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 text-gray-500"></p>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
{{end}}
|
||||
</ul>
|
||||
{{template "calendar" .}}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
{{end}}
|
|
@ -0,0 +1,106 @@
|
|||
{{define "content"}}
|
||||
|
||||
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8">
|
||||
<h1 class="text-2xl font-semibold text-gray-900">Modifier un véhicule</h1>
|
||||
</div>
|
||||
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 md:px-8 mt-8" x-data="{
|
||||
fields: {
|
||||
licence_plate: '{{ .ViewState.vehicle.Data.licence_plate }}',
|
||||
name: '{{ .ViewState.vehicle.Data.name }}',
|
||||
},
|
||||
rules: {
|
||||
licence_plate: ['required', 'regexMatch:^[A-Z]{1,2}-[0-9]{1,3}-[A-Z]{1,2}$'],
|
||||
name: ['required'],
|
||||
},
|
||||
formValidation: {
|
||||
valid: false,
|
||||
fields: {
|
||||
name: {valid: null},
|
||||
licence_plate: {valid: null},
|
||||
}
|
||||
},
|
||||
isFormValid: true,
|
||||
validate() {
|
||||
this.formValidation = Iodine.assert(this.fields, this.rules)
|
||||
},
|
||||
validateField(field) {
|
||||
this.formValidation.fields[field] = Iodine.assert(this.fields[field], this.rules[field])
|
||||
},
|
||||
submit(event) {
|
||||
this.validate()
|
||||
if(!this.formValidation.valid) {
|
||||
this.isFormValid = false
|
||||
event.preventDefault()
|
||||
}
|
||||
return this.formValidation.valid
|
||||
}
|
||||
}">
|
||||
<form class="space-y-6" method="POST" @submit="submit">
|
||||
<div class="bg-white shadow px-4 py-5 sm:rounded-lg sm:p-6">
|
||||
<div class="md:grid md:grid-cols-3 md:gap-6">
|
||||
<div class="md:col-span-1">
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900">Identité du véhicule</h3>
|
||||
<p class="mt-1 text-sm text-gray-500">Informations de base sur le véhicule</p>
|
||||
</div>
|
||||
<div class="mt-5 md:mt-0 md:col-span-2">
|
||||
<div class="grid grid-cols-3 md:grid-cols-6 gap-6">
|
||||
<div class="col-span-5">
|
||||
<label for="name" class="block text-sm font-medium text-gray-700">Modèle (ou nom donné au
|
||||
véhicule)</label>
|
||||
<input type="text" name="name" id="name"
|
||||
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm rounded-2xl"
|
||||
x-model="fields.name" @blur="validateField('name')"
|
||||
:class="formValidation.fields.name.valid == false ? 'border-co-red border-2' : 'border-gray-300'">
|
||||
</div>
|
||||
<div class="col-span-3">
|
||||
{{template "vehicle_type_select" .}}
|
||||
</div>
|
||||
<div class="col-span-3">
|
||||
<label for="licence_plate"
|
||||
class="block text-sm font-medium text-gray-700">Immatriculation</label>
|
||||
<input type="text" name="licence_plate" id="licence_plate" placeholder="XX-123-YY"
|
||||
class="mt-1 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm rounded-2xl"
|
||||
x-model="fields.licence_plate"
|
||||
@blur="fields.licence_plate = fields.licence_plate.toUpperCase(); validateField('licence_plate')"
|
||||
:class="formValidation.fields.licence_plate.valid == false ? 'border-co-red border-2' : 'border-gray-300'">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="bg-white shadow px-4 py-5 sm:rounded-lg sm:p-6">
|
||||
<div class="md:grid md:grid-cols-3 md:gap-6">
|
||||
<div class="md:col-span-1">
|
||||
<h3 class="text-lg font-medium leading-6 text-gray-900">Informations pratiques</h3>
|
||||
<p class="mt-1 text-sm text-gray-500">Informations pratiques pour la réservation</p>
|
||||
</div>
|
||||
<div class="mt-5 md:mt-0 md:col-span-2">
|
||||
{{ $fieldName := "address" }}
|
||||
{{ template "address_autocomplete" (dict "FieldName" $fieldName "Address" .ViewState.vehicle.Data.address) }}
|
||||
|
||||
<div class="mt-5">
|
||||
<label for="informations" class="block text-sm font-medium text-gray-700">Informations pratiques pour le bénéficiaire</label>
|
||||
<div class="mt-1">
|
||||
<textarea rows="4" name="informations" id="informations"
|
||||
class="shadow-sm focus:ring-co-blue focus:border-co-blue block w-full sm:text-sm border-gray-300 rounded-2xl"></textarea>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex justify-end">
|
||||
<p x-show="! isFormValid" class="px-4 py-2 text-sm text-co-red">Certains champs de sont pas valides.</p>
|
||||
<a href="/app/vehicles-management/fleet/{{.ViewState.vehicle.ID}}">
|
||||
<button type="button"
|
||||
class="bg-white py-2 px-4 border border-gray-300 rounded-2xl shadow-sm text-sm font-medium text-gray-700 hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">Annuler</button>
|
||||
</a>
|
||||
<button type="submit"
|
||||
class="ml-3 inline-flex justify-center py-2 px-4 border border-transparent shadow-sm text-sm font-medium rounded-2xl text-white bg-co-blue hover:bg-co-blue focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">Modifier
|
||||
le véhicule</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
{{end}}
|
|
@ -17,7 +17,7 @@
|
|||
<div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
|
||||
<a href="/app/vehicles-management/fleet/add">
|
||||
<button type="button"
|
||||
class="inline-flex items-center justify-center rounded-2xl border border-transparent bg-co-blue px-4 py-2 text-sm font-medium text-white shadow-sm focus:outline-none focus:ring-2 focus:ring-ci-blue focus:ring-offset-2 sm:w-auto">
|
||||
class="inline-flex items-center justify-center rounded-2xl border border-transparent bg-co-blue px-4 py-2 text-sm font-medium text-white shadow-sm focus:outline-none focus:ring-2 focus:ring-co-blue focus:ring-offset-2 sm:w-auto">
|
||||
{{$.IconSet.Icon "hero:outline/plus-circle" "h-5 w-5 mr-3"}}
|
||||
Ajouter un véhicule
|
||||
</button>
|
||||
|
|
|
@ -842,6 +842,10 @@ html {
|
|||
grid-column: span 5 / span 5;
|
||||
}
|
||||
|
||||
.m-auto {
|
||||
margin: auto;
|
||||
}
|
||||
|
||||
.mx-auto {
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
|
@ -857,6 +861,21 @@ html {
|
|||
margin-right: -1rem;
|
||||
}
|
||||
|
||||
.-my-1\.5 {
|
||||
margin-top: -0.375rem;
|
||||
margin-bottom: -0.375rem;
|
||||
}
|
||||
|
||||
.-my-1 {
|
||||
margin-top: -0.25rem;
|
||||
margin-bottom: -0.25rem;
|
||||
}
|
||||
|
||||
.my-4 {
|
||||
margin-top: 1rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.-mr-12 {
|
||||
margin-right: -3rem;
|
||||
}
|
||||
|
@ -949,6 +968,26 @@ html {
|
|||
margin-top: -0.5rem;
|
||||
}
|
||||
|
||||
.-mr-1\.5 {
|
||||
margin-right: -0.375rem;
|
||||
}
|
||||
|
||||
.ml-2 {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.-mr-1 {
|
||||
margin-right: -0.25rem;
|
||||
}
|
||||
|
||||
.mb-4 {
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.-mt-4 {
|
||||
margin-top: -1rem;
|
||||
}
|
||||
|
||||
.block {
|
||||
display: block;
|
||||
}
|
||||
|
@ -1117,6 +1156,14 @@ html {
|
|||
flex: 1 1 0%;
|
||||
}
|
||||
|
||||
.flex-auto {
|
||||
flex: 1 1 auto;
|
||||
}
|
||||
|
||||
.flex-none {
|
||||
flex: none;
|
||||
}
|
||||
|
||||
.flex-shrink-0 {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
@ -1174,6 +1221,10 @@ html {
|
|||
user-select: none;
|
||||
}
|
||||
|
||||
.grid-flow-row {
|
||||
grid-auto-flow: row;
|
||||
}
|
||||
|
||||
.grid-cols-6 {
|
||||
grid-template-columns: repeat(6, minmax(0, 1fr));
|
||||
}
|
||||
|
@ -1186,6 +1237,14 @@ html {
|
|||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.grid-cols-7 {
|
||||
grid-template-columns: repeat(7, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.grid-cols-2 {
|
||||
grid-template-columns: repeat(2, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.flex-row {
|
||||
flex-direction: row;
|
||||
}
|
||||
|
@ -1424,6 +1483,16 @@ html {
|
|||
border-bottom-left-radius: 1rem;
|
||||
}
|
||||
|
||||
.rounded-l-2xl {
|
||||
border-top-left-radius: 1rem;
|
||||
border-bottom-left-radius: 1rem;
|
||||
}
|
||||
|
||||
.rounded-r-2xl {
|
||||
border-top-right-radius: 1rem;
|
||||
border-bottom-right-radius: 1rem;
|
||||
}
|
||||
|
||||
.border {
|
||||
border-width: 1px;
|
||||
}
|
||||
|
@ -1452,6 +1521,14 @@ html {
|
|||
border-bottom-width: 2px;
|
||||
}
|
||||
|
||||
.border-r-0 {
|
||||
border-right-width: 0px;
|
||||
}
|
||||
|
||||
.border-l-0 {
|
||||
border-left-width: 0px;
|
||||
}
|
||||
|
||||
.border-dashed {
|
||||
border-style: dashed;
|
||||
}
|
||||
|
@ -1570,6 +1647,11 @@ html {
|
|||
background-color: rgb(79 70 229 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-gray-900 {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(17 24 39 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.bg-opacity-75 {
|
||||
--tw-bg-opacity: 0.75;
|
||||
}
|
||||
|
@ -1586,6 +1668,22 @@ html {
|
|||
padding: 0.5rem;
|
||||
}
|
||||
|
||||
.p-1\.5 {
|
||||
padding: 0.375rem;
|
||||
}
|
||||
|
||||
.p-1 {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
|
||||
.p-8 {
|
||||
padding: 2rem;
|
||||
}
|
||||
|
||||
.p-12 {
|
||||
padding: 3rem;
|
||||
}
|
||||
|
||||
.px-4 {
|
||||
padding-left: 1rem;
|
||||
padding-right: 1rem;
|
||||
|
@ -1739,6 +1837,14 @@ html {
|
|||
padding-left: 0.375rem;
|
||||
}
|
||||
|
||||
.pl-3\.5 {
|
||||
padding-left: 0.875rem;
|
||||
}
|
||||
|
||||
.pr-12 {
|
||||
padding-right: 3rem;
|
||||
}
|
||||
|
||||
.text-left {
|
||||
text-align: left;
|
||||
}
|
||||
|
@ -1810,6 +1916,10 @@ html {
|
|||
font-weight: 800;
|
||||
}
|
||||
|
||||
.font-black {
|
||||
font-weight: 900;
|
||||
}
|
||||
|
||||
.uppercase {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
@ -1884,6 +1994,11 @@ html {
|
|||
color: rgb(75 85 99 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.text-co-green {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(108 193 31 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.placeholder-gray-500::-moz-placeholder {
|
||||
--tw-placeholder-opacity: 1;
|
||||
color: rgb(107 114 128 / var(--tw-placeholder-opacity));
|
||||
|
@ -2083,6 +2198,11 @@ html {
|
|||
background-color: rgb(67 56 202 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.hover\:bg-gray-100:hover {
|
||||
--tw-bg-opacity: 1;
|
||||
background-color: rgb(243 244 246 / var(--tw-bg-opacity));
|
||||
}
|
||||
|
||||
.hover\:bg-opacity-5:hover {
|
||||
--tw-bg-opacity: 0.05;
|
||||
}
|
||||
|
@ -2121,6 +2241,16 @@ html {
|
|||
color: inherit;
|
||||
}
|
||||
|
||||
.hover\:text-gray-500:hover {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(107 114 128 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.hover\:text-indigo-500:hover {
|
||||
--tw-text-opacity: 1;
|
||||
color: rgb(99 102 241 / var(--tw-text-opacity));
|
||||
}
|
||||
|
||||
.focus\:border-transparent:focus {
|
||||
border-color: transparent;
|
||||
}
|
||||
|
@ -2202,6 +2332,11 @@ html {
|
|||
--tw-ring-color: rgb(59 130 246 / var(--tw-ring-opacity));
|
||||
}
|
||||
|
||||
.focus\:ring-co-red:focus {
|
||||
--tw-ring-opacity: 1;
|
||||
--tw-ring-color: rgb(255 19 0 / var(--tw-ring-opacity));
|
||||
}
|
||||
|
||||
.focus\:ring-offset-2:focus {
|
||||
--tw-ring-offset-width: 2px;
|
||||
}
|
||||
|
@ -2262,6 +2397,10 @@ html {
|
|||
display: flex;
|
||||
}
|
||||
|
||||
.sm\:grid {
|
||||
display: grid;
|
||||
}
|
||||
|
||||
.sm\:hidden {
|
||||
display: none;
|
||||
}
|
||||
|
@ -2302,6 +2441,10 @@ html {
|
|||
grid-template-columns: repeat(6, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.sm\:grid-cols-3 {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
}
|
||||
|
||||
.sm\:flex-row-reverse {
|
||||
flex-direction: row-reverse;
|
||||
}
|
||||
|
@ -2326,6 +2469,10 @@ html {
|
|||
gap: 1.5rem;
|
||||
}
|
||||
|
||||
.sm\:gap-4 {
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.sm\:space-y-0 > :not([hidden]) ~ :not([hidden]) {
|
||||
--tw-space-y-reverse: 0;
|
||||
margin-top: calc(0px * calc(1 - var(--tw-space-y-reverse)));
|
||||
|
@ -2342,6 +2489,17 @@ html {
|
|||
--tw-space-x-reverse: 1;
|
||||
}
|
||||
|
||||
.sm\:divide-y > :not([hidden]) ~ :not([hidden]) {
|
||||
--tw-divide-y-reverse: 0;
|
||||
border-top-width: calc(1px * calc(1 - var(--tw-divide-y-reverse)));
|
||||
border-bottom-width: calc(1px * var(--tw-divide-y-reverse));
|
||||
}
|
||||
|
||||
.sm\:divide-gray-200 > :not([hidden]) ~ :not([hidden]) {
|
||||
--tw-divide-opacity: 1;
|
||||
border-color: rgb(229 231 235 / var(--tw-divide-opacity));
|
||||
}
|
||||
|
||||
.sm\:overflow-hidden {
|
||||
overflow: hidden;
|
||||
}
|
||||
|
@ -2354,6 +2512,10 @@ html {
|
|||
border-radius: 1.5rem;
|
||||
}
|
||||
|
||||
.sm\:rounded-2xl {
|
||||
border-radius: 1rem;
|
||||
}
|
||||
|
||||
.sm\:p-6 {
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
@ -2363,6 +2525,11 @@ html {
|
|||
padding-right: 1.5rem;
|
||||
}
|
||||
|
||||
.sm\:py-5 {
|
||||
padding-top: 1.25rem;
|
||||
padding-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.sm\:pl-6 {
|
||||
padding-left: 1.5rem;
|
||||
}
|
||||
|
@ -2371,6 +2538,10 @@ html {
|
|||
padding-right: 1.5rem;
|
||||
}
|
||||
|
||||
.sm\:pb-5 {
|
||||
padding-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.sm\:text-sm {
|
||||
font-size: 0.875rem;
|
||||
line-height: 1.25rem;
|
||||
|
@ -2493,6 +2664,10 @@ html {
|
|||
padding-left: 0px;
|
||||
}
|
||||
|
||||
.md\:pr-0 {
|
||||
padding-right: 0px;
|
||||
}
|
||||
|
||||
.md\:text-right {
|
||||
text-align: right;
|
||||
}
|
||||
|
@ -2515,6 +2690,10 @@ html {
|
|||
grid-column-start: 3;
|
||||
}
|
||||
|
||||
.lg\:col-start-2 {
|
||||
grid-column-start: 2;
|
||||
}
|
||||
|
||||
.lg\:-mx-8 {
|
||||
margin-left: -2rem;
|
||||
margin-right: -2rem;
|
||||
|
|
Loading…
Reference in New Issue