module Routes.User
( getUserR
, getCreateRepoR
, postCreateRepoR
) where
import ClassyPrelude hiding (Handler)
import qualified Git
import qualified Yesod
import qualified Yesod.Auth as Auth
import Database (Repository (..), Unique (UniqueUsername), User (User, userUsername))
import Database.Persist (entityKey, entityVal, insert_, selectList, (==.))
import Database.Persist.Class.PersistUnique (getByValueUniques)
import HagiaSite (HagiaSite (..), Handler, Route (CreateRepoR, RepoR), Widget, repoPath)
import Path (PathSegment, pathSegmentFromDbString, toText)
import Yesod (FormResult, MForm, getYesod, runDB)
import Yesod.Auth (maybeAuthId)
import Yesod.Core (Html, whamlet)
getUserR :: PathSegment -> Handler Html
getUserR userName = do
user <-
runDB (getByValueUniques [UniqueUsername $ toText userName]) >>= \case
Nothing -> Yesod.notFound
Just x -> pure $ entityKey x
repos <- map entityVal <$> runDB (selectList [#user ==. user] [])
authId <- maybeAuthId
let visibleRepos =
if authId == Just user
then repos
else filter (not . repositoryPrivate) repos
Yesod.defaultLayout $ do
Yesod.setTitle $ Yesod.toHtml userName
[whamlet|
<div .content .row-g5 style="margin-top: 5px">
<!-- User personality -->
<div .column-g5 style="width: 25%; align-items: start">
<div style="font-size: 40px">
#{userName}
$if isJust authId
<a .seamless-a href=@{CreateRepoR}> Create repository
<!-- Repos -->
<div .column-g5 style="width: 65%; margin-left: auto; align-items: start; font-size: 20px">
$forall repo <- visibleRepos
$with name <- pathSegmentFromDbString $ repositoryName repo
<a href=@{RepoR userName name}>
#{userName} / #{name}
|]
data CreateRepoForm = CreateRepoForm
{ repoName :: !Text
, repoSummary :: !(Maybe Text)
, private :: !Bool
}
deriving (Eq, Show)
createRepoForm :: Html -> MForm Handler (FormResult CreateRepoForm, Widget)
createRepoForm =
Yesod.renderDivs $
CreateRepoForm
<$> Yesod.areq Yesod.textField "New repo name" Nothing
<*> Yesod.aopt Yesod.textField "Short description (optional)" Nothing
<*> Yesod.areq Yesod.checkBoxField "Private" (Just False)
getCreateRepoR :: Handler Html
getCreateRepoR = do
(widget, enctype) <- Yesod.generateFormPost createRepoForm
Yesod.defaultLayout $ do
Yesod.setTitle "Create repository"
[whamlet|
<h1> Create repo
<form method=post action=@{CreateRepoR} enctype=#{enctype}>
^{widget}
<button> Create
|]
postCreateRepoR :: Handler Html
postCreateRepoR = do
userId <- Auth.requireAuthId
User{userUsername} <-
runDB $
Yesod.get userId >>= \case
Nothing -> error "XXX Authorized user doesn't exist"
Just x -> pure x
((result, widget), enctype) <- Yesod.runFormPost createRepoForm
case result of
Yesod.FormSuccess CreateRepoForm{repoName, repoSummary, private} -> do
let username = pathSegmentFromDbString userUsername
let reponame = pathSegmentFromDbString repoName
projectRoot <- repoPath username reponame
-- TODO: create directory for user? Maybe this is done when creating users
HagiaSite{git} <- getYesod
liftIO $ Git.createRepo git projectRoot
runDB $
insert_
Repository
{ repositoryName = repoName
, repositorySummary = repoSummary
, repositoryUser = userId
, repositoryPrivate = private
}
Yesod.redirect $ RepoR username reponame
_ ->
Yesod.defaultLayout $ do
Yesod.setTitle "Create repository"
[whamlet|
<h1> Create repo
Something went wrong, try again with different values
<form method=post action=@{CreateRepoR} enctype=#{enctype}>
^{widget}
<button> Create
|]