diff --git a/.gitignore b/.gitignore
index f702e7b..3346355 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,3 +1,3 @@
-config.yaml
+/config.yaml
.vscode
__debug_bin
\ No newline at end of file
diff --git a/README.md b/README.md
index 7383122..8819f67 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,12 @@
# PARCOURSMOB
-The PARCOURSMOB inclusive mobility platform.
\ No newline at end of file
+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
\ No newline at end of file
diff --git a/go.mod b/go.mod
index a5e9b03..7335778 100644
--- a/go.mod
+++ b/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
diff --git a/handlers/application/beneficiaries.go b/handlers/application/beneficiaries.go
index 025ad37..422a619 100644
--- a/handlers/application/beneficiaries.go
+++ b/handlers/application/beneficiaries.go
@@ -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
+}
diff --git a/handlers/application/vehicles-management.go b/handlers/application/vehicles-management.go
index d85b121..f5e9e5d 100644
--- a/handlers/application/vehicles-management.go
+++ b/handlers/application/vehicles-management.go
@@ -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())
+}
diff --git a/handlers/application/vehicles.go b/handlers/application/vehicles.go
new file mode 100644
index 0000000..5d26ddc
--- /dev/null
+++ b/handlers/application/vehicles.go
@@ -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(), "")
+}
diff --git a/main.go b/main.go
index e6f27d3..859959e 100644
--- a/main.go
+++ b/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)
diff --git a/renderer/func-maps.go b/renderer/func-maps.go
index 1b062c3..561fee2 100644
--- a/renderer/func-maps.go
+++ b/renderer/func-maps.go
@@ -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)
diff --git a/renderer/renderer.go b/renderer/renderer.go
index 7673bbc..e4f9f66 100644
--- a/renderer/renderer.go
+++ b/renderer/renderer.go
@@ -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",
})
}
diff --git a/renderer/vehicle-management.go b/renderer/vehicle-management.go
index 36c4ffd..dbb9217 100644
--- a/renderer/vehicle-management.go
+++ b/renderer/vehicle-management.go
@@ -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)
}
diff --git a/renderer/vehicles.go b/renderer/vehicles.go
new file mode 100644
index 0000000..50982df
--- /dev/null
+++ b/renderer/vehicles.go
@@ -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)
+}
diff --git a/services/fleets.go b/services/fleets.go
new file mode 100644
index 0000000..a47a7b2
--- /dev/null
+++ b/services/fleets.go
@@ -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
+}
diff --git a/services/services.go b/services/services.go
index ac6be54..bc17da5 100644
--- a/services/services.go
+++ b/services/services.go
@@ -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
}
diff --git a/themes/default/config.yaml b/themes/default/config.yaml
new file mode 100644
index 0000000..13f42f5
--- /dev/null
+++ b/themes/default/config.yaml
@@ -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:
+ hero:outline/briefcase:
+ hero:outline/calendar:
+ hero:outline/cog:
+ hero:outline/home:
+ hero:outline/map:
+ hero:outline/office-building:
+ hero:outline/plus-circle:
+ hero:outline/shield-check:
+ hero:outline/user-group:
+ hero:outline/x:
+ hero:solid/chevron-right:
+ hero:solid/question-mark-icon:
+ hero:solid/search:
+ hero:solid/selector:
+ img:profile-picture-placeholder:
+
diff --git a/themes/default/layouts/administration/_partials/groups_admins.html b/themes/default/layouts/administration/_partials/groups_admins.html
index 64292ef..34040cc 100644
--- a/themes/default/layouts/administration/_partials/groups_admins.html
+++ b/themes/default/layouts/administration/_partials/groups_admins.html
@@ -7,13 +7,13 @@
-
+
diff --git a/themes/default/layouts/administration/display_group.html b/themes/default/layouts/administration/display_group.html
index fce538f..c669351 100644
--- a/themes/default/layouts/administration/display_group.html
+++ b/themes/default/layouts/administration/display_group.html
@@ -14,10 +14,10 @@
-
Supprimer
Modifier
+ 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 -->
diff --git a/themes/default/layouts/administration/home.html b/themes/default/layouts/administration/home.html
index 7f7dea8..3a561c6 100644
--- a/themes/default/layouts/administration/home.html
+++ b/themes/default/layouts/administration/home.html
@@ -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">
Bénéficiaires
-
160 bénéficiaires
+
{{len (index .ViewState.groups 0).Members}} bénéficiaires
@@ -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">
Organisations
-
12 organisations
+
{{len .ViewState.groups}} organisations
@@ -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">
Référents
-
53 membres
+
1 membres
@@ -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">
Accompagnement
-
363 actions réalisées
+
0 actions réalisées
@@ -106,10 +106,10 @@
-
@@ -119,7 +119,7 @@
+ alt="Tom Cook"> -->
diff --git a/themes/default/layouts/beneficiaries/_partials/beneficiary-events.html b/themes/default/layouts/beneficiaries/_partials/beneficiary-events.html
index 1256a08..684622f 100644
--- a/themes/default/layouts/beneficiaries/_partials/beneficiary-events.html
+++ b/themes/default/layouts/beneficiaries/_partials/beneficiary-events.html
@@ -1,5 +1,4 @@
{{define "beneficiary_events"}}
- TODO Dispositifs
{{end}}
\ No newline at end of file
diff --git a/themes/default/layouts/beneficiaries/_partials/beneficiary-journeys.html b/themes/default/layouts/beneficiaries/_partials/beneficiary-journeys.html
index 1e3f850..7d31762 100644
--- a/themes/default/layouts/beneficiaries/_partials/beneficiary-journeys.html
+++ b/themes/default/layouts/beneficiaries/_partials/beneficiary-journeys.html
@@ -1,5 +1,4 @@
{{define "beneficiary_journeys"}}
- TODO Déplacements
{{end}}
\ No newline at end of file
diff --git a/themes/default/layouts/beneficiaries/_partials/beneficiary-notes.html b/themes/default/layouts/beneficiaries/_partials/beneficiary-notes.html
index 34c64c4..a793a17 100644
--- a/themes/default/layouts/beneficiaries/_partials/beneficiary-notes.html
+++ b/themes/default/layouts/beneficiaries/_partials/beneficiary-notes.html
@@ -1,7 +1,7 @@
{{define "beneficiary_notes"}}
diff --git a/themes/default/layouts/beneficiaries/_partials/beneficiary-vehicles.html b/themes/default/layouts/beneficiaries/_partials/beneficiary-vehicles.html
new file mode 100644
index 0000000..b5d4a77
--- /dev/null
+++ b/themes/default/layouts/beneficiaries/_partials/beneficiary-vehicles.html
@@ -0,0 +1,31 @@
+{{define "beneficiary_vehicles"}}
+
+
Réserver un véhicule
+
+
+{{end}}
\ No newline at end of file
diff --git a/themes/default/layouts/beneficiaries/display.html b/themes/default/layouts/beneficiaries/display.html
index c14b847..2f42ebc 100644
--- a/themes/default/layouts/beneficiaries/display.html
+++ b/themes/default/layouts/beneficiaries/display.html
@@ -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
-
- Documents
+ Documents -->
@@ -131,6 +131,7 @@
{{template "beneficiary_notes" .}}
{{template "beneficiary_journeys" .}}
+ {{template "beneficiary_vehicles" .}}
{{template "beneficiary_events" .}}
{{template "beneficiary_files" .}}
@@ -141,162 +142,7 @@
Actions réalisées
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Advance
- to offer
-
+
Aucune action réalisée pour le moment
diff --git a/themes/default/layouts/dashboard/dashboard.html b/themes/default/layouts/dashboard/dashboard.html
index a6bf543..331c9df 100644
--- a/themes/default/layouts/dashboard/dashboard.html
+++ b/themes/default/layouts/dashboard/dashboard.html
@@ -3,6 +3,67 @@
Tableau de bord
+
+
Statistiques de votre organisation
+
+
+
+ {{.IconSet.Icon "hero:outline/user-group" "h-6 w-6"}}
+
+
+
+
Bénéficiaires
+
{{.ViewState.beneficiaries.count}} bénéficiaires
+
+
+
+
+
+
+ {{.IconSet.Icon "hero:outline/shield-check" "h-6 w-6"}}
+
+
+
+
+
+
+ {{.IconSet.Icon "hero:outline/office-building" "h-6 w-6"}}
+
+
+
+
+
+
+ {{.IconSet.Icon "hero:outline/briefcase" "h-6 w-6"}}
+
+
+
+
+
+
diff --git a/themes/default/layouts/layout.html b/themes/default/layouts/layout.html
index ee3448a..f2d3425 100644
--- a/themes/default/layouts/layout.html
+++ b/themes/default/layouts/layout.html
@@ -118,8 +118,8 @@
x-transition:leave-start="transform opacity-100 scale-100"
x-transition:leave-end="transform opacity-0 scale-95">
-
+
@@ -135,7 +135,7 @@
id="user-menu-button" aria-expanded="false" aria-haspopup="true">
Open user menu
diff --git a/themes/default/layouts/vehicles/booking-display.html b/themes/default/layouts/vehicles/booking-display.html
new file mode 100644
index 0000000..afc7eb4
--- /dev/null
+++ b/themes/default/layouts/vehicles/booking-display.html
@@ -0,0 +1,137 @@
+{{define "content"}}
+
+
Réservation de véhicule
+
+
+
+
+
+
Bénéficiaire
+
+
+
+
+
+
Nom
+
+ {{.ViewState.beneficiary.Data.first_name}}
+ {{.ViewState.beneficiary.Data.last_name}}
+
+
+
Email
+
+ {{.ViewState.beneficiary.Data.email}}
+
+
+
Téléphone
+
+ {{.ViewState.beneficiary.Data.phone_number}}
+
+ {{if .ViewState.Data.birthdate}}
+
+
Date de naissance
+ {{(timeFrom
+ .ViewState.Data.birthdate).Format
+ "02/01/2006"}}
+
+ {{end}}
+ {{if and .ViewState.Data.gender (ne .ViewState.Data.gender "0")}}
+
+
Date de naissance
+ {{genderISO5218
+ .ViewState.Data.gender}}
+
+ {{end}}
+ {{if .ViewState.Data.address}}
+
+
Adresse
+
+ {{.ViewState.Data.address.properties.label}}
+
+ {{end}}
+
+
+
+
+
+
+
+
+
+
+
+
Réservation
+
Informations utiles sur la réservation.
+
+
+ SMS
+ Email
+ Imprimer
+
+
+
+
+
+
+
+
+
Gestionnaire
+
+ COOPGO
+
+
+
+
Véhicule
+
+ {{.ViewState.vehicle.Data.name}}
+
+
+
Immatriculation
+
+ {{.ViewState.vehicle.Data.licence_plate}}
+
+
+
Type
+
+ Voiture
+
+ {{if .ViewState.vehicle.Data.address}}
+
+
Lieu de récupération
+ {{.ViewState.vehicle.Data.address.properties.label}}
+
+ {{end}}
+
+
Date de récupération
+ {{(timeFrom .ViewState.booking.Startdate).Format
+ "02/01/2006"}}
+
+
+
Date de fin
+ {{(timeFrom .ViewState.booking.Enddate).Format
+ "02/01/2006"}}
+
+
+
+
+
+
+
+
+
+{{end}}
\ No newline at end of file
diff --git a/themes/default/layouts/vehicles/search.html b/themes/default/layouts/vehicles/search.html
new file mode 100644
index 0000000..518aefb
--- /dev/null
+++ b/themes/default/layouts/vehicles/search.html
@@ -0,0 +1,158 @@
+{{define "content"}}
+
+
Véhicules partagés
+
+
+
+
+
+
+
Chercher un véhicule
+
+
+
+
+ {{if .ViewState.searched}}
+
+
Véhicules disponibles
+
+
+ {{end}}
+
+
+
+{{end}}
\ No newline at end of file
diff --git a/themes/default/layouts/vehicles_management/_partials/bookings-list.html b/themes/default/layouts/vehicles_management/_partials/bookings-list.html
index 3b803d3..a646f4a 100644
--- a/themes/default/layouts/vehicles_management/_partials/bookings-list.html
+++ b/themes/default/layouts/vehicles_management/_partials/bookings-list.html
@@ -7,26 +7,23 @@
-
Statut
-
-
+ -->
+
Type
-
+
Immatriculation
-
+
Beneficiaire
-
- Prescripteur
-
-
+
Gestionnaire
-
+
Dates
@@ -35,33 +32,38 @@
+ {{range .ViewState.vehicles}}
+ {{$vehicle := .}}
+ {{range .Bookings}}
-
+
+
+ Voiture
- aa
+ {{$vehicle.Data.licence_plate}}
+
+
+
+
+ COOPGO
- aa
+ Du {{(timeFrom .Startdate).Format "02/01/2006"}} au {{(timeFrom .Enddate).Format "02/01/2006"}}
- aa
-
-
- aa
-
-
- aa
-
-
- Voir
+ {{end}}
+ {{end}}
diff --git a/themes/default/layouts/vehicles_management/_partials/calendar.html b/themes/default/layouts/vehicles_management/_partials/calendar.html
new file mode 100644
index 0000000..5a6dbb5
--- /dev/null
+++ b/themes/default/layouts/vehicles_management/_partials/calendar.html
@@ -0,0 +1,259 @@
+{{define "calendar"}}
+
+
Août 2022
+
+ Mois précédent
+
+
+
+
+
+
+ Mois suivant
+
+
+
+
+
+
+
+
L
+
M
+
M
+
J
+
V
+
S
+
D
+
+
+
+
+
+ 1
+
+
+
+
+ 2
+
+
+
+
+ 3
+
+
+
+
+ 4
+
+
+
+
+ 5
+
+
+
+
+ 6
+
+
+
+
+ 7
+
+
+
+
+ 8
+
+
+
+
+ 9
+
+
+
+
+ 10
+
+
+
+
+ 11
+
+
+
+
+ 12
+
+
+
+
+ 13
+
+
+
+
+ 14
+
+
+
+
+ 15
+
+
+
+
+ 16
+
+
+
+
+ 17
+
+
+
+
+ 18
+
+
+
+
+ 19
+
+
+
+
+ 20
+
+
+
+
+ 21
+
+
+
+
+ 22
+
+
+
+
+ 23
+
+
+
+
+ 24
+
+
+
+
+ 25
+
+
+
+
+ 26
+
+
+
+
+ 27
+
+
+
+
+ 28
+
+
+
+
+ 29
+
+
+
+
+ 30
+
+
+
+
+ 31
+
+
+
+
+ 1
+
+
+
+
+ 2
+
+
+
+
+ 3
+
+
+
+
+ 4
+
+
+
+{{end}}
\ No newline at end of file
diff --git a/themes/default/layouts/vehicles_management/_partials/vehicles-list.html b/themes/default/layouts/vehicles_management/_partials/vehicles-list.html
index 36fff55..c8840ae 100644
--- a/themes/default/layouts/vehicles_management/_partials/vehicles-list.html
+++ b/themes/default/layouts/vehicles_management/_partials/vehicles-list.html
@@ -9,16 +9,16 @@
- Immatriculation
+ Numéro (Immat / Bicycode)
-
- Gestionnaire
+
+ Type
-
+
Modèle
-
- Gestionnaire
+
+ Lieu
Actions
@@ -26,24 +26,26 @@
+ {{range .ViewState.vehicles}}
- aa
+ {{.Data.licence_plate}}
- aa
+ {{if eq .Type "electric_bike"}}Vélo électrique{{else}}Voiture{{end}}
- aa
+ {{.Data.name}}
- aa
+ {{if .Data.address}}{{.Data.address.properties.label}}{{end}}
- Voir
+ {{end}}
diff --git a/themes/default/layouts/vehicles_management/booking-display.html b/themes/default/layouts/vehicles_management/booking-display.html
new file mode 100644
index 0000000..2dbeaeb
--- /dev/null
+++ b/themes/default/layouts/vehicles_management/booking-display.html
@@ -0,0 +1,147 @@
+{{define "content"}}
+
+
Réservation de véhicule
+
+
+
+
+
+
Bénéficiaire
+
+
+
+
+
+
Nom
+
+ {{.ViewState.beneficiary.Data.first_name}}
+ {{.ViewState.beneficiary.Data.last_name}}
+
+
+
Email
+
+ {{.ViewState.beneficiary.Data.email}}
+
+
+
Téléphone
+
+ {{.ViewState.beneficiary.Data.phone_number}}
+
+ {{if .ViewState.Data.birthdate}}
+
+
Date de naissance
+ {{(timeFrom
+ .ViewState.Data.birthdate).Format
+ "02/01/2006"}}
+
+ {{end}}
+ {{if and .ViewState.Data.gender (ne .ViewState.Data.gender "0")}}
+
+
Date de naissance
+ {{genderISO5218
+ .ViewState.Data.gender}}
+
+ {{end}}
+ {{if .ViewState.Data.address}}
+
+
Adresse
+
+ {{.ViewState.Data.address.properties.label}}
+
+ {{end}}
+
+
+
+
+
+
+
+
+
+
+
+
Réservation
+
Informations utiles sur la réservation.
+
+
+ SMS
+ Email
+ Imprimer
+
+
+
+
+
+
+
+
+
Gestionnaire
+
+ COOPGO
+
+
+
+
Véhicule
+
+ {{.ViewState.vehicle.Data.name}}
+
+
+
Immatriculation
+
+ {{.ViewState.vehicle.Data.licence_plate}}
+
+
+
Type
+
+ Voiture
+
+ {{if .ViewState.vehicle.Data.address}}
+
+
Lieu de récupération
+ {{.ViewState.vehicle.Data.address.properties.label}}
+
+ {{end}}
+
+
Date de récupération
+ {{(timeFrom .ViewState.booking.Startdate).Format
+ "02/01/2006"}}
+
+
+
Date de fin
+ {{(timeFrom .ViewState.booking.Enddate).Format
+ "02/01/2006"}}
+
+
+
Indisponible à partir du
+ {{(timeFrom .ViewState.booking.Unavailablefrom).Format
+ "02/01/2006"}}
+
+
+
Sera à nouveau disponible le
+ {{(timeFrom .ViewState.booking.Unavailableto).Format
+ "02/01/2006"}}
+
+
+
+
+
+
+
+
+
+{{end}}
\ No newline at end of file
diff --git a/themes/default/layouts/vehicles_management/fleet-display.html b/themes/default/layouts/vehicles_management/fleet-display.html
new file mode 100644
index 0000000..387f392
--- /dev/null
+++ b/themes/default/layouts/vehicles_management/fleet-display.html
@@ -0,0 +1,90 @@
+{{define "content"}}
+
+
+
+
+
+
{{.ViewState.vehicle.Data.name}}
+
+
+
+
+
+
+
+
+
+
Informations
+
Informations sur le véhicule
+
+
+
+ {{if .ViewState.vehicle.Data.type}}
+
+
Type
+ {{if eq .ViewState.vehicle.Data.type "electric_bike"}}Vélo électrique{{else}}Voiture{{end}}
+
+ {{else}}
+
+
Type
+ Voiture
+
+ {{end}}
+ {{if .ViewState.vehicle.Data.licence_plate}}
+
+
Numéro (Immatriculation, bicycode, ...)
+ {{.ViewState.vehicle.Data.licence_plate}}
+
+ {{end}}
+ {{if .ViewState.vehicle.Data.address}}
+
+
Lieu
+ {{.ViewState.vehicle.Data.address.properties.label}}
+
+ {{end}}
+ {{if .ViewState.vehicle.Data.informations}}
+
+
Informations pratiques pour le bénéficiaire
+ {{.ViewState.vehicle.Data.informations}}
+
+ {{end}}
+
+
+
+
+
+
+
+
Réservations à venir
+ {{if eq (len .ViewState.vehicle.Bookings) 0}}
+
Aucune réservation à venir
+ {{end}}
+
+ {{range .ViewState.vehicle.Bookings}}
+
+
+
+ {{end}}
+
+ {{template "calendar" .}}
+
+
+
+
+{{end}}
\ No newline at end of file
diff --git a/themes/default/layouts/vehicles_management/fleet-update.html b/themes/default/layouts/vehicles_management/fleet-update.html
new file mode 100644
index 0000000..88b6770
--- /dev/null
+++ b/themes/default/layouts/vehicles_management/fleet-update.html
@@ -0,0 +1,106 @@
+{{define "content"}}
+
+
+
+
Modifier un véhicule
+
+
+
+{{end}}
\ No newline at end of file
diff --git a/themes/default/layouts/vehicles_management/overview.html b/themes/default/layouts/vehicles_management/overview.html
index 39886ea..9ab5eda 100644
--- a/themes/default/layouts/vehicles_management/overview.html
+++ b/themes/default/layouts/vehicles_management/overview.html
@@ -17,7 +17,7 @@
+ 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
diff --git a/themes/default/public/css/main.css b/themes/default/public/css/main.css
index 4f7da2c..5d43147 100644
--- a/themes/default/public/css/main.css
+++ b/themes/default/public/css/main.css
@@ -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;