Compare commits

..

3 Commits

7 changed files with 47 additions and 13 deletions
+1
View File
@@ -12,5 +12,6 @@ __pycache__
.superpowers/
node_modules/
frontend/dist/
test-results/
hyperbole-local/
hyperbole-local/
+12 -1
View File
@@ -1,6 +1,7 @@
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}
{-# LANGUAGE TypeOperators #-}
{-# OPTIONS_GHC -Wno-unused-imports -Wno-missing-export-lists -Wno-name-shadowing #-}
@@ -20,6 +21,7 @@ import System.Environment (getArgs, lookupEnv)
import System.FilePath (takeDirectory)
import System.IO.Error (isDoesNotExistError)
import Sis (UserId (..))
import Sis.Database
import Sis.Page.Activity
import Sis.Page.Chores
@@ -28,7 +30,7 @@ import Sis.Page.Household
import Sis.Page.Login
import Sis.Page.Signup
import Sis.Route
import Sis.View.Layout (documentHead)
import Sis.View.Layout (UserSession (..), documentHead)
import Web.Hyperbole
import Web.Hyperbole.Application
import Web.Hyperbole.Effect.Response
@@ -108,6 +110,15 @@ router RDashboard = runPage Sis.Page.Dashboard.page
router RChores = runPage Sis.Page.Chores.page
router RHousehold = runPage Sis.Page.Household.page
router RActivity = runPage Sis.Page.Activity.page
router (RInvite code) = do
mSession <- lookupSession @UserSession
case mSession of
Nothing -> redirect (routeUri RLogin)
Just us -> do
mHousehold <- acceptInvite (UserId (usUserId us)) (unInviteCode code)
case mHousehold of
Just _ -> redirect (routeUri RDashboard)
Nothing -> redirect (routeUri RHousehold)
router RSeed = do
seed
redirect (routeUri RDashboard)
+4 -6
View File
@@ -80,7 +80,7 @@ data DB :: Effect where
CreateInvite :: Int -> Maybe Text -> DB m Invite
GetInvites :: Int -> DB m [Invite]
RevokeInvite :: Int -> DB m ()
AcceptInvite :: UserId -> Text -> DB m Household
AcceptInvite :: UserId -> Text -> DB m (Maybe Household)
Seed :: DB m ()
type instance DispatchOf DB = 'Dynamic
@@ -324,10 +324,8 @@ runDB conn = interpret $ \_ -> \case
\ FROM households h JOIN memberships m ON m.household_id = h.id AND m.role = 'owner' WHERE h.id = ?"
(Only hid) ::
IO [(Int, Text, Int, Int)]
case listToMaybe [Household (HouseholdId hId) hName (UserId ownerId) count | (hId, hName, ownerId, count) <- hResult] of
Just h -> pure h
Nothing -> error "Household not found after accept"
_ -> error "Invite not found"
pure $ listToMaybe [Household (HouseholdId hId) hName (UserId ownerId) count | (hId, hName, ownerId, count) <- hResult]
_ -> pure Nothing
Seed -> liftIO $ do
let demoPassword = "password123"
pwHash <- hashPasswordIO demoPassword
@@ -524,7 +522,7 @@ getInvites = send . GetInvites
revokeInvite :: (DB :> es) => Int -> Eff es ()
revokeInvite = send . RevokeInvite
acceptInvite :: (DB :> es) => UserId -> Text -> Eff es Household
acceptInvite :: (DB :> es) => UserId -> Text -> Eff es (Maybe Household)
acceptInvite u = send . AcceptInvite u
seed :: (DB :> es) => Eff es ()
+7 -3
View File
@@ -49,9 +49,13 @@ instance (DB :> es, IOE :> es) => HyperView DashboardPage es where
(h : _) -> do
dash <- getDashboard (unHouseholdId (householdId h)) today
pure $ hyper DashboardPage $ pageLayout us $ dashboardView dash
update (CheckOff _oid) = do
-- TODO: wire up to activity form
update RefreshDashboard
update (CheckOff oid) = do
mUser <- lookupSession @UserSession
case mUser of
Nothing -> pure (el "Not authenticated")
Just us -> do
_ <- recordActivity (unOccurrenceId oid) (UserId (usUserId us)) ActivityCompleted Nothing False
update RefreshDashboard
dashboardView :: Dashboard -> View DashboardPage ()
dashboardView dash = do
+2 -1
View File
@@ -121,7 +121,8 @@ memberRow m = do
inviteRow :: Invite -> View HouseholdPage ()
inviteRow i = do
el @ att "class" nbListItemClass @ att "style" "display:flex;justify-content:space-between;padding:0.5rem" $ do
el @ att "style" "font-size:0.85rem" $ text ("/invite/" <> inviteCode i)
route (RInvite (InviteCode (inviteCode i))) @ att "class" nbButtonDefaultClass @ att "style" "font-size:0.85rem;text-decoration:none" $
text (inviteCode i)
button (RevokeInviteAction (inviteId i)) @ att "class" nbButtonDefaultClass @ att "style" "font-size:0.8rem;background:var(--nb-red)" $
text "Revoke"
+20 -1
View File
@@ -1,10 +1,28 @@
{-# LANGUAGE DeriveGeneric #-}
module Sis.Route (AppRoute (..)) where
module Sis.Route (AppRoute (..), InviteCode (..)) where
import Data.Text (Text)
import GHC.Generics (Generic)
import Web.Hyperbole.Route
----------------------------------------------------------------------
-- Invite Code
----------------------------------------------------------------------
newtype InviteCode = InviteCode {unInviteCode :: Text}
deriving stock (Show, Eq)
instance Route InviteCode where
matchRoute (Path [t]) = Just (InviteCode t)
matchRoute _ = Nothing
routePath (InviteCode c) = Path [c]
baseRoute = Nothing
----------------------------------------------------------------------
-- App Routes
----------------------------------------------------------------------
data AppRoute
= Home
| RLogin
@@ -13,6 +31,7 @@ data AppRoute
| RChores
| RHousehold
| RActivity
| RInvite InviteCode
| RSeed
deriving stock (Eq, Generic, Show)
+1 -1
View File
@@ -78,7 +78,7 @@ newtype ChoreId = ChoreId {unChoreId :: Int}
newtype OccurrenceId = OccurrenceId {unOccurrenceId :: Int}
deriving newtype (Show, Eq, Read, ToJSON, FromJSON)
newtype ActivityId = ActivityId {unActivityId :: Int}
newtype ActivityId = ActivityId Int
deriving newtype (Show, Eq, Read, ToJSON, FromJSON)
newtype InviteId = InviteId {unInviteId :: Int}