Skip to content

Commit

Permalink
Add business
Browse files Browse the repository at this point in the history
  • Loading branch information
ciukstar committed Oct 1, 2023
1 parent c6a82ab commit 13fde43
Show file tree
Hide file tree
Showing 26 changed files with 1,059 additions and 371 deletions.
10 changes: 9 additions & 1 deletion config/models.persistentmodels
Original file line number Diff line number Diff line change
Expand Up @@ -100,4 +100,12 @@ Brand
strapline Textarea Maybe
ico ByteString Maybe
icoMime Text Maybe
more Textarea Maybe
more Textarea Maybe

Business
name Text
address Textarea
phone Text Maybe
mobile Text Maybe
email Text Maybe
UniqueBusiness name
13 changes: 10 additions & 3 deletions config/routes.yesodroutes
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,10 @@
/book/staff BookStaffR GET POST
/book BookOffersR GET POST

/search/requests RequestsSearchR GET
/requests/#BookId RequestR GET
/requests RequestsR GET
/search/requests RequestsSearchR GET
/requests/#BookId/approve RequestApproveR POST
/requests/#BookId RequestR GET
/requests RequestsR GET

/aboutus AboutUsR GET

Expand All @@ -40,6 +41,12 @@
/ HomeR GET

/admin AdminR:

/business/delete BusinessDeleteR POST
/business/#BusinessId/edit BusinessEditR GET POST
/business/create BusinessCreateR GET
/business BusinessR GET POST

/brand/#BrandId/ico BrandIcoR GET
/brand/#BrandId/mark BrandMarkR GET
/brand/delete BrandDeleteR POST
Expand Down
7 changes: 7 additions & 0 deletions messages/en.msg
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
BusinessAlreadyExists: Business already exists
NoBusinessYet: There is no business yet
Business: Business
Address: Address
Location: Location
ApproveAppointmentConfirm: Please confirm that you approve this appointment request
FromCoworkers: From coworkers
DemoUserAccounts: Demo user accounts
WithoutAssignee: Without assignee
Expand Down Expand Up @@ -64,6 +70,7 @@ NoAppointmentsYet: You have no appointments yet
LoginToSeeYourAppointments: Please login to see your appointments
MyAppointments: My appointments
Time: Time
Date: Date
Day: Day
NotYourAccount: Not your account
Continue: Continue
Expand Down
7 changes: 7 additions & 0 deletions messages/fr.msg
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
BusinessAlreadyExists: L'entreprise existe déjà
NoBusinessYet: Il n'y a pas encore d'entreprise
Business: Entreprise
Address: Adresse
Location: Lieu
ApproveAppointmentConfirm: Veuillez confirmer que vous approuvez cette demande de rendez-vous
FromCoworkers: Des collègues
DemoUserAccounts: Comptes utilisateurs démo
WithoutAssignee: Sans exécuteur
Expand Down Expand Up @@ -64,6 +70,7 @@ NoAppointmentsYet: Vous n'avez pas encore de rendez-vous
LoginToSeeYourAppointments: Veuillez vous connecter pour voir vos rendez-vous
MyAppointments: Mes rendez-vous
Time: Heure
Date: Date
Day: Jour
NotYourAccount: Pas votre compte
Continue: Continuez
Expand Down
7 changes: 7 additions & 0 deletions messages/ro.msg
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
BusinessAlreadyExists: Afacerea există deja
NoBusinessYet: Nu există încă nicio afacere
Business: Afacere
Address: Adresă
Location: Locația
ApproveAppointmentConfirm: Vă rugăm să confirmați că ați aprobat această solicitare de programare
FromCoworkers: De la colegi
DemoUserAccounts: Conturi de utilizator Demo
WithoutAssignee: Fără executor
Expand Down Expand Up @@ -64,6 +70,7 @@ NoAppointmentsYet: Nu aveți încă programări
LoginToSeeYourAppointments: Vă rugăm să vă autentificați pentru a vă vedea programările
MyAppointments: Programările mele
Time: Ora
Date: Data
Day: Ziua
NotYourAccount: Nu e contul dvs.
Continue: Continuați
Expand Down
7 changes: 7 additions & 0 deletions messages/ru.msg
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
BusinessAlreadyExists: Организация уже существует
NoBusinessYet: Организации пока нет
Business: Организация
Address: Адрес
Location: Место
ApproveAppointmentConfirm: Пожалуйста, подтвердите, что вы одобряете этот запрос на встречу
FromCoworkers: От коллег
DemoUserAccounts: Демо-аккаунты
WithoutAssignee: Без исполнителя
Expand Down Expand Up @@ -64,6 +70,7 @@ NoAppointmentsYet: У вас еще нет записей
LoginToSeeYourAppointments: Пожалуйста, войдите, чтобы увидеть ваши записи
MyAppointments: Мои записи на приём
Time: Время
Date: Дата
Day: День
NotYourAccount: Не ваша учетная запись
Continue: Продолжить
Expand Down
231 changes: 231 additions & 0 deletions src/Admin/Business.hs
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}

module Admin.Business
( getBusinessR
, postBusinessR
, getBusinessCreateR
, getBusinessEditR
, postBusinessEditR
, postBusinessDeleteR
) where

import Control.Monad (void)
import Data.Maybe (isNothing, isJust)
import Data.Text (Text)
import Text.Hamlet (Html)
import Yesod.Auth (maybeAuth, Route (LoginR))
import Yesod.Core
( Yesod(defaultLayout), getMessages, whamlet, SomeMessage (SomeMessage)
, redirect, addMessageI
)
import Yesod.Core.Handler (setUltDestCurrent)
import Yesod.Core.Widget (setTitleI)
import Yesod.Form.Fields (textField, emailField, textareaField)
import Yesod.Form.Functions (generateFormPost, mreq, mopt, runFormPost, checkM)
import Yesod.Form.Types
( MForm, FormResult (FormSuccess), FieldView (fvLabel, fvInput, fvErrors)
, FieldSettings (FieldSettings, fsLabel, fsTooltip, fsId, fsName, fsAttrs)
, Field
)

import Settings (widgetFile)

import Foundation
( Handler, Widget
, Route (ProfileR, AccountPhotoR, PhotoPlaceholderR, AuthR, AdminR)
, AdminR (BusinessR, BusinessCreateR, BusinessEditR, BusinessDeleteR)
, AppMessage
( MsgBusiness, MsgPhoto, MsgNoBusinessYet, MsgTheName, MsgAddress
, MsgPhone, MsgMobile, MsgEmail, MsgSave, MsgCancel, MsgRecordAdded
, MsgYesDelete, MsgDeleteAreYouSure, MsgPleaseConfirm, MsgRecordEdited
, MsgRecordDeleted, MsgBusinessAlreadyExists
)
)

import Yesod.Persist.Core (YesodPersist(runDB))
import Database.Persist (Entity (Entity, entityVal), PersistStoreWrite (insert_))
import Database.Esqueleto.Experimental
( selectOne, from, table, update, set, val, where_, delete
, (=.), (^.), (==.)
)

import Model
( Business
( Business, businessName, businessAddress, businessPhone, businessMobile
, businessEmail
)
, BusinessId
, EntityField
( BusinessName, BusinessAddress, BusinessPhone, BusinessMobile, BusinessEmail
, BusinessId
)
)

import Menu (menu)


postBusinessDeleteR :: Handler Html
postBusinessDeleteR = do
runDB $ delete $ void $ from (table @Business)
addMessageI "info" MsgRecordDeleted
redirect $ AdminR BusinessR


postBusinessEditR :: BusinessId -> Handler Html
postBusinessEditR bid = do
business <- runDB $ selectOne $ do
x <- from $ table @Business
where_ $ x ^. BusinessId ==. val bid
return x
((fr,fw),et) <- runFormPost $ formBusiness business
case fr of
FormSuccess (Business name address phone mobile email) -> do
runDB $ update $ \x -> do
set x [ BusinessName =. val name
, BusinessAddress =. val address
, BusinessPhone =. val phone
, BusinessMobile =. val mobile
, BusinessEmail =. val email
]
where_ $ x ^. BusinessId ==. val bid
addMessageI "info" MsgRecordEdited
redirect $ AdminR BusinessR
_ -> defaultLayout $ do
setTitleI MsgBusiness
$(widgetFile "admin/business/edit")


getBusinessEditR :: BusinessId -> Handler Html
getBusinessEditR bid = do
business <- runDB $ selectOne $ from $ table @Business
(fw,et) <- generateFormPost $ formBusiness business
defaultLayout $ do
setTitleI MsgBusiness
$(widgetFile "admin/business/edit")


getBusinessCreateR :: Handler Html
getBusinessCreateR = do
(fw,et) <- generateFormPost $ formBusiness Nothing
defaultLayout $ do
setTitleI MsgBusiness
$(widgetFile "admin/business/create")


postBusinessR :: Handler Html
postBusinessR = do
((fr,fw),et) <- runFormPost $ formBusiness Nothing
business <- runDB $ selectOne $ from $ table @Business
case (fr,business) of
(FormSuccess r,Nothing) -> do
runDB $ insert_ r
addMessageI "info" MsgRecordAdded
redirect $ AdminR BusinessR
(_,Just _) -> do
addMessageI "warn" MsgBusinessAlreadyExists
redirect $ AdminR BusinessR
_ -> defaultLayout $ do
setTitleI MsgBusiness
$(widgetFile "admin/business/create")


getBusinessR :: Handler Html
getBusinessR = do
user <- maybeAuth
business <- runDB $ selectOne $ from $ table @Business
setUltDestCurrent
msgs <- getMessages
defaultLayout $ do
setTitleI MsgBusiness
$(widgetFile "admin/business/business")


formBusiness :: Maybe (Entity Business) -> Html -> MForm Handler (FormResult Business, Widget)
formBusiness business extra = do
(nameR,nameV) <- mreq uniqueNameField FieldSettings
{ fsLabel = SomeMessage MsgTheName
, fsTooltip = Nothing, fsId = Nothing, fsName = Nothing
, fsAttrs = [("class","mdc-text-field__input")]
} (businessName . entityVal <$> business)
(addrR,addrV) <- mreq textareaField FieldSettings
{ fsLabel = SomeMessage MsgAddress
, fsTooltip = Nothing, fsId = Nothing, fsName = Nothing
, fsAttrs = [("class","mdc-text-field__input")]
} (businessAddress . entityVal <$> business)
(phoneR,phoneV) <- mopt textField FieldSettings
{ fsLabel = SomeMessage MsgPhone
, fsTooltip = Nothing, fsId = Nothing, fsName = Nothing
, fsAttrs = [("class","mdc-text-field__input")]
} (businessPhone . entityVal <$> business)
(mobileR,mobileV) <- mopt textField FieldSettings
{ fsLabel = SomeMessage MsgMobile
, fsTooltip = Nothing, fsId = Nothing, fsName = Nothing
, fsAttrs = [("class","mdc-text-field__input")]
} (businessMobile . entityVal <$> business)
(emailR,emailV) <- mopt emailField FieldSettings
{ fsLabel = SomeMessage MsgEmail
, fsTooltip = Nothing, fsId = Nothing, fsName = Nothing
, fsAttrs = [("class","mdc-text-field__input")]
} (businessEmail . entityVal <$> business)

let r = Business <$> nameR <*> addrR <*> phoneR <*> mobileR <*> emailR
let w = [whamlet|
#{extra}
<div.form-field>
<div.mdc-text-field.mdc-text-field--filled data-mdc-auto-init=MDCTextField
:isJust (fvErrors nameV):.mdc-text-field--invalid>
<span.mdc-text-field__ripple>
<span.mdc-floating-label>#{fvLabel nameV}
^{fvInput nameV}
<span.mdc-line-ripple>
$maybe errs <- fvErrors nameV
<div.mdc-text-field-helper-line>
<div.mdc-text-field-helper-text.mdc-text-field-helper-text--validation-msg aria-hidden=true>
#{errs}

<div.form-field>
<div.mdc-text-field.mdc-text-field--textarea.mdc-text-field--filled data-mdc-auto-init=MDCTextField
:isJust (fvErrors addrV):.mdc-text-field--invalid>
<span.mdc-text-field__ripple>
<span.mdc-floating-label>#{fvLabel addrV}
<span.mdc-text-field__resizer>
^{fvInput addrV}
<span.mdc-line-ripple>
$maybe errs <- fvErrors addrV
<div.mdc-text-field-helper-line>
<div.mdc-text-field-helper-text.mdc-text-field-helper-text--validation-msg aria-hidden=true>
#{errs}

$forall v <- [phoneV,mobileV,emailV]
<div.form-field>
<div.mdc-text-field.mdc-text-field--filled data-mdc-auto-init=MDCTextField
:isJust (fvErrors v):.mdc-text-field--invalid>
<span.mdc-text-field__ripple>
<span.mdc-floating-label>#{fvLabel v}
^{fvInput v}
<span.mdc-line-ripple>
$maybe errs <- fvErrors v
<div.mdc-text-field-helper-line>
<div.mdc-text-field-helper-text.mdc-text-field-helper-text--validation-msg aria-hidden=true>
#{errs}
|]
return (r,w)
where
uniqueNameField :: Field Handler Text
uniqueNameField = checkM uniqueName textField

uniqueName :: Text -> Handler (Either AppMessage Text)
uniqueName name = do
mx <- runDB $ selectOne $ do
x <- from $ table @Business
where_ $ x ^. BusinessName ==. val name
return x
return $ case mx of
Nothing -> Right name
Just (Entity eid _) -> case business of
Nothing -> Left MsgBusinessAlreadyExists
Just (Entity eid' _) | eid == eid' -> Right name
| otherwise -> Left MsgBusinessAlreadyExists
9 changes: 8 additions & 1 deletion src/Application.hs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ import System.Environment.Blank (getEnv)

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

import Handler.Appointments
Expand Down Expand Up @@ -80,6 +80,13 @@ import Handler.Account (getProfileR, getAccountR, postAccountR, getAccountPhotoR
import Handler.Home (getHomeR)
import Handler.Resources (getDocsR)

import Admin.Business
( getBusinessR, postBusinessR
, getBusinessCreateR
, getBusinessEditR, postBusinessEditR
, postBusinessDeleteR
)

import Admin.Brand
( getBrandR, getBrandMarkR, getBrandIcoR, postBrandR, getBrandEditR
, postBrandEditR, postBrandDeleteR, getBrandCreateR
Expand Down
8 changes: 8 additions & 0 deletions src/Demo/DemoDataEN.hs
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ import Model
, Contents (Contents, contentsSection, contentsContent)
, BookStatus (BookStatusRequest)
, Book (Book, bookUser, bookOffer, bookRole, bookDay, bookTime, bookTz, bookStatus)
, Business (Business, businessName, businessAddress, businessPhone, businessMobile, businessEmail)
)
import Data.FileEmbed (embedFile)
import Demo.DemoPhotos
Expand All @@ -51,6 +52,13 @@ populateEN = do

(today,time) <- liftIO $ getCurrentTime >>= \x -> return (utctDay x,timeToTimeOfDay (utctDayTime x))

insert_ $ Business { businessName = "Salon"
, businessAddress = "5331 Rexford Court, Montgomery AL 36116"
, businessPhone = Just "937-810-6140"
, businessMobile = Just "567-274-7469"
, businessEmail = Just "[email protected]"
}

insert_ $ Contents { contentsSection = "CONTACTS"
, contentsContent = Textarea [st|
<section style="margin:0 1rem">
Expand Down
Loading

0 comments on commit 13fde43

Please sign in to comment.