135 lines
5.2 KiB
Haskell
135 lines
5.2 KiB
Haskell
|
module Main where
|
||
|
|
||
|
import Database.PostgreSQL.Simple
|
||
|
import Control.Monad (forever, forM_)
|
||
|
import Control.Monad.IO.Class (liftIO)
|
||
|
import Control.Monad.Trans.Class (lift)
|
||
|
import Control.Monad.Trans.Reader (runReaderT, ask)
|
||
|
import Control.Exception (catch, SomeException)
|
||
|
import Data.Maybe (isJust, fromJust)
|
||
|
import Data.Time (Day)
|
||
|
import Data.Time.Format (parseTimeM, defaultTimeLocale)
|
||
|
import Data.Time.Calendar (Day)
|
||
|
|
||
|
import User
|
||
|
import Reservation
|
||
|
import Session
|
||
|
import Types
|
||
|
import Database
|
||
|
|
||
|
main :: IO ()
|
||
|
main = do
|
||
|
conn <- catch connectDB handleSqlError
|
||
|
initializeDB conn
|
||
|
addAdminUser conn
|
||
|
|
||
|
putStrLn "Welcome to the Ticket Booking System!"
|
||
|
user <- loginOrRegister conn
|
||
|
runSession user $ appLoop conn user
|
||
|
|
||
|
loginOrRegister :: Connection -> IO User
|
||
|
loginOrRegister conn = do
|
||
|
putStrLn "1) Register 2) Login"
|
||
|
choice <- getLine
|
||
|
case choice of
|
||
|
"1" -> do
|
||
|
putStrLn "Enter your name:"
|
||
|
name <- getLine
|
||
|
putStrLn "Enter your password:"
|
||
|
password <- getLine
|
||
|
registerUser conn name password
|
||
|
loginOrRegister conn
|
||
|
"2" -> do
|
||
|
putStrLn "Enter your name:"
|
||
|
name <- getLine
|
||
|
putStrLn "Enter your password:"
|
||
|
password <- getLine
|
||
|
mUser <- loginUser conn name password
|
||
|
if isJust mUser
|
||
|
then return (fromJust mUser)
|
||
|
else do
|
||
|
putStrLn "Invalid credentials, please try again."
|
||
|
loginOrRegister conn
|
||
|
_ -> do
|
||
|
putStrLn "Invalid option, please try again."
|
||
|
loginOrRegister conn
|
||
|
|
||
|
appLoop :: Connection -> User -> Session ()
|
||
|
appLoop conn user = forever $ do
|
||
|
lift $ putStrLn $ "Logged in as " ++ userName user ++ ". "
|
||
|
isAdminResult <- liftIO $ User.isAdmin conn (userName user)
|
||
|
|
||
|
if isAdminResult == Just True
|
||
|
then adminMenu
|
||
|
else userMenu
|
||
|
|
||
|
where
|
||
|
adminMenu = do
|
||
|
lift $ putStrLn "Admin Menu:"
|
||
|
lift $ putStrLn "1) Add event 2) View events 3) Exit"
|
||
|
choice <- lift getLine
|
||
|
case choice of
|
||
|
"1" -> do
|
||
|
lift $ putStrLn "Enter event name:"
|
||
|
eventName <- lift getLine
|
||
|
lift $ putStrLn "Enter event date (YYYY-MM-DD):"
|
||
|
eventDateStr <- lift getLine
|
||
|
case parseEventDate eventDateStr of
|
||
|
Just eventDate ->
|
||
|
if isValidEventDate eventDate
|
||
|
then do
|
||
|
lift $ addEvent conn user eventName eventDate
|
||
|
else lift $ putStrLn "Invalid event date. Please enter a date between 2024-05-27 and 2026-01-01, with a valid month (01-12) and day (01-31)."
|
||
|
Nothing -> lift $ putStrLn "Invalid date format. Please enter the date in the format YYYY-MM-DD."
|
||
|
"2" -> do
|
||
|
events <- lift $ getEvents conn
|
||
|
lift $ printEvents events
|
||
|
"3" -> liftIO $ putStrLn "Exiting..." >> error "Program terminated by user"
|
||
|
_ -> lift $ putStrLn "Invalid option. Please try again."
|
||
|
|
||
|
userMenu = do
|
||
|
lift $ putStrLn "User Menu:"
|
||
|
lift $ putStrLn "1) Add reservation 2) View reservations 3) View events 4) Check event attendees 5) Exit"
|
||
|
choice <- lift getLine
|
||
|
case choice of
|
||
|
"1" -> do
|
||
|
events <- lift $ getEvents conn
|
||
|
lift $ printEvents events
|
||
|
lift $ putStrLn "Enter event ID:"
|
||
|
eventIdStr <- lift getLine
|
||
|
let eventId = read eventIdStr :: Int
|
||
|
lift $ addReservation conn (userId user) eventId
|
||
|
"2" -> do
|
||
|
reservations <- lift $ getReservations conn (userId user)
|
||
|
lift $ putStrLn "Your reservations:"
|
||
|
lift $ forM_ reservations (printReservation conn)
|
||
|
"3" -> do
|
||
|
events <- lift $ getEvents conn
|
||
|
lift $ printEvents events
|
||
|
"4" -> do
|
||
|
events <- lift $ getEvents conn
|
||
|
lift $ printEvents events
|
||
|
lift $ putStrLn "Enter event ID to check attendees:"
|
||
|
eventIdStr <- lift getLine
|
||
|
let eventId = read eventIdStr :: Int
|
||
|
attendees <- lift $ getUsersForEvent conn eventId
|
||
|
lift $ putStrLn $ "Attendees for event " ++ show eventId ++ ":"
|
||
|
lift $ forM_ attendees $ \(userId, userName) -> putStrLn $ show userName
|
||
|
"5" -> liftIO $ putStrLn "Exiting..." >> error "Program terminated by user"
|
||
|
_ -> lift $ putStrLn "Invalid option. Please try again."
|
||
|
|
||
|
handleSqlError :: SomeException -> IO Connection
|
||
|
handleSqlError e = do
|
||
|
putStrLn $ "Database connection error: " ++ show e
|
||
|
error "Failed to connect to the database"
|
||
|
|
||
|
printEvents :: [Event] -> IO ()
|
||
|
printEvents events = do
|
||
|
putStrLn "Available events:"
|
||
|
forM_ events $ \event ->
|
||
|
putStrLn $ "Event ID: " ++ show (eventId event) ++ ", Name: " ++ eventName event ++ ", Date: " ++ show (eventDate event)
|
||
|
|
||
|
printReservation :: Connection -> Reservation -> IO ()
|
||
|
printReservation conn reservation = do
|
||
|
event <- getEvent conn (reservationEventId reservation)
|
||
|
putStrLn $ "Event Name: " ++ eventName event ++ ", Event Date: " ++ show (eventDate event)
|