Compare commits
3 Commits
1c19d97dc8
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 92c9fae885 | |||
| 47a2eff484 | |||
| 9d0246cbcf |
@@ -12,5 +12,6 @@ __pycache__
|
|||||||
.superpowers/
|
.superpowers/
|
||||||
node_modules/
|
node_modules/
|
||||||
frontend/dist/
|
frontend/dist/
|
||||||
|
test-results/
|
||||||
hyperbole-local/
|
hyperbole-local/
|
||||||
hyperbole-local/
|
hyperbole-local/
|
||||||
|
|||||||
+12
-1
@@ -1,6 +1,7 @@
|
|||||||
{-# LANGUAGE FlexibleContexts #-}
|
{-# LANGUAGE FlexibleContexts #-}
|
||||||
{-# LANGUAGE OverloadedStrings #-}
|
{-# LANGUAGE OverloadedStrings #-}
|
||||||
{-# LANGUAGE ScopedTypeVariables #-}
|
{-# LANGUAGE ScopedTypeVariables #-}
|
||||||
|
{-# LANGUAGE TypeApplications #-}
|
||||||
{-# LANGUAGE TypeOperators #-}
|
{-# LANGUAGE TypeOperators #-}
|
||||||
{-# OPTIONS_GHC -Wno-unused-imports -Wno-missing-export-lists -Wno-name-shadowing #-}
|
{-# 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.FilePath (takeDirectory)
|
||||||
import System.IO.Error (isDoesNotExistError)
|
import System.IO.Error (isDoesNotExistError)
|
||||||
|
|
||||||
|
import Sis (UserId (..))
|
||||||
import Sis.Database
|
import Sis.Database
|
||||||
import Sis.Page.Activity
|
import Sis.Page.Activity
|
||||||
import Sis.Page.Chores
|
import Sis.Page.Chores
|
||||||
@@ -28,7 +30,7 @@ import Sis.Page.Household
|
|||||||
import Sis.Page.Login
|
import Sis.Page.Login
|
||||||
import Sis.Page.Signup
|
import Sis.Page.Signup
|
||||||
import Sis.Route
|
import Sis.Route
|
||||||
import Sis.View.Layout (documentHead)
|
import Sis.View.Layout (UserSession (..), documentHead)
|
||||||
import Web.Hyperbole
|
import Web.Hyperbole
|
||||||
import Web.Hyperbole.Application
|
import Web.Hyperbole.Application
|
||||||
import Web.Hyperbole.Effect.Response
|
import Web.Hyperbole.Effect.Response
|
||||||
@@ -108,6 +110,15 @@ router RDashboard = runPage Sis.Page.Dashboard.page
|
|||||||
router RChores = runPage Sis.Page.Chores.page
|
router RChores = runPage Sis.Page.Chores.page
|
||||||
router RHousehold = runPage Sis.Page.Household.page
|
router RHousehold = runPage Sis.Page.Household.page
|
||||||
router RActivity = runPage Sis.Page.Activity.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
|
router RSeed = do
|
||||||
seed
|
seed
|
||||||
redirect (routeUri RDashboard)
|
redirect (routeUri RDashboard)
|
||||||
|
|||||||
+4
-6
@@ -80,7 +80,7 @@ data DB :: Effect where
|
|||||||
CreateInvite :: Int -> Maybe Text -> DB m Invite
|
CreateInvite :: Int -> Maybe Text -> DB m Invite
|
||||||
GetInvites :: Int -> DB m [Invite]
|
GetInvites :: Int -> DB m [Invite]
|
||||||
RevokeInvite :: Int -> DB m ()
|
RevokeInvite :: Int -> DB m ()
|
||||||
AcceptInvite :: UserId -> Text -> DB m Household
|
AcceptInvite :: UserId -> Text -> DB m (Maybe Household)
|
||||||
Seed :: DB m ()
|
Seed :: DB m ()
|
||||||
|
|
||||||
type instance DispatchOf DB = 'Dynamic
|
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 = ?"
|
\ FROM households h JOIN memberships m ON m.household_id = h.id AND m.role = 'owner' WHERE h.id = ?"
|
||||||
(Only hid) ::
|
(Only hid) ::
|
||||||
IO [(Int, Text, Int, Int)]
|
IO [(Int, Text, Int, Int)]
|
||||||
case listToMaybe [Household (HouseholdId hId) hName (UserId ownerId) count | (hId, hName, ownerId, count) <- hResult] of
|
pure $ listToMaybe [Household (HouseholdId hId) hName (UserId ownerId) count | (hId, hName, ownerId, count) <- hResult]
|
||||||
Just h -> pure h
|
_ -> pure Nothing
|
||||||
Nothing -> error "Household not found after accept"
|
|
||||||
_ -> error "Invite not found"
|
|
||||||
Seed -> liftIO $ do
|
Seed -> liftIO $ do
|
||||||
let demoPassword = "password123"
|
let demoPassword = "password123"
|
||||||
pwHash <- hashPasswordIO demoPassword
|
pwHash <- hashPasswordIO demoPassword
|
||||||
@@ -524,7 +522,7 @@ getInvites = send . GetInvites
|
|||||||
revokeInvite :: (DB :> es) => Int -> Eff es ()
|
revokeInvite :: (DB :> es) => Int -> Eff es ()
|
||||||
revokeInvite = send . RevokeInvite
|
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
|
acceptInvite u = send . AcceptInvite u
|
||||||
|
|
||||||
seed :: (DB :> es) => Eff es ()
|
seed :: (DB :> es) => Eff es ()
|
||||||
|
|||||||
@@ -49,8 +49,12 @@ instance (DB :> es, IOE :> es) => HyperView DashboardPage es where
|
|||||||
(h : _) -> do
|
(h : _) -> do
|
||||||
dash <- getDashboard (unHouseholdId (householdId h)) today
|
dash <- getDashboard (unHouseholdId (householdId h)) today
|
||||||
pure $ hyper DashboardPage $ pageLayout us $ dashboardView dash
|
pure $ hyper DashboardPage $ pageLayout us $ dashboardView dash
|
||||||
update (CheckOff _oid) = do
|
update (CheckOff oid) = do
|
||||||
-- TODO: wire up to activity form
|
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
|
update RefreshDashboard
|
||||||
|
|
||||||
dashboardView :: Dashboard -> View DashboardPage ()
|
dashboardView :: Dashboard -> View DashboardPage ()
|
||||||
|
|||||||
@@ -121,7 +121,8 @@ memberRow m = do
|
|||||||
inviteRow :: Invite -> View HouseholdPage ()
|
inviteRow :: Invite -> View HouseholdPage ()
|
||||||
inviteRow i = do
|
inviteRow i = do
|
||||||
el @ att "class" nbListItemClass @ att "style" "display:flex;justify-content:space-between;padding:0.5rem" $ 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)" $
|
button (RevokeInviteAction (inviteId i)) @ att "class" nbButtonDefaultClass @ att "style" "font-size:0.8rem;background:var(--nb-red)" $
|
||||||
text "Revoke"
|
text "Revoke"
|
||||||
|
|
||||||
|
|||||||
+20
-1
@@ -1,10 +1,28 @@
|
|||||||
{-# LANGUAGE DeriveGeneric #-}
|
{-# LANGUAGE DeriveGeneric #-}
|
||||||
|
|
||||||
module Sis.Route (AppRoute (..)) where
|
module Sis.Route (AppRoute (..), InviteCode (..)) where
|
||||||
|
|
||||||
|
import Data.Text (Text)
|
||||||
import GHC.Generics (Generic)
|
import GHC.Generics (Generic)
|
||||||
import Web.Hyperbole.Route
|
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
|
data AppRoute
|
||||||
= Home
|
= Home
|
||||||
| RLogin
|
| RLogin
|
||||||
@@ -13,6 +31,7 @@ data AppRoute
|
|||||||
| RChores
|
| RChores
|
||||||
| RHousehold
|
| RHousehold
|
||||||
| RActivity
|
| RActivity
|
||||||
|
| RInvite InviteCode
|
||||||
| RSeed
|
| RSeed
|
||||||
deriving stock (Eq, Generic, Show)
|
deriving stock (Eq, Generic, Show)
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -78,7 +78,7 @@ newtype ChoreId = ChoreId {unChoreId :: Int}
|
|||||||
newtype OccurrenceId = OccurrenceId {unOccurrenceId :: Int}
|
newtype OccurrenceId = OccurrenceId {unOccurrenceId :: Int}
|
||||||
deriving newtype (Show, Eq, Read, ToJSON, FromJSON)
|
deriving newtype (Show, Eq, Read, ToJSON, FromJSON)
|
||||||
|
|
||||||
newtype ActivityId = ActivityId {unActivityId :: Int}
|
newtype ActivityId = ActivityId Int
|
||||||
deriving newtype (Show, Eq, Read, ToJSON, FromJSON)
|
deriving newtype (Show, Eq, Read, ToJSON, FromJSON)
|
||||||
|
|
||||||
newtype InviteId = InviteId {unInviteId :: Int}
|
newtype InviteId = InviteId {unInviteId :: Int}
|
||||||
|
|||||||
Reference in New Issue
Block a user