Agenda improvements

This commit is contained in:
Arnaud Delcasse 2022-09-06 15:02:59 +02:00
parent 8aa8fc927b
commit 23f4603dec
14 changed files with 285 additions and 137 deletions

View File

@ -6,6 +6,7 @@ import (
"net/http"
groupsmanagement "git.coopgo.io/coopgo-platform/groups-management/grpcapi"
accounts "git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi"
"github.com/google/uuid"
"github.com/gorilla/mux"
"google.golang.org/protobuf/types/known/structpb"
@ -119,5 +120,88 @@ func (h *ApplicationHandler) AdministrationGroupDisplay(w http.ResponseWriter, r
return
}
h.Renderer.AdministrationGroupDisplay(w, r, resp.Group.ToStorageType())
members, err := h.members()
if err != nil {
if err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
}
groupmembers := []any{}
admins := []any{}
for _, m := range members {
mm := m.ToStorageType()
for _, g := range mm.Data["groups"].([]any) {
if g.(string) == groupid {
groupmembers = append(groupmembers, mm)
}
if g.(string) == groupid+":admin" {
admins = append(admins, mm)
}
}
}
h.Renderer.AdministrationGroupDisplay(w, r, resp.Group.ToStorageType(), groupmembers, admins)
}
func (h *ApplicationHandler) AdministrationGroupInviteAdmin(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
groupid := vars["groupid"]
// groupresp, err := h.services.GRPC.GroupsManagement.GetGroup(&groupsmanagement.GetGroupRequest{
// Id: groupid,
// Namespace: "parcoursmob_organizations",
// })
// if err != nil {
// fmt.Println(err)
// w.WriteHeader(http.StatusInternalServerError)
// return
// }
r.ParseForm()
accountresp, err := h.services.GRPC.MobilityAccounts.GetAccountUsername(context.TODO(), &accounts.GetAccountUsernameRequest{
Username: r.FormValue("username"),
Namespace: "parcoursmob",
})
fmt.Println(err)
if err == nil {
account := accountresp.Account.ToStorageType()
account.Data["groups"] = append(account.Data["groups"].([]any), groupid, groupid)
account.Data["groups"] = append(account.Data["groups"].([]any), groupid, groupid+":admin")
as, _ := accounts.AccountFromStorageType(&account)
_, err = h.services.GRPC.MobilityAccounts.UpdateData(
context.TODO(),
&accounts.UpdateDataRequest{
Account: as,
},
)
fmt.Println(err)
http.Redirect(w, r, fmt.Sprintf("/app/administration/groups/%s", groupid), http.StatusFound)
return
}
http.Redirect(w, r, fmt.Sprintf("/app/administration/groups/%s", groupid), http.StatusFound)
return
}
func (h *ApplicationHandler) members() ([]*accounts.Account, error) {
resp, err := h.services.GRPC.MobilityAccounts.GetAccounts(context.TODO(), &accounts.GetAccountsRequest{
Namespaces: []string{"parcoursmob"},
})
if err != nil {
return nil, err
}
return resp.Accounts, nil
}

View File

@ -58,8 +58,6 @@ func (h *ApplicationHandler) AgendaHome(w http.ResponseWriter, r *http.Request)
for _, e := range resp.Events {
groupids = append(groupids, e.Owners...)
responses = append(responses, e.ToStorageType())
// fmt.Println(e)
// fmt.Println(e.ToStorageType())
}
sort.Sort(EventsByStartdate(responses))
@ -294,7 +292,7 @@ func parseEventsForm(r *http.Request) (*EventsForm, error) {
return formData, nil
}
func contains(s []string, e string) bool {
func contains[V string](s []V, e V) bool {
for _, a := range s {
if a == e {
return true

View File

@ -4,8 +4,11 @@ import (
"context"
"fmt"
"net/http"
"sort"
"git.coopgo.io/coopgo-apps/parcoursmob/utils/identification"
agenda "git.coopgo.io/coopgo-platform/agenda/grpcapi"
agendastorage "git.coopgo.io/coopgo-platform/agenda/storage"
"git.coopgo.io/coopgo-platform/groups-management/storage"
mobilityaccounts "git.coopgo.io/coopgo-platform/mobility-accounts/grpcapi"
)
@ -47,6 +50,27 @@ func (h *ApplicationHandler) Dashboard(w http.ResponseWriter, r *http.Request) {
}
}
h.Renderer.Dashboard(w, r, accounts, count)
members, err := h.members()
if err != nil {
fmt.Println(err)
w.WriteHeader(http.StatusInternalServerError)
return
}
count_members := len(members)
events := []agendastorage.Event{}
eventsresp, err := h.services.GRPC.Agenda.GetEvents(context.TODO(), &agenda.GetEventsRequest{
Namespaces: []string{"parcoursmob_dispositifs"},
})
for _, e := range eventsresp.Events {
events = append(events, e.ToStorageType())
}
sort.Sort(EventsByStartdate(events))
h.Renderer.Dashboard(w, r, accounts, count, count_members, events)
}

View File

@ -91,6 +91,7 @@ func main() {
appAdmin.HandleFunc("/", applicationHandler.Administration)
appAdmin.HandleFunc("/groups/", applicationHandler.AdministrationCreateGroup)
appAdmin.HandleFunc("/groups/{groupid}", applicationHandler.AdministrationGroupDisplay)
appAdmin.HandleFunc("/groups/{groupid}/invite-admin", applicationHandler.AdministrationGroupInviteAdmin)
//TODO Secure with Middleware checking for modules
fmt.Println("-> HTTP server listening on", address)

View File

@ -21,11 +21,13 @@ func (renderer *Renderer) AdministrationCreateGroup(w http.ResponseWriter, r *ht
renderer.Render("administration", w, r, files, state)
}
func (renderer *Renderer) AdministrationGroupDisplay(w http.ResponseWriter, r *http.Request, group any) {
func (renderer *Renderer) AdministrationGroupDisplay(w http.ResponseWriter, r *http.Request, group any, groupmembers []any, admins []any) {
files := renderer.ThemeConfig.GetStringSlice("views.administration.display_group.files")
state := NewState(r, renderer.ThemeConfig, administrationMenu)
state.ViewState = map[string]any{
"group": group,
"members": groupmembers,
"admins": admins,
}
renderer.Render("administration", w, r, files, state)

View File

@ -2,11 +2,13 @@ package renderer
import (
"net/http"
agendastorage "git.coopgo.io/coopgo-platform/agenda/storage"
)
const dashboardMenu = "dashboard"
func (renderer *Renderer) Dashboard(w http.ResponseWriter, r *http.Request, accounts []any, nbaccounts int) {
func (renderer *Renderer) Dashboard(w http.ResponseWriter, r *http.Request, accounts []any, nbaccounts int, count_members int, events []agendastorage.Event) {
files := renderer.ThemeConfig.GetStringSlice("views.dashboard.files")
state := NewState(r, renderer.ThemeConfig, dashboardMenu)
state.ViewState = map[string]any{
@ -14,6 +16,8 @@ func (renderer *Renderer) Dashboard(w http.ResponseWriter, r *http.Request, acco
"count": nbaccounts,
"latest": accounts,
},
"count_members": count_members,
"events": events,
}
renderer.Render("dashboard", w, r, files, state)

View File

@ -7,6 +7,7 @@ views:
- layouts/_partials/mainmenu.html
dashboard:
files:
- layouts/dashboard/_partials/agenda-widget.html
- layouts/dashboard/_partials/beneficiaries-widget.html
- layouts/dashboard/dashboard.html
beneficiaries:

View File

@ -5,33 +5,56 @@
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
{{range .ViewState.admins}}
<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="http://localhost:9000/app/beneficiaries/e7616eac-4a87-4396-a505-23e0421b9c4c/picture" alt="">
<img class="h-10 w-10 rounded-co" src="/app/beneficiaries/{{.ID}}/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">Arnaud Delcasse</p>
<p class="text-sm text-gray-500 truncate">arnaud.delcasse@coopgo.fr</p>
<p class="text-sm font-medium text-gray-900">{{.Data.first_name}} {{.Data.last_name}}</p>
<p class="text-sm text-gray-500 truncate">{{.Data.email}}</p>
</a>
</div>
</div>
<!-- More people... -->
{{end}}
</div>
</div>
<div class="px-6 py-4">
<h2 class="text-md font-medium text-gray-900">Ajouter</h2>
<div class="flex">
<div class="px-2 py-4">
<form class="flex" method="POST" action="/app/administration/groups/{{.ViewState.group.ID}}/invite-admin">
<div class="pr-2 flex-1">
<input type="text" name="name" id="name"
<input type="text" name="username" id="username"
class="mt-1 border-gray-300 focus:ring-co-blue focus:border-co-blue block w-full shadow-sm sm:text-sm rounded-2xl"
placeholder="Email">
</div>
<button class="px-1 py-1 border border-transparent text-sm font-medium rounded-2xl shadow-sm text-white bg-co-blue hover:bg-co-blue focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-co-blue">Ajouter</button>
<button class="px-1 py-1 border border-transparent text-sm font-medium rounded-2xl shadow-sm text-white bg-co-blue hover:bg-co-blue focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-co-blue">Ajouter administrateur</button>
</div>
</form>
</div>
<!-- <div class="border-t border-gray-200 px-4 py-5 sm:px-6">
<h2 class="text-md font-medium text-gray-900">Membres de l'organisation</h2>
<div class="grid grid-cols-1 gap-4 sm:grid-cols-2">
{{range .ViewState.members}}
<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="/app/beneficiaries/{{.ID}}/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">{{.Data.first_name}} {{.Data.last_name}}</p>
<p class="text-sm text-gray-500 truncate">{{.Data.email}}</p>
</a>
</div>
</div>
{{end}}
</div>
</div> -->
{{end}}

View File

@ -0,0 +1,29 @@
{{define "agenda_widget"}}
<div class="col-span-1 bg-white rounded-2xl shadow divide-y divide-gray-200 flex flex-col">
<div class="-ml-4 -mt-2 px-4 py-2 flex items-center justify-between flex-wrap sm:flex-nowrap">
<div class="ml-4 mt-2">
<h3 class="text-lg leading-6 font-medium text-gray-900">Prochains dispositifs</h3>
</div>
<!-- <div class="ml-4 mt-2 flex-shrink-0">
<button type="button" class="relative inline-flex items-center px-4 py-2 border border-transparent shadow-sm text-sm font-medium rounded-md text-white bg-co-blue hover:bg-co-blue focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue">Voir</button>
</div> -->
</div>
<ul role="list" class="divide-y divide-gray-200 flex-1">
{{range .}}
<li class="py-2 px-4 flex">
<a href="/app/agenda/{{.ID}}" class="flex w-full">
<div class="ml-3">
<p class="text-sm font-medium text-gray-900">{{(timeFrom .Startdate).Format "02/01"}} - {{.Type}} - {{.Name}}</p>
</div>
</a>
</li>
{{end}}
</ul>
<a href="/app/agenda/">
<button class="w-full p-2 text-center bg-co-blue text-white rounded-b-2xl text-sm">
Agenda des dispositifs
</button>
</a>
</div>
{{end}}

View File

@ -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">Référents</a>
<p class="text-gray-500">53 membres</p>
<p class="text-gray-500">{{.ViewState.count_members}} membres</p>
</div>
</div>
</li>
@ -69,6 +69,7 @@
{{template "beneficiaries_widget" .ViewState.beneficiaries}}
{{template "agenda_widget" .ViewState.events}}
</div>

View File

@ -130,7 +130,8 @@
<!-- Profile dropdown -->
<div class="ml-3 relative" x-data="{ profileMenuOpen: false }">
<div>
<button @click="profileMenuOpen = ! profileMenuOpen" type="button"
<!-- <button @click="profileMenuOpen = ! profileMenuOpen" type="button" -->
<button type="button"
class="max-w-xs bg-white flex items-center text-sm rounded-co focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-co-blue"
id="user-menu-button" aria-expanded="false" aria-haspopup="true">
<span class="sr-only">Open user menu</span>

View File

@ -6,14 +6,14 @@
<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">
<!-- <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>
<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">
@ -80,8 +80,8 @@
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>
<!-- <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>

View File

@ -6,7 +6,7 @@
<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">
<!-- <div class="mt-4 sm:mt-0 sm:ml-16 sm:flex-none">
<button type="button"
class="inline-flex items-center justify-center px-4 py-2 border border-gray-300 shadow-sm text-sm font-medium rounded-2xl text-gray-700 bg-white hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-offset-gray-100 focus:ring-co-blue">
Changer de véhicule
@ -17,7 +17,7 @@
Annuler
</button>
</a>
</div>
</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">
@ -85,8 +85,8 @@
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>
<!-- <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>

View File

@ -846,6 +846,11 @@ html {
margin-bottom: 1rem;
}
.my-8 {
margin-top: 2rem;
margin-bottom: 2rem;
}
.-my-1\.5 {
margin-top: -0.375rem;
margin-bottom: -0.375rem;
@ -856,11 +861,6 @@ html {
margin-bottom: -0.25rem;
}
.my-8 {
margin-top: 2rem;
margin-bottom: 2rem;
}
.-mr-12 {
margin-right: -3rem;
}
@ -929,6 +929,18 @@ html {
margin-left: 1.25rem;
}
.ml-2 {
margin-left: 0.5rem;
}
.mb-4 {
margin-bottom: 1rem;
}
.mr-2 {
margin-right: 0.5rem;
}
.ml-6 {
margin-left: 1.5rem;
}
@ -945,10 +957,6 @@ html {
margin-top: -1rem;
}
.mb-4 {
margin-bottom: 1rem;
}
.-mt-2 {
margin-top: -0.5rem;
}
@ -957,30 +965,10 @@ html {
margin-right: -0.375rem;
}
.ml-2 {
margin-left: 0.5rem;
}
.-mr-1 {
margin-right: -0.25rem;
}
.mr-2 {
margin-right: 0.5rem;
}
.mr-0 {
margin-right: 0px;
}
.mt-16 {
margin-top: 4rem;
}
.mt-12 {
margin-top: 3rem;
}
.block {
display: block;
}
@ -1097,14 +1085,14 @@ html {
width: 4rem;
}
.w-12 {
width: 3rem;
}
.w-11 {
width: 2.75rem;
}
.w-12 {
width: 3rem;
}
.min-w-0 {
min-width: 0px;
}
@ -1438,6 +1426,16 @@ html {
border-bottom-right-radius: 1.5rem;
}
.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;
}
.rounded-l-md {
border-top-left-radius: 0.375rem;
border-bottom-left-radius: 0.375rem;
@ -1448,16 +1446,6 @@ html {
border-bottom-right-radius: 0.375rem;
}
.rounded-r-2xl {
border-top-right-radius: 1rem;
border-bottom-right-radius: 1rem;
}
.rounded-l-2xl {
border-top-left-radius: 1rem;
border-bottom-left-radius: 1rem;
}
.rounded-b-2xl {
border-bottom-right-radius: 1rem;
border-bottom-left-radius: 1rem;
@ -1555,6 +1543,11 @@ html {
background-color: rgb(255 221 0 / var(--tw-bg-opacity));
}
.bg-gray-200 {
--tw-bg-opacity: 1;
background-color: rgb(229 231 235 / var(--tw-bg-opacity));
}
.bg-gray-50 {
--tw-bg-opacity: 1;
background-color: rgb(249 250 251 / var(--tw-bg-opacity));
@ -1580,33 +1573,28 @@ html {
background-color: rgb(17 24 39 / var(--tw-bg-opacity));
}
.bg-gray-200 {
--tw-bg-opacity: 1;
background-color: rgb(229 231 235 / var(--tw-bg-opacity));
}
.bg-opacity-75 {
--tw-bg-opacity: 0.75;
}
.p-4 {
padding: 1rem;
}
.p-12 {
padding: 3rem;
}
.p-1 {
padding: 0.25rem;
}
.p-2 {
padding: 0.5rem;
}
.p-1\.5 {
padding: 0.375rem;
.p-4 {
padding: 1rem;
}
.p-1 {
padding: 0.25rem;
.p-1\.5 {
padding: 0.375rem;
}
.px-4 {
@ -1649,21 +1637,11 @@ html {
padding-bottom: 1rem;
}
.py-12 {
padding-top: 3rem;
padding-bottom: 3rem;
}
.px-3 {
padding-left: 0.75rem;
padding-right: 0.75rem;
}
.px-1 {
padding-left: 0.25rem;
padding-right: 0.25rem;
}
.py-3\.5 {
padding-top: 0.875rem;
padding-bottom: 0.875rem;
@ -1674,6 +1652,16 @@ html {
padding-bottom: 0.75rem;
}
.py-12 {
padding-top: 3rem;
padding-bottom: 3rem;
}
.px-1 {
padding-left: 0.25rem;
padding-right: 0.25rem;
}
.py-8 {
padding-top: 2rem;
padding-bottom: 2rem;
@ -1712,24 +1700,24 @@ html {
padding-right: 2.25rem;
}
.pl-1 {
padding-left: 0.25rem;
}
.pr-10 {
padding-right: 2.5rem;
}
.pl-4 {
padding-left: 1rem;
.pr-12 {
padding-right: 3rem;
}
.pr-4 {
padding-right: 1rem;
}
.pr-12 {
padding-right: 3rem;
.pl-4 {
padding-left: 1rem;
}
.pl-1 {
padding-left: 0.25rem;
}
.pr-10 {
padding-right: 2.5rem;
}
.pt-8 {
@ -1744,10 +1732,6 @@ html {
padding-left: 0.375rem;
}
.pb-1 {
padding-bottom: 0.25rem;
}
.text-left {
text-align: left;
}
@ -1760,10 +1744,6 @@ html {
text-align: right;
}
.text-justify {
text-align: justify;
}
.align-middle {
vertical-align: middle;
}
@ -2122,6 +2102,11 @@ html {
color: rgb(75 85 99 / var(--tw-text-opacity));
}
.hover\:text-co-blue:hover {
--tw-text-opacity: 1;
color: rgb(36 56 135 / var(--tw-text-opacity));
}
.hover\:text-white:hover {
--tw-text-opacity: 1;
color: rgb(255 255 255 / var(--tw-text-opacity));
@ -2132,11 +2117,6 @@ html {
color: rgb(55 65 81 / var(--tw-text-opacity));
}
.hover\:text-co-blue:hover {
--tw-text-opacity: 1;
color: rgb(36 56 135 / var(--tw-text-opacity));
}
.hover\:text-gray-900:hover {
--tw-text-opacity: 1;
color: rgb(17 24 39 / var(--tw-text-opacity));
@ -2255,25 +2235,20 @@ html {
grid-column: span 3 / span 3;
}
.sm\:col-span-4 {
grid-column: span 4 / span 4;
}
.sm\:col-span-2 {
grid-column: span 2 / span 2;
.sm\:col-span-6 {
grid-column: span 6 / span 6;
}
.sm\:col-span-1 {
grid-column: span 1 / span 1;
}
.sm\:col-span-6 {
grid-column: span 6 / span 6;
.sm\:col-span-2 {
grid-column: span 2 / span 2;
}
.sm\:mx-auto {
margin-left: auto;
margin-right: auto;
.sm\:col-span-4 {
grid-column: span 4 / span 4;
}
.sm\:-mx-6 {
@ -2281,6 +2256,11 @@ html {
margin-right: -1.5rem;
}
.sm\:mx-auto {
margin-left: auto;
margin-right: auto;
}
.sm\:mt-0 {
margin-top: 0px;
}
@ -2317,14 +2297,14 @@ html {
width: 100%;
}
.sm\:max-w-md {
max-width: 28rem;
}
.sm\:max-w-xs {
max-width: 20rem;
}
.sm\:max-w-md {
max-width: 28rem;
}
.sm\:flex-auto {
flex: 1 1 auto;
}