Skip to content

Commit

Permalink
Add some filters
Browse files Browse the repository at this point in the history
  • Loading branch information
ciukstar committed Sep 28, 2023
1 parent 2065e9c commit 0ad24b7
Show file tree
Hide file tree
Showing 20 changed files with 569 additions and 50 deletions.
3 changes: 2 additions & 1 deletion config/routes.yesodroutes
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
/book/staff BookStaffR GET POST
/book BookOffersR GET POST

/request RequestsR GET
/requests/#BookId RequestR GET
/requests RequestsR GET

/aboutus AboutUsR GET

Expand Down
6 changes: 6 additions & 0 deletions messages/en.msg
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Assignee: Assignee
ShowAll: Show all
Approve: Approve
Request: Request
LoginToSeeTheRequests: Please login to see the requests
NoPendingRequestsYet: No requests for approval yet
NoRequestsYet: There are no requests yet
AppointmentStateDiagram: State transition diagram for appointment
NoHistoryYet: There is no history yet
Expand Down
6 changes: 6 additions & 0 deletions messages/fr.msg
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Assignee: Désigné
ShowAll: Afficher tout
Approve: Approuver
Request: Demande
LoginToSeeTheRequests: Veuillez vous connecter pour voir les demandes
NoPendingRequestsYet: Il n'y a pas encore de demandes d'approbation
NoRequestsYet: Il n'y a pas encore de demandes
AppointmentStateDiagram: Diagramme de transition d'état de rendez-vous
NoHistoryYet: Il n'y a pas encore d'historique
Expand Down
6 changes: 6 additions & 0 deletions messages/ro.msg
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Assignee: Desemnatul
ShowAll: Arată tot
Approve: Aprobă
Request: Solicitare
LoginToSeeTheRequests: Vă rugăm să vă conectați pentru a vedea solicitările
NoPendingRequestsYet: Nu există încă cereri de aprobare
NoRequestsYet: Nu există încă solicitări
AppointmentStateDiagram: Diagrama tranziție de stare a programării
NoHistoryYet: Nu există încă istorie
Expand Down
6 changes: 6 additions & 0 deletions messages/ru.msg
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
Assignee: Исполнитель
ShowAll: Показать всё
Approve: Утвердить
Request: Запрос
LoginToSeeTheRequests: Пожалуйста, войдите, чтобы увидеть запросы
NoPendingRequestsYet: Запросов на одобрение пока нет
NoRequestsYet: Запросов пока нет
AppointmentStateDiagram: Схема перехода состояний для записи на прием
NoHistoryYet: Истории пока нет
Expand Down
2 changes: 1 addition & 1 deletion src/Application.hs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ import System.Environment.Blank (getEnv)
-- Import all relevant handler modules here.
-- Don't forget to add new modules to your cabal file!

import Handler.Requests (getRequestsR)
import Handler.Requests (getRequestsR, getRequestR)

import Handler.Appointments
( getAppointmentsR, getAppointmentR, postAppointmentR
Expand Down
3 changes: 2 additions & 1 deletion src/Foundation.hs
Original file line number Diff line number Diff line change
Expand Up @@ -194,7 +194,8 @@ instance Yesod App where
isAuthorized (AppointmentRescheduleR _) _ = return Authorized

isAuthorized RequestsR _ = return Authorized

isAuthorized (RequestR _) _ = return Authorized


isAuthorized AccountR _ = return Authorized
isAuthorized (AccountPhotoR _) _ = return Authorized
Expand Down
105 changes: 88 additions & 17 deletions src/Handler/Requests.hs
Original file line number Diff line number Diff line change
@@ -1,52 +1,110 @@
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}

module Handler.Requests (getRequestsR) where
module Handler.Requests (getRequestsR, getRequestR) where

import Data.Text (intercalate, unpack, Text)
import Data.Maybe (mapMaybe)
import Data.Text (intercalate, unpack, Text, pack)
import Data.Time.Format (defaultTimeLocale, formatTime)
import Text.Hamlet (Html)
import Text.Read (readMaybe)
import Text.Shakespeare.I18N (renderMessage)
import Yesod.Core
( Yesod(defaultLayout), setUltDestCurrent, getMessages
, getYesod, languages
, getYesod, languages, preEscapedToMarkup, whamlet, getRequest
, YesodRequest (reqGetParams), newIdent
)
import Yesod.Core.Widget (setTitleI)
import Yesod.Auth ( Route(LoginR), maybeAuth )
import Yesod.Auth ( Route(LoginR, LogoutR), maybeAuth )
import Yesod.Form.Fields (Textarea(unTextarea))
import Yesod.Form.Types (MForm, FormResult (FormSuccess))
import Yesod.Form.Functions (generateFormPost)
import Settings (widgetFile)

import Foundation
( Handler
, Route (AuthR, PhotoPlaceholderR, AccountPhotoR, ProfileR)
( Handler, Widget
, Route
( AuthR, PhotoPlaceholderR, AccountPhotoR, ProfileR, RequestsR, RequestR
, AppointmentCancelR, AppointmentHistR, AppointmentRescheduleR, AdminR
, ServiceThumbnailR
)
, AdminR (AdmStaffPhotoR)
, AppMessage
( MsgRequests, MsgPhoto, MsgLogin, MsgSymbolHour, MsgSymbolMinute
, MsgAwaitingApproval, MsgApproved, MsgCancelled, MsgPaid
, MsgNoRequestsYet
( MsgRequests, MsgPhoto, MsgLogin, MsgLogout, MsgSymbolHour
, MsgSymbolMinute, MsgAwaitingApproval, MsgApproved, MsgCancelled
, MsgPaid, MsgLoginToSeeTheRequests, MsgRequest, MsgStatus, MsgAssignee
, MsgYes, MsgNo, MsgCancelAppointmentReally, MsgPleaseConfirm, MsgHistory
, MsgReschedule, MsgMeetingLocation, MsgCustomer, MsgSelect, MsgCancel
, MsgService, MsgMeetingTime, MsgAcquaintance, MsgAppoinmentStatus
, MsgDuration, MsgApprove, MsgNoPendingRequestsYet, MsgShowAll
)
)

import Database.Persist (Entity (Entity))
import Yesod.Persist.Core (YesodPersist(runDB))
import Database.Esqueleto.Experimental
( select, from, table, innerJoin, on, where_, val
, (:&)((:&)), (==.), (^.)
, orderBy, desc
( select, from, table, innerJoin, leftJoin, on, where_, val
, (:&)((:&)), (==.), (^.), (?.)
, orderBy, desc, just, selectOne, valList, in_
)

import Model
( Book(Book), Offer, Service (Service)
, BookStatus (BookStatusRequest, BookStatusApproved, BookStatusCancelled, BookStatusPaid)
( Book (Book), BookId, Offer, Service (Service), Role (Role), Staff (Staff)
, Offer (Offer), Thumbnail (Thumbnail), User (User), Contents (Contents)
, BookStatus
( BookStatusRequest, BookStatusApproved, BookStatusCancelled
, BookStatusPaid
)
, EntityField
( BookOffer, OfferId, OfferService, ServiceId, BookUser, BookDay, BookTime
( BookOffer, OfferId, OfferService, ServiceId, BookDay, BookTime
, BookRole, RoleId, RoleStaff, StaffId, StaffUser, ContentsSection, BookId
, ThumbnailService, BookUser, UserId, BookStatus
)
)

import Menu (menu)
import Handler.Contacts (section)


getRequestR :: BookId -> Handler Html
getRequestR bid = do
stati <- filter ((== "status") . fst) . reqGetParams <$> getRequest
app <- getYesod
langs <- languages
user <- maybeAuth
location <- runDB $ selectOne $ do
x <- from $ table @Contents
where_ $ x ^. ContentsSection ==. val section
return x
request <- runDB $ selectOne $ do
x :& o :& s :& t :& r :& e :& c <- from $ table @Book
`innerJoin` table @Offer `on` (\(x :& o) -> x ^. BookOffer ==. o ^. OfferId)
`innerJoin` table @Service `on` (\(_ :& o :& s) -> o ^. OfferService ==. s ^. ServiceId)
`leftJoin` table @Thumbnail `on` (\(_ :& _ :& s :& t) -> just (s ^. ServiceId) ==. t ?. ThumbnailService)
`innerJoin` table @Role `on` (\(x :& _ :& _ :& _ :& r) -> x ^. BookRole ==. just (r ^. RoleId))
`innerJoin` table @Staff `on` (\(_ :& _ :& _ :& _ :& r :& e) -> r ^. RoleStaff ==. e ^. StaffId)
`innerJoin` table @User `on` (\(x :& _ :& _ :& _ :& _ :& _ :& c) -> x ^. BookUser ==. c ^. UserId)
where_ $ x ^. BookId ==. val bid
case user of
Just (Entity uid _) -> where_ $ e ^. StaffUser ==. just (val uid)
Nothing -> where_ $ val False
return (x,o,s,t,r,e,c)
msgs <- getMessages
(fw,et) <- generateFormPost formCancel
defaultLayout $ do
setTitleI MsgRequest
$(widgetFile "requests/request")


formCancel :: Html -> MForm Handler (FormResult (), Widget)
formCancel extra = return (FormSuccess (),[whamlet|#{extra}|])


getRequestsR :: Handler Html
getRequestsR = do
stati <- filter ((== "status") . fst) . reqGetParams <$> getRequest
user <- maybeAuth
setUltDestCurrent
msgs <- getMessages
Expand All @@ -57,11 +115,24 @@ getRequestsR = do
Just (Entity uid _) -> do
app <- getYesod
langs <- languages
dlgStatusList <- newIdent
let statusList = [ (BookStatusRequest, MsgRequest)
, (BookStatusApproved, MsgApproved)
, (BookStatusCancelled, MsgCancelled)
, (BookStatusPaid, MsgPaid)
]
let states = mapMaybe (readMaybe . unpack . snd) stati
dlgAssignee <- newIdent
requests <- runDB $ select $ do
x :& _ :& s <- from $ table @Book
x :& _ :& s :& _ :& e <- from $ table @Book
`innerJoin` table @Offer `on` (\(x :& o) -> x ^. BookOffer ==. o ^. OfferId)
`innerJoin` table @Service `on` (\(_ :& o :& s) -> o ^. OfferService ==. s ^. ServiceId)
where_ $ x ^. BookUser ==. val uid
`innerJoin` table @Role `on` (\(x :& _ :& _ :& r) -> x ^. BookRole ==. just (r ^. RoleId))
`innerJoin` table @Staff `on` (\(_ :& _ :& _ :& r :& e) -> r ^. RoleStaff ==. e ^. StaffId)
where_ $ e ^. StaffUser ==. just (val uid)
case states of
[] -> return ()
xs -> where_ $ x ^. BookStatus `in_` valList xs
orderBy [desc (x ^. BookDay), desc (x ^. BookTime)]
return (x,s)
defaultLayout $ do
Expand Down
4 changes: 3 additions & 1 deletion src/Menu.hs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE OverloadedStrings #-}

module Menu (menu) where

import Data.Text (pack)
import Yesod.Core.Handler (getCurrentRoute)
import Foundation
( Widget
Expand All @@ -21,7 +23,7 @@ import Foundation
)
)

import Model (Services (Services))
import Model (BookStatus (BookStatusRequest), Services (Services))

import Settings (widgetFile)
import Settings.StaticFiles (img_salon_svg)
Expand Down
47 changes: 23 additions & 24 deletions templates/appointments/appointment.hamlet
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,29 @@
<span.mdc-button__focus-ring>
<span.mdc-button__label>_{MsgCancelAppointment}

<form method=post action=@{AppointmentCancelR bid} #formAppoitmentCancel enctype=#{et}>
^{fw}

<div.mdc-dialog #dlgCancelAppointment data-mdc-auto-init=MDCDialog>
<div.mdc-dialog__container>
<div.mdc-dialog__surface tabindex=-1 role=alertdialog aria-modal=true>
<h4.mdc-dialog__title>_{MsgPleaseConfirm}
<div.mdc-dialog__content>
_{MsgCancelAppointmentReally}

<div.mdc-dialog__actions>
<button.mdc-dialog__button.mdc-button type=button data-mdc-dialog-action=close>
<span.mdc-button__ripple>
<span.mdc-button__focus-ring>
<span.mdc-button__label>_{MsgNo}

<button.mdc-dialog__button.mdc-button.mdc-button--raised type=submit form=formAppoitmentCancel>
<span.mdc-button__ripple>
<span.mdc-button__focus-ring>
<span.mdc-button__label>_{MsgYes}

<div.mdc-dialog__scrim>

<form method=get action=@{AppointmentRescheduleR bid} #formGetAppointmentReschedule>
<button.mdc-card__action.mdc-card__action--button.mdc-button.mdc-button--unelevated
type=submit name=tz form=formGetAppointmentReschedule onclick="this.value = -(new Date().getTimezoneOffset())">
Expand All @@ -169,27 +192,3 @@
<span.mdc-icon-button__ripple>
<span.mdc-icon-button__focus-ring>
<i.material-symbols-outlined>history


<form method=post action=@{AppointmentCancelR bid} #formAppoitmentCancel enctype=#{et}>
^{fw}

<div.mdc-dialog #dlgCancelAppointment data-mdc-auto-init=MDCDialog>
<div.mdc-dialog__container>
<div.mdc-dialog__surface tabindex=-1 role=alertdialog aria-modal=true>
<h4.mdc-dialog__title>_{MsgPleaseConfirm}
<div.mdc-dialog__content>
_{MsgCancelAppointmentReally}

<div.mdc-dialog__actions>
<button.mdc-dialog__button.mdc-button type=button data-mdc-dialog-action=close>
<span.mdc-button__ripple>
<span.mdc-button__focus-ring>
<span.mdc-button__label>_{MsgNo}

<button.mdc-dialog__button.mdc-button.mdc-button--raised type=submit form=formAppoitmentCancel>
<span.mdc-button__ripple>
<span.mdc-button__focus-ring>
<span.mdc-button__label>_{MsgYes}

<div.mdc-dialog__scrim>
2 changes: 1 addition & 1 deletion templates/menu.hamlet
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
<i.mdc-deprecated-list-item__graphic.material-symbols-outlined>pending_actions
<span.mdc-deprecated-list-item__text>_{MsgMyAppointments}

<a.mdc-deprecated-list-item href=@{RequestsR}
<a.mdc-deprecated-list-item href=@?{(RequestsR,[("status",pack $ show BookStatusRequest)])}
:Just RequestsR /= curr:tabindex=-1
:Just RequestsR == curr:tabindex=0
:Just RequestsR == curr:.mdc-deprecated-list-item--activated>
Expand Down
15 changes: 15 additions & 0 deletions templates/requests/login.cassius
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

header.mdc-top-app-bar
div.mdc-top-app-bar__row
transition: height 0.3s ease-out

main
margin: 0 1rem
display: flex
flex-direction: column
align-items: center
figure
text-align: center
i.material-symbols-outlined
font-size: 4rem
color: var(--mdc-theme-primary)
52 changes: 52 additions & 0 deletions templates/requests/login.hamlet
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
^{menu}
<header.mdc-top-app-bar.mdc-top-app-bar--prominent.mdc-top-app-bar--fixed data-mdc-auto-init=MDCTopAppBar>
<div.mdc-top-app-bar__row>
<section.mdc-top-app-bar__section.mdc-top-app-bar__section--align-start>
<button.mdc-top-app-bar__navigation-icon.mdc-icon-button #btnMainMenu>
<span.mdc-icon-button__ripple>
<i.material-symbols-outlined>menu
<span.mdc-top-app-bar__title.mdc-theme--text-primary-on-light>
_{MsgRequests}

<section.mdc-top-app-bar__section.mdc-top-app-bar__section--align-end role=toolbar>
$maybe Entity uid _ <- user
<button.mdc-top-app-bar__action-item.mdc-icon-button type=button #buttonProfile>
<span.mdc-icon-button__ripple>
<img src=@{AccountPhotoR uid} style="clip-path:circle(50%)" alt=_{MsgPhoto}
onerror="this.src = '@{PhotoPlaceholderR}'">

<div.mdc-menu-surface--anchor>
<div.mdc-menu.mdc-menu-surface data-mdc-auto-init=MDCMenuSurface>
<ul.mdc-deprecated-list.mdc-deprecated-list--icon-list
role=menu aria-hidden=true aria-orientation=vertical tabindex=-1>

<a.mdc-deprecated-list-item role=menuitem href=@{AuthR LogoutR}>
<span.mdc-deprecated-list-item__ripple>
<i.material-symbols-outlined style="margin-right:1rem">logout
<span.mdc-deprecated-list-item__text>_{MsgLogout}
$nothing
<a.mdc-top-app-bar__action-item.mdc-icon-button role=button href=@{AuthR LoginR}>
<span.mdc-icon-button__ripple>
<i.material-symbols-outlined>login


<main.mdc-top-app-bar--prominent-fixed-adjust>
<figure>
<i.material-symbols-outlined>key
<figcaption>
_{MsgLoginToSeeTheRequests}.

<a.mdc-button.mdc-button--raised href=@{AuthR LoginR} role=button>
<span.mdc-button__ripple>
<span.mdc-button__focus-ring>
<span.mdc-button__label>_{MsgLogin}

$forall (_,msg) <- msgs
<aside.mdc-snackbar data-mdc-auto-init=MDCSnackbar>
<div.mdc-snackbar__surface>
<div.mdc-snackbar__label>#{msg}
<div.mdc-snackbar__actions>
<button.mdc-snackbar__dismiss.mdc-icon-button type=button>
<span.mdc-icon-button__ripple>
<span.mdc-icon-button__focus-ring>
<i.material-symbols-outlined>close
14 changes: 14 additions & 0 deletions templates/requests/login.julius
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@

window.mdc.autoInit();

window.onscroll = function (e) {
if (document.body.scrollTop > 128 || document.documentElement.scrollTop > 128) {
document.querySelector('header.mdc-top-app-bar').classList.remove('mdc-top-app-bar--prominent');
} else {
document.querySelector('header.mdc-top-app-bar').classList.add('mdc-top-app-bar--prominent');
}
};

Array.from(
document.querySelectorAll('aside.mdc-snackbar')
).forEach(function (x) { x.MDCSnackbar.open(); });
Loading

0 comments on commit 0ad24b7

Please sign in to comment.