module ControllerGetActions where import Control.Monad.Reader import Control.Monad import Happstack.Server import Happstack.State import Data.List import Happstack.Helpers import qualified Data.ByteString.Char8 as B import ControllerMisc import StateVersions.AppState1 import View import FromDataInstances import Misc import qualified MiscMap as M viewConsultants :: RenderGlobals -> ServerPartT IO Response viewConsultants rglobs = do PaginationUrlData currB resPB currP resPP <- getData' consultants <- fmap (map unusername . M.keys . M.filter (consultant . userprofile) . users) $ query AskDatastore let p = Pagination { currentbar = currB , resultsPerBar = resPB , currentpage = currP , resultsPerPage = resPP , baselink = "tutorial/consultants" , paginationtitle = ""} consultantCells = map ( return . userlink ) consultants consultantTable = paintTable Nothing consultantCells (Just p) -- if not logged in, you get an invite to register as a consultant -- basically an incentive to register tmplattrs = maybe (def ++ [("registerAsConsultant","list yourself as a Happstack developer")]) (const def) (mbUser rglobs) where def = [("consultantList", consultantTable)] return . tutlayoutU rglobs tmplattrs $ "consultants" viewConsultantsWanted :: RenderGlobals -> ServerPartT IO Response viewConsultantsWanted rglobs = do (PaginationUrlData currB resPB currP resPP) <- getData' consultantswanted <- return . map unusername . M.keys =<< return . M.filter (not . M.null . unjobs . jobs ) . users =<< query AskDatastore let p = Pagination { currentbar = currB ,resultsPerBar = resPB , currentpage = currP , resultsPerPage = resPP , baselink = "tutorial/consultantswanted" , paginationtitle = ""} consultantCells = map ( return . userlink ) consultantswanted consultantTable = paintTable Nothing consultantCells (Just p) -- an incentive to register tmplattrs = maybe (def ++ [("postJob","post a Happstack job")]) (const def ) (mbUser rglobs) where def = [("ulist", consultantTable)] return . tutlayoutU rglobs tmplattrs $ "consultantswanted" viewJobs :: RenderGlobals -> ServerPartT IO Response viewJobs rglobs = do PaginationUrlData currB resPB currP resPP <- getData' rsListAllJobs <- query ListAllJobs let pag = Pagination { currentbar = currB , resultsPerBar = resPB , currentpage = currP , resultsPerPage = resPP , baselink = "tutorial/jobs" , paginationtitle = "Job Results: "} jobCells = map f rsListAllJobs where f (JobName j', (Job budget _), UserName posted) = let j = B.unpack j' in [ joblink posted j , B.unpack budget , userlink posted ] paintAllJobsTable _ j p = paintTable (Just ["project","budget","posted by"]) j (Just p) jobTable = paintAllJobsTable rglobs jobCells pag -- if not logged in, you get invited to post a job, -- basically an incentive to register -- this next line should be coming from a template, and it's duplicated elsewhere, slightly bad. tmplattrs = maybe (def++[("postJob","post a Happstack job")]) (const def) (return . sesUser =<< mbSession rglobs) where def = [("jobTable", jobTable)] return . tutlayoutU rglobs tmplattrs $ "jobs" -- better name would be just viewEditProfile, since everyone gets a profile, not just consultants. viewEditConsultantProfile :: RenderGlobals -> ServerPartT IO Response viewEditConsultantProfile rglobs = case mbUser rglobs of Nothing -> return . tutlayoutU rglobs [("errormsg", "error: no user")] $ "errortemplate" Just currU -> do mbUis <- query $ GetUserInfos currU case mbUis of Nothing -> return . tutlayoutU rglobs [("errormsg", "error: no user infos")] $ "errortemplate" Just uis -> do let cp = userprofile uis uimage <- liftIO $ avatarimage currU -- use show below to properly escape quotes let showPr = paintProfile rglobs (B.unpack . unusername $ currU) cp uimage attrs = [ ("username", B.unpack . unusername $ currU) , ("userimage", uimage) , ("blurb", B.unpack . blurb $ cp) , ("contact", B.unpack . contact $ cp) , ("listAsConsultantChecked", checkedStringIfTrue $ consultant cp ) , ("profile",showPr) ] return $ tutlayoutU rglobs attrs "editconsultantprofile" viewEditJob :: UserName -> JobName -> RenderGlobals -> ServerPartT IO Response viewEditJob pBy jN rglobs = case mbUser rglobs of Nothing -> return $ tutlayoutU rglobs [("errormsg", "error: no user")] "errortemplate" Just currU -> if currU /= pBy then return $ tutlayoutU rglobs [("errormsg", "error: " ++ (B.unpack . unjobname $ jN) ++ " not posted by " ++ (B.unpack . unusername $ currU) )] "errortemplate" else do mbJ <- lookupJob pBy jN case mbJ of Nothing -> return $ tutlayoutU rglobs [ ( "errormsg", "error, bad job: " ++ (show (pBy,jN) ) ) ] "errortemplate" Just j -> do let attrs = [ ("jobname", quote . B.unpack . unjobname $ jN) , ("budget", quote . B.unpack . jobbudget $ j) , ("jobblurb", quote . B.unpack . jobblurb $ j) , ("showJob",paintjob rglobs pBy (jN,j) ) ] return $ tutlayoutU rglobs attrs "editjob" lookupJob :: (MonadIO m) => UserName -> JobName -> m (Maybe Job) lookupJob pBy jN = do mbUis <- ( query . GetUserInfos ) pBy case mbUis of Nothing -> return Nothing Just uis -> return $ M.lookup jN (unjobs . jobs $ uis) pageMyJobPosts :: RenderGlobals -> ServerPartT IO Response pageMyJobPosts rglobs = do mbUis <- getGlobsUserInfos rglobs case mbUis of Left err -> return . tutlayoutU rglobs [("errormsg", err)] $ "errortemplate" Right (currU,uis) -> do let jobPostsTable = paintUserJobsTable (unusername currU) (M.toList . unjobs . jobs $ uis) return $ tutlayoutU rglobs [("jobPostsTable",jobPostsTable)] "myjobposts" getGlobsUserInfos :: Monad m => RenderGlobals -> ServerPartT IO (m ( UserName,UserInfos) ) getGlobsUserInfos rglobs = case (fmap sesUser $ mbSession rglobs) of Nothing -> fail "getUserInfos, no user in globals" Just un -> do mbUis <- query $ GetUserInfos un case mbUis of Nothing -> return $ fail "getUserInfos, no user infos" Just uis -> return $ return (un,uis) viewJob :: (MonadIO m) => RenderGlobals -> ServerPartT m Response viewJob rglobs = do JobLookup pBy jN <- getData' mbJ <- lookupJob pBy jN case mbJ of Nothing -> return $ tutlayoutU rglobs [("errmsg", "no job found")] "errortemplate" Just j -> return $ tutlayoutU rglobs [("job",paintjob rglobs pBy (jN,j) )] "viewjob" userProfile :: (MonadIO m) => RenderGlobals -> ServerPartT m Response userProfile rglobs = do UserNameUrlString user <- getData' mbCP <- do mbUis <- query (GetUserInfos user) return $ fmap userprofile mbUis case mbCP of Nothing -> return $ tutlayoutU rglobs [("errormsgProfile", "bad user: " ++ (B.unpack . unusername $ user) )] "viewconsultantprofile" Just cp -> do userimg <- liftIO $ avatarimage user return $ tutlayoutU rglobs [("cp", paintProfile rglobs (B.unpack . unusername $ user) cp userimg)] "viewconsultantprofile" viewEditJobWD :: RenderGlobals -> ServerPartT IO Response viewEditJobWD rglobs = withData $ \(JobLookup pBy jN) -> viewEditJob pBy jN rglobs deleteJobWD :: RenderGlobals -> ServerPartT IO Response deleteJobWD rglobs = withData $ \(JobLookup pBy jN) -> deleteJob pBy jN rglobs -- there's a lot of repeated code for viewEdit and Delete of jobs. -- maybe can consolidate deleteJob :: UserName -> JobName -> RenderGlobals -> ServerPartT IO Response deleteJob pBy jN rglobs = case mbUser rglobs of Nothing -> return $ tutlayoutU rglobs [("errormsg", "error: no user")] "errortemplate" Just currU -> if currU /= pBy then return $ tutlayoutU rglobs [("errormsg", "error: " ++ (B.unpack . unjobname $ jN) ++ " not posted by " ++ (B.unpack . unusername $ currU) )] "errortemplate" else do update $ DelJob currU jN pageMyJobPosts rglobs