moved hamlet to widgetfiles

This commit is contained in:
Stuce 2025-07-02 17:37:55 +01:00
parent c63309b9e8
commit de60936cd2
11 changed files with 80 additions and 82 deletions

View file

@ -1,12 +1,15 @@
# sTodo # sTodo
Stuce's simple todo is a web app that let's you self host a simple todolist. Stuce's simple todo is a web app that let's you self host a simple todolist.
The goal is to provide a minimalistic and fast todo list that is self hostable. The goal is to provide a minimalistic and fast todo list that is self hostable.
## Usage
- can be used as is for a single user behind a vpn (for ex, wireguard)
- can be setup for multi user with a reverse proxy and an authentification provider that supports trusted sso (for ex, nginx + authelia)
## Next goals ## Next goals
- Make multi user support - Make multi user support
- [ ] write a minimal step by step guide to install with nix, - [ ] write a minimal step by step guide to install with nix,
- [ ] add some css to make it look nicer - [ ] add some css to make it look nicer
- [ ] add htmx to make more agreable without making js manadatory - [ ] add htmx to make more agreable without making js manadatory
- [ ] make api to allow usage with native app - [ ] make api to allow usage with native app (a way to get every list that has been modified since date $date belonging from the user in a json or similar format)
## Version 0.0.3 ## Version 0.0.3
Simple todo list webapp. Simple todo list webapp.
Features : Features :

View file

@ -75,12 +75,12 @@ instance Yesod App where
Nothing -> getApprootText guessApproot app req Nothing -> getApprootText guessApproot app req
Just root -> root Just root -> root
-- Store session data on the client in encrypted cookies, -- -- Store session data on the client in encrypted cookies,
-- default session idle timeout is 120 minutes -- -- default session idle timeout is 120 minutes
makeSessionBackend :: App -> IO (Maybe SessionBackend) -- makeSessionBackend :: App -> IO (Maybe SessionBackend)
makeSessionBackend app = Just <$> defaultClientSessionBackend -- makeSessionBackend app = Just <$> defaultClientSessionBackend
120 -- timeout in minutes -- 120 -- timeout in minutes
(appSessionKey $ appSettings app) -- (appSessionKey $ appSettings app)
-- Yesod Middleware allows you to run code before and after each handler function. -- Yesod Middleware allows you to run code before and after each handler function.
-- The defaultYesodMiddleware adds the response header "Vary: Accept, Accept-Language" and performs authorization checks. -- The defaultYesodMiddleware adds the response header "Vary: Accept, Accept-Language" and performs authorization checks.
@ -97,7 +97,7 @@ instance Yesod App where
master <- getYesod master <- getYesod
mmsg <- getMessage mmsg <- getMessage
mcurrentRoute <- getCurrentRoute -- mcurrentRoute <- getCurrentRoute
-- We break up the default layout into two components: -- We break up the default layout into two components:
-- default-layout is the contents of the body tag, and -- default-layout is the contents of the body tag, and
@ -190,7 +190,7 @@ unsafeHandler = Unsafe.fakeHandlerGetLogger appLogger
-- https://github.com/yesodweb/yesod/wiki/i18n-messages-in-the-scaffolding -- https://github.com/yesodweb/yesod/wiki/i18n-messages-in-the-scaffolding
-- TODO: complete implementation should short circuit if multi user is on but no user exist -- TODO: complete implementation should short circuit if multi user is on but no user exist, to enforce policy safely
getUserId :: HandlerFor App (Key User) getUserId :: HandlerFor App (Key User)
getUserId = do getUserId = do
mName <- lookupHeader "Remote-User" mName <- lookupHeader "Remote-User"

View file

@ -18,18 +18,7 @@ getGroupR = do
groups <- getGroups userId groups <- getGroups userId
defaultLayout $ do defaultLayout $ do
setTitle "Groups" setTitle "Groups"
[whamlet| $(widgetFile "group")
<a href=@{GroupR}>Home
<ul>
$forall group <- groups
<li>
<a href=@{TodolistR $ entityKey group}>#{(groupGroup . entityVal) group}
<form action=@{AddGroupR} method="post">
<input type="text" name="group" placeholder="new group">
<button type="submit">add
<a href=@{EditGroupR}>Edit
|]
postAddGroupR :: Handler Html postAddGroupR :: Handler Html
postAddGroupR = do postAddGroupR = do
g <- runInputPost $ ireq textField "group" g <- runInputPost $ ireq textField "group"
@ -48,16 +37,7 @@ getEditGroupR = do
defaultLayout $ do defaultLayout $ do
let a e = pack $ show $ fromSqlKey $ entityKey e ::Text let a e = pack $ show $ fromSqlKey $ entityKey e ::Text
setTitle "Groups" setTitle "Groups"
[whamlet| $(widgetFile "edit-group")
<form action=@{DeleteGroupR} method="POST">
<ul>
$forall group <- groups
<li>
<input type="checkbox" name="ids" value="#{a group}">
<a href="">#{(groupGroup . entityVal) group}
<button type=submit>Delete selected
<a href=@{GroupR}>Back
|]
postEditGroupR :: Handler Html postEditGroupR :: Handler Html
postEditGroupR = do postEditGroupR = do
-- TODO: not implemented yet -- TODO: not implemented yet

View file

@ -26,20 +26,7 @@ getTodolistR groupId = do
defaultLayout $ do defaultLayout $ do
let getTitle = todolistTitle . entityVal let getTitle = todolistTitle . entityVal
setTitle "todolist" setTitle "todolist"
[whamlet| $(widgetFile "todolist")
<a href=@{GroupR}>Home
<ul>
$forall list <- lists
<li>
<a href=@{TodolistItemsR groupId (entityKey list)}>#{getTitle list}
<form action=@{AddTodolistR groupId} method="post">
<input type="text" name="list" placeholder="new list">
<button type="submit">add
<form action=@{AddUserR groupId} method="post">
<input type="text" name="user" placeholder="new user">
<button type="submit">share
<a href=@{EditTodolistR groupId}>Edit
|]
getEditTodolistR :: GroupId -> Handler Html getEditTodolistR :: GroupId -> Handler Html
getEditTodolistR groupId = do getEditTodolistR groupId = do
@ -48,16 +35,8 @@ getEditTodolistR groupId = do
defaultLayout $ do defaultLayout $ do
let keyToText e = pack $ show $ fromSqlKey $ entityKey e ::Text let keyToText e = pack $ show $ fromSqlKey $ entityKey e ::Text
setTitle "Groups" setTitle "Groups"
[whamlet| $(widgetFile "edit-todolist")
<form action=@{DeleteTodolistR groupId} method="POST">
<ul>
$forall list <- lists
<li>
<input type="checkbox" name="ids" value="#{keyToText list}">
<a href="">#{(todolistTitle . entityVal) list}
<button type=submit>Delete selected
<a href=@{TodolistR groupId}>Back
|]
postDeleteTodolistR :: GroupId -> Handler Html postDeleteTodolistR :: GroupId -> Handler Html
postDeleteTodolistR groupId = do postDeleteTodolistR groupId = do
text <- lookupPostParams "ids" text <- lookupPostParams "ids"

View file

@ -21,25 +21,7 @@ getTodolistItemsR groupId todolistId = do
defaultLayout $ do defaultLayout $ do
setTitle "items" setTitle "items"
[whamlet| $(widgetFile "todolist-items")
<a href=@{GroupR}>Home
&nbsp;
<a href=@{TodolistR groupId}>Lists
<ul>
$forall item <- items
<li>
<form action=@{CheckTodolistItemR groupId todolistId (entityKey item)} method="POST">
<button type="submit">#{getText item}
<form action=@{AddTodolistItemR groupId todolistId} method="post">
<form action=@{AddTodolistItemR groupId todolistId} method="post">
<input type="text" name="item" placeholder="new item">
<button type="submit">add
<form action=@{TrimTodolistItemsR groupId todolistId} method="post">
<button type="submit">trim
<form action=@{SortTodolistItemsR groupId todolistId} method="post">
<button type="submit">sort
<a href=@{EditTodolistItemsR groupId todolistId}>Edit
|]
postCheckTodolistItemR :: GroupId -> TodolistId -> TodolistItemId -> Handler Html postCheckTodolistItemR :: GroupId -> TodolistId -> TodolistItemId -> Handler Html
@ -60,14 +42,8 @@ getEditTodolistItemsR groupId todolistId = do
let text = unlines $ map getText items let text = unlines $ map getText items
defaultLayout $ do defaultLayout $ do
setTitle "edit" setTitle "edit"
[whamlet| $(widgetFile "edit-todolist-items")
<form action=@{EditTodolistItemsR groupId todolistId} method=POST>
<label for="edit text area">Edit todolist
<br>
<textarea id="edit text area" name=text rows=30 cols=50 placeholder="[x] wake up1&#10;[x] eat&#10;[ ] sleep&#10;[ ] repeat">#{text}
<br>
<button type="submit">edit
|]
postEditTodolistItemsR :: GroupId -> TodolistId -> Handler Html postEditTodolistItemsR :: GroupId -> TodolistId -> Handler Html
postEditTodolistItemsR groupId todolistId = do postEditTodolistItemsR groupId todolistId = do
mText <- runInputPost $ iopt textField "text" mText <- runInputPost $ iopt textField "text"

View file

@ -0,0 +1,8 @@
<form action=@{DeleteGroupR} method="POST">
<ul>
$forall group <- groups
<li>
<input type="checkbox" name="ids" value="#{a group}">
<a href="">#{(groupGroup . entityVal) group}
<button type=submit>Delete selected
<a href=@{GroupR}>Back

View file

@ -0,0 +1,6 @@
<form action=@{EditTodolistItemsR groupId todolistId} method=POST>
<label for="edit text area">Edit todolist
<br>
<textarea id="edit text area" name=text rows=30 cols=50 placeholder="[x] wake up1&#10;[x] eat&#10;[ ] sleep&#10;[ ] repeat">#{text}
<br>
<button type="submit">edit

View file

@ -0,0 +1,8 @@
<form action=@{DeleteTodolistR groupId} method="POST">
<ul>
$forall list <- lists
<li>
<input type="checkbox" name="ids" value="#{keyToText list}">
<a href="">#{(todolistTitle . entityVal) list}
<button type=submit>Delete selected
<a href=@{TodolistR groupId}>Back

9
templates/group.hamlet Normal file
View file

@ -0,0 +1,9 @@
<a href=@{GroupR}>Home
<ul>
$forall group <- groups
<li>
<a href=@{TodolistR $ entityKey group}>#{(groupGroup . entityVal) group}
<form action=@{AddGroupR} method="post">
<input type="text" name="group" placeholder="new group">
<button type="submit">add
<a href=@{EditGroupR}>Edit

View file

@ -0,0 +1,17 @@
<a href=@{GroupR}>Home
&nbsp;
<a href=@{TodolistR groupId}>Lists
<ul>
$forall item <- items
<li>
<form action=@{CheckTodolistItemR groupId todolistId (entityKey item)} method="POST">
<button type="submit">#{getText item}
<form action=@{AddTodolistItemR groupId todolistId} method="post">
<form action=@{AddTodolistItemR groupId todolistId} method="post">
<input type="text" name="item" placeholder="new item">
<button type="submit">add
<form action=@{TrimTodolistItemsR groupId todolistId} method="post">
<button type="submit">trim
<form action=@{SortTodolistItemsR groupId todolistId} method="post">
<button type="submit">sort
<a href=@{EditTodolistItemsR groupId todolistId}>Edit

12
templates/todolist.hamlet Normal file
View file

@ -0,0 +1,12 @@
<a href=@{GroupR}>Home
<ul>
$forall list <- lists
<li>
<a href=@{TodolistItemsR groupId (entityKey list)}>#{getTitle list}
<form action=@{AddTodolistR groupId} method="post">
<input type="text" name="list" placeholder="new list">
<button type="submit">add
<form action=@{AddUserR groupId} method="post">
<input type="text" name="user" placeholder="new user">
<button type="submit">share
<a href=@{EditTodolistR groupId}>Edit