ticket-booking-main/app/Main.hs
2024-05-27 14:47:43 +02:00

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)