Compare commits
10 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
8e8259ab42
|
|||
|
58f9080137
|
|||
|
c004bb6bdd
|
|||
|
cd07c1fce7
|
|||
|
8acc8bc44e
|
|||
| a2a5c55d80 | |||
|
71048409dc
|
|||
|
edf9244382
|
|||
|
4f596d0d07
|
|||
|
30a5f72a35
|
@@ -1,2 +1,38 @@
|
|||||||
# todo-php
|
# To-Do List PHP
|
||||||
A PHP app that offers todo notes. Not safe, not recommended, but it exists.
|
|
||||||
|
A to-do list app that uses **unencrypted** files to store data. Not safe for anything else than self-hosted personal use.
|
||||||
|
It requires no external libraries and can run off of PHP's built-in server if needed.
|
||||||
|
|
||||||
|
Pull requests are welcome.
|
||||||
|
|
||||||
|
## Description
|
||||||
|
|
||||||
|
This is a to-do list that supports deadlines.
|
||||||
|
It is a great way of organizing your thoughts and plans.
|
||||||
|
The dates are "translated" to plain English,
|
||||||
|
which means that the deadlines are written in relative names like Tomorrow, Yesterday, Next Tuesday, etc.
|
||||||
|
This is not a scrum board like approach, more like a simplified calendar.
|
||||||
|
A calendar that has no other function than to store your upcoming events and reminders.
|
||||||
|
Unlike other calendars, all features are removed that would obscure the at-a-glance overview aspect of all notes.
|
||||||
|
It is not meant for archiving or very long term (or recurring) events, but for planning the week.
|
||||||
|
|
||||||
|
While it is not secure enough to use it in public, it could be used by multiple people simultaneously.
|
||||||
|
The app fully supports user separation. Each user can have unlimited backups of their lists that can be easily restored.
|
||||||
|
|
||||||
|
As a possible daily-driver to-do app that could serve as your home page,
|
||||||
|
it features categorization so that certain events can be viewed as distinct notes and will never get mixed up.
|
||||||
|
|
||||||
|
Editing notes is possible, but just like the "snooze" button on alarms, there are quick-access buttons for delaying reminders by a day or a week.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Users
|
||||||
|
- Backups
|
||||||
|
- Categorization
|
||||||
|
- Note editing
|
||||||
|
- Quick delaying without manually editing
|
||||||
|
- Friendly dates (Tomorrow, Yesterday, Next Tuesday, etc.)
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
- PHP 7.4.10 or higher
|
||||||
|
|||||||
@@ -256,7 +256,7 @@ else if (!empty($_POST["action"]))
|
|||||||
$modified = false;
|
$modified = false;
|
||||||
if ($action === "add" || $action == "edit")
|
if ($action === "add" || $action == "edit")
|
||||||
{
|
{
|
||||||
if (!empty($_POST["todo_item_id"]))
|
if (isset($_POST["todo_item_id"]))
|
||||||
{
|
{
|
||||||
$id_to_edit = $_POST["todo_item_id"];
|
$id_to_edit = $_POST["todo_item_id"];
|
||||||
}
|
}
|
||||||
@@ -285,6 +285,12 @@ else if (!empty($_POST["action"]))
|
|||||||
}
|
}
|
||||||
|
|
||||||
$now = time();
|
$now = time();
|
||||||
|
$created = $now;
|
||||||
|
|
||||||
|
if (isset($id_to_edit) && !empty($model["list"][$id_to_edit]) && !empty($model["list"][$id_to_edit]["created"]))
|
||||||
|
{
|
||||||
|
$created = $model["list"][$id_to_edit]["created"];
|
||||||
|
}
|
||||||
|
|
||||||
if (empty($model["list"]))
|
if (empty($model["list"]))
|
||||||
{
|
{
|
||||||
@@ -296,11 +302,11 @@ else if (!empty($_POST["action"]))
|
|||||||
"description" => $description,
|
"description" => $description,
|
||||||
"deadline" => $deadline,
|
"deadline" => $deadline,
|
||||||
"category" => $category,
|
"category" => $category,
|
||||||
"created" => $now,
|
"created" => $created,
|
||||||
"modified" => $now,
|
"modified" => $now,
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!empty($id_to_edit) && !empty($model["list"][$id_to_edit]))
|
if (isset($id_to_edit) && !empty($model["list"][$id_to_edit]))
|
||||||
{
|
{
|
||||||
$model["list"][$id_to_edit] = $new_item;
|
$model["list"][$id_to_edit] = $new_item;
|
||||||
}
|
}
|
||||||
@@ -346,6 +352,31 @@ else if (!empty($_POST["action"]))
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if ($action === "pin" && !empty($_POST["category_name"]))
|
||||||
|
{
|
||||||
|
if (empty($model["pinned"]))
|
||||||
|
{
|
||||||
|
$model["pinned"] = array();
|
||||||
|
}
|
||||||
|
|
||||||
|
$category_name = $_POST["category_name"];
|
||||||
|
if (in_array($category_name, $model["pinned"]))
|
||||||
|
{
|
||||||
|
foreach ($model["pinned"] as $pin_key => $pin_name)
|
||||||
|
{
|
||||||
|
if ($pin_name == $category_name)
|
||||||
|
{
|
||||||
|
unset($model["pinned"][$pin_key]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$model["pinned"][] = $category_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
$modified = true;
|
||||||
|
}
|
||||||
|
|
||||||
if ($modified)
|
if ($modified)
|
||||||
{
|
{
|
||||||
@@ -373,6 +404,55 @@ else
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// functions used by renderers
|
||||||
|
function get_fancy_date($date) : string
|
||||||
|
{
|
||||||
|
$now = time();
|
||||||
|
$now_dayth = intval(date("z", $now));
|
||||||
|
|
||||||
|
$ymd = date("y-m-d", $date);
|
||||||
|
$day = date("l", $date);
|
||||||
|
$dayth = intval(date("z", $date));
|
||||||
|
|
||||||
|
$fancy_date = $ymd;
|
||||||
|
|
||||||
|
if ($dayth - $now_dayth == 0)
|
||||||
|
{
|
||||||
|
$fancy_date = "Today ({$day})";
|
||||||
|
}
|
||||||
|
else if ($dayth - $now_dayth == 1)
|
||||||
|
{
|
||||||
|
$fancy_date = "Tomorrow ({$day})";
|
||||||
|
}
|
||||||
|
else if ($dayth - $now_dayth == -1)
|
||||||
|
{
|
||||||
|
$fancy_date = "Yesterday ({$day})";
|
||||||
|
}
|
||||||
|
else if ($dayth - $now_dayth < -7)
|
||||||
|
{
|
||||||
|
$fancy_date = "{$day} ({$ymd})";
|
||||||
|
}
|
||||||
|
else if ($dayth - $now_dayth < 0)
|
||||||
|
{
|
||||||
|
$fancy_date = "Last " . $day;
|
||||||
|
}
|
||||||
|
else if ($dayth - $now_dayth < 7)
|
||||||
|
{
|
||||||
|
$fancy_date = $day;
|
||||||
|
}
|
||||||
|
else if ($dayth - $now_dayth < 14)
|
||||||
|
{
|
||||||
|
$fancy_date = "Next " . $day;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$fancy_date = "{$day} ({$ymd})";
|
||||||
|
}
|
||||||
|
|
||||||
|
return $fancy_date;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// renderers
|
// renderers
|
||||||
function todo_list(array $model = []) : string
|
function todo_list(array $model = []) : string
|
||||||
{
|
{
|
||||||
@@ -388,131 +468,217 @@ function todo_list(array $model = []) : string
|
|||||||
$te->append_block_template("CONTENT", "ADD_FORM");
|
$te->append_block_template("CONTENT", "ADD_FORM");
|
||||||
$te->append_block_template("CONTENT", "NAVBAR");
|
$te->append_block_template("CONTENT", "NAVBAR");
|
||||||
|
|
||||||
$categories = array();
|
$pinned_categories = array();
|
||||||
|
if (!empty($model["pinned"]))
|
||||||
|
{
|
||||||
|
$pinned_categories = array_merge($model["pinned"]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$default_category = "Uncategorized";
|
||||||
|
$default_category_id = "uncategorized";
|
||||||
|
|
||||||
|
$categories = array( $default_category_id => [] );
|
||||||
|
|
||||||
$now = time();
|
$now = time();
|
||||||
$now_dayth = intval(date("z", $now));
|
$now_dayth = intval(date("z", $now));
|
||||||
|
|
||||||
|
$category_autofills = array();
|
||||||
|
|
||||||
if (!empty($list))
|
if (!empty($list))
|
||||||
{
|
{
|
||||||
foreach ($list as $key => $item)
|
foreach ($list as $key => $item)
|
||||||
{
|
{
|
||||||
if (!empty($item["category"]))
|
$item["id"] = $key;
|
||||||
|
|
||||||
|
$date = "Unscheduled";
|
||||||
|
if (!empty($item["deadline"]))
|
||||||
{
|
{
|
||||||
$category = strtolower($item["category"]);
|
$date = get_fancy_date($item["deadline"]);
|
||||||
$category_name = $item["category"];
|
$date_int = $item["deadline"];
|
||||||
$category_basis = "custom";
|
|
||||||
}
|
|
||||||
else if (!empty($item["deadline"]))
|
|
||||||
{
|
|
||||||
$deadline = $item["deadline"];
|
|
||||||
|
|
||||||
$ymd = date("y-m-d", $deadline);
|
|
||||||
$day = date("l", $deadline);
|
|
||||||
$dayth = intval(date("z", $deadline));
|
|
||||||
|
|
||||||
$category = $ymd;
|
|
||||||
if ($dayth - $now_dayth == 0)
|
|
||||||
{
|
|
||||||
$category_name = "Today ({$day})";
|
|
||||||
}
|
|
||||||
else if ($dayth - $now_dayth == 1)
|
|
||||||
{
|
|
||||||
$category_name = "Tomorrow ({$day})";
|
|
||||||
}
|
|
||||||
else if ($dayth - $now_dayth == -1)
|
|
||||||
{
|
|
||||||
$category_name = "Yesterday ({$day})";
|
|
||||||
}
|
|
||||||
else if ($dayth - $now_dayth < -7)
|
|
||||||
{
|
|
||||||
$category_name = "{$day} ({$ymd})";
|
|
||||||
}
|
|
||||||
else if ($dayth - $now_dayth < 0)
|
|
||||||
{
|
|
||||||
$category_name = "Last " . $day;
|
|
||||||
}
|
|
||||||
else if ($dayth - $now_dayth < 7)
|
|
||||||
{
|
|
||||||
$category_name = $day;
|
|
||||||
}
|
|
||||||
else if ($dayth - $now_dayth < 14)
|
|
||||||
{
|
|
||||||
$category_name = "Next " . $day;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
$category_name = "{$day} ({$ymd})";
|
|
||||||
}
|
|
||||||
|
|
||||||
$category_basis = "date";
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
$category = "uncategorized";
|
$date_int = "-1";
|
||||||
$category_name = "Uncategorized";
|
}
|
||||||
$category_basis = "default";
|
|
||||||
|
if (!empty($item["category"]))
|
||||||
|
{
|
||||||
|
$category_name = $item["category"];
|
||||||
|
|
||||||
|
$category_autofills[] = $item["category"];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$category_name = $default_category;
|
||||||
|
}
|
||||||
|
|
||||||
|
$category = strtolower($category_name);
|
||||||
|
$category = str_replace(" ", "-", $category);
|
||||||
|
$category = str_replace([ "\t", "\n", "\r", "\0", "\v" ], "--", $category);
|
||||||
|
|
||||||
|
$is_pinned = false;
|
||||||
|
if (in_array($category, $pinned_categories))
|
||||||
|
{
|
||||||
|
$is_pinned = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (empty($categories[$category]))
|
if (empty($categories[$category]))
|
||||||
{
|
{
|
||||||
$categories[$category] = array(
|
$categories[$category] = array(
|
||||||
"title" => $category_name,
|
"title" => $category_name,
|
||||||
"basis" => $category_basis,
|
"id" => $category,
|
||||||
"list" => array(),
|
"list" => array(),
|
||||||
|
"pinned" => $is_pinned,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
$categories[$category]["list"][$key] = $item;
|
if (empty($categories[$category]["list"][$date_int]))
|
||||||
|
{
|
||||||
|
$categories[$category]["list"][$date_int] = array(
|
||||||
|
"title" => $date,
|
||||||
|
"id" => $date_int,
|
||||||
|
"list" => array(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$categories[$category]["list"][$date_int]["list"][$key] = $item;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (!empty($categories))
|
if (!empty($categories))
|
||||||
{
|
{
|
||||||
$te->set_block("MAIN_ITEMS", "");
|
$te->set_block("MAIN_ITEMS", "");
|
||||||
}
|
}
|
||||||
$te->set_block("DATALIST_AUTOFILLS", "");
|
$te->set_block("DATALIST_AUTOFILLS", "");
|
||||||
|
|
||||||
ksort($categories);
|
foreach ($categories as $category_key => $category)
|
||||||
|
{
|
||||||
|
if (!empty($categories[$category_key]["list"]))
|
||||||
|
{
|
||||||
|
ksort($categories[$category_key]["list"]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uasort($categories, function($a, $b)
|
||||||
|
{
|
||||||
|
global $pinned_categories;
|
||||||
|
|
||||||
|
$is_a_pinned = isset($a["pinned"]) ? $a["pinned"] : false;
|
||||||
|
$is_b_pinned = isset($b["pinned"]) ? $b["pinned"] : false;
|
||||||
|
$a_id = isset($a["id"]) ? $a["id"] : 1;
|
||||||
|
|
||||||
|
if ($is_a_pinned && $is_b_pinned)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else if ($a_id == "uncategorized")
|
||||||
|
{
|
||||||
|
if ($is_b_pinned)
|
||||||
|
{
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if ($is_a_pinned)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
$category_autofills = array_unique($category_autofills);
|
||||||
|
foreach ($category_autofills as $autofill)
|
||||||
|
{
|
||||||
|
$te->append_argumented_block("DATALIST_AUTOFILLS", "DATALIST_AUTOFILL", [
|
||||||
|
"DATALIST_AUTOFILL_DATA" => $autofill,
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($json_requested) || isset($_GET["json"]))
|
||||||
|
{
|
||||||
|
header("Content-Type: application/json");
|
||||||
|
echo json_encode($categories);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
$titles = array();
|
$titles = array();
|
||||||
foreach ($categories as $category_key => $category)
|
foreach ($categories as $category_key => $category)
|
||||||
{
|
{
|
||||||
$category_name = $category["title"];
|
if (empty($category["list"]))
|
||||||
$category_basis = $category["basis"];
|
|
||||||
$te->set_block("MAIN_CATEGORY_ITEMS", "");
|
|
||||||
|
|
||||||
if ($category_basis == "custom")
|
|
||||||
{
|
{
|
||||||
$te->append_argumented_block("DATALIST_AUTOFILLS", "DATALIST_AUTOFILL", [
|
continue;
|
||||||
"DATALIST_AUTOFILL_DATA" => $category_name,
|
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($category["list"] as $key => $item)
|
$te->set_block("MAIN_CATEGORY_ITEMS", "");
|
||||||
|
|
||||||
|
foreach ($category["list"] as $date_key => $date)
|
||||||
{
|
{
|
||||||
$titles[] = $item["title"];
|
$te->set_block("MAIN_DATE_ITEMS", "");
|
||||||
|
|
||||||
if (empty($item["description"]))
|
foreach ($date["list"] as $key => $item)
|
||||||
{
|
{
|
||||||
$te->set_block_template("MAIN_ITEM_SUMMARY", "MAIN_ITEM_SUMMARY_NODESC");
|
$titles[] = $item["title"];
|
||||||
}
|
|
||||||
else
|
$deadline = "N/A";
|
||||||
{
|
$created = "N/A";
|
||||||
$te->set_block_template("MAIN_ITEM_SUMMARY", "MAIN_ITEM_SUMMARY_DESC");
|
$modified = "N/A";
|
||||||
|
$displayed_category = "Uncategorized";
|
||||||
|
$category_raw = $item["category"];
|
||||||
|
|
||||||
|
if (empty($item["description"]))
|
||||||
|
{
|
||||||
|
$te->set_block_template("MAIN_ITEM_SUMMARY", "MAIN_ITEM_SUMMARY_NODESC");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
$te->set_block_template("MAIN_ITEM_SUMMARY", "MAIN_ITEM_SUMMARY_DESC");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($item["deadline"]))
|
||||||
|
{
|
||||||
|
$deadline = date("Y-m-d", intval($item["deadline"]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($item["created"]))
|
||||||
|
{
|
||||||
|
$created = date("Y-m-d", intval($item["created"]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isset($item["modified"]))
|
||||||
|
{
|
||||||
|
$modified = date("Y-m-d", intval($item["modified"]));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!empty($item["category"]))
|
||||||
|
{
|
||||||
|
$displayed_category = $item["category"];
|
||||||
|
}
|
||||||
|
|
||||||
|
$te->append_argumented_block("MAIN_DATE_ITEMS", "MAIN_ITEM", [
|
||||||
|
"MAIN_ITEM_ID" => $key,
|
||||||
|
"MAIN_ITEM_TITLE" => str_replace([ "\"", "'" ], [ """, "'" ], $item["title"]),
|
||||||
|
"MAIN_ITEM_DESCRIPTION" => str_replace([ "\"", "'" ], [ """, "'" ], $item["description"]),
|
||||||
|
"MAIN_ITEM_CATEGORY" => str_replace([ "\"", "'" ], [ """, "'" ], $displayed_category),
|
||||||
|
"MAIN_ITEM_CATEGORY_RAW" => $category_raw,
|
||||||
|
"MAIN_ITEM_DEADLINE" => $deadline,
|
||||||
|
"MAIN_ITEM_CREATED" => $created,
|
||||||
|
"MAIN_ITEM_MODIFIED" => $modified,
|
||||||
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
$te->append_argumented_block("MAIN_CATEGORY_ITEMS", "MAIN_ITEM", [
|
$te->append_argumented_block("MAIN_CATEGORY_ITEMS", "MAIN_DATE", [
|
||||||
"MAIN_ITEM_ID" => $key,
|
"MAIN_DATE_ID" => $date_key,
|
||||||
"MAIN_ITEM_TITLE" => $item["title"],
|
"MAIN_DATE_TITLE" => $date["title"],
|
||||||
"MAIN_ITEM_DESCRIPTION" => $item["description"],
|
]);
|
||||||
]);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
$te->append_argumented_block("MAIN_ITEMS", "MAIN_CATEGORY", [
|
$te->append_argumented_block("MAIN_ITEMS", "MAIN_CATEGORY", [
|
||||||
"MAIN_CATEGORY_ID" => $category_key,
|
"MAIN_CATEGORY_ID" => $category_key,
|
||||||
"MAIN_CATEGORY_TITLE" => $category_name,
|
"MAIN_CATEGORY_TITLE" => $category["title"],
|
||||||
|
"MAIN_CATEGORY_PIN_OR_UNPIN" => $category["pinned"] ? "Unpin" : "Pin",
|
||||||
|
"MAIN_CATEGORY_EXTRA_PIN_BUTTON_CLASS" => $category["id"] == $default_category_id ? "hidden" : "",
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
$te->append_argumented_block("DATALISTS", "DATALIST", [
|
$te->append_argumented_block("DATALISTS", "DATALIST", [
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
<div class="todo-add-container">
|
<div class="todo-add-container">
|
||||||
<details>
|
<details>
|
||||||
<summary>New</summary>
|
<summary id="addFormSummary">New</summary>
|
||||||
<form action="./" method="POST" autocomplete="off">
|
<form action="./" method="POST" autocomplete="off">
|
||||||
<input type="hidden" name="action" value="add" />
|
<input id="add_form_action" type="hidden" name="action" value="add" />
|
||||||
|
<input id="todo_item_id" type="hidden" name="todo_item_id" value="" />
|
||||||
<div class="todo-add-div">
|
<div class="todo-add-div">
|
||||||
<p>{{ ADD_NOTICE }}</p>
|
<p>{{ ADD_NOTICE }}</p>
|
||||||
</div>
|
</div>
|
||||||
@@ -15,6 +16,7 @@
|
|||||||
<div class="todo-add-div">
|
<div class="todo-add-div">
|
||||||
<label class="label" for="todo_description">Description</label>
|
<label class="label" for="todo_description">Description</label>
|
||||||
<input id="todo_description" type="text" name="todo_description" />
|
<input id="todo_description" type="text" name="todo_description" />
|
||||||
|
<i>(optional)</i>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="todo-add-div">
|
<div class="todo-add-div">
|
||||||
@@ -30,7 +32,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="todo-add-div">
|
<div class="todo-add-div">
|
||||||
<input class="todo-add-button" type="submit" value="Add" />
|
<input id="add_form_button" class="todo-add-button" type="submit" value="Add" />
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</details>
|
</details>
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
<p><a href="https://github.com/Thayol/todo-php"><small>GitHub</small></p>
|
||||||
@@ -17,4 +17,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<p>Don't have an account? <a href="./?reg">Sign up!</a></p>
|
<p>Don't have an account? <a href="./?reg">Sign up!</a></p>
|
||||||
|
{{ GITHUB_LINK }}
|
||||||
</div>
|
</div>
|
||||||
@@ -1,4 +1,12 @@
|
|||||||
<div class="todo-category" id="todo-category-{{ MAIN_CATEGORY_ID }}">
|
<div class="todo-category" id="todo-category-{{ MAIN_CATEGORY_ID }}">
|
||||||
<h3>{{ MAIN_CATEGORY_TITLE }}</h3>
|
<h3>
|
||||||
|
{{ MAIN_CATEGORY_TITLE }}
|
||||||
|
|
||||||
|
<form style="float: right;" class="{{ MAIN_CATEGORY_EXTRA_PIN_BUTTON_CLASS }}" action="./" method="POST">
|
||||||
|
<input type="hidden" name="action" value="pin" />
|
||||||
|
<input type="hidden" name="category_name" value="{{ MAIN_CATEGORY_ID }}" />
|
||||||
|
<input type="submit" value="{{ MAIN_CATEGORY_PIN_OR_UNPIN }}" class="todo-button" />
|
||||||
|
</form>
|
||||||
|
</h3>
|
||||||
{{ MAIN_CATEGORY_ITEMS }}
|
{{ MAIN_CATEGORY_ITEMS }}
|
||||||
</div>
|
</div>
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
<div class="todo-category" id="todo-category-{{ MAIN_DATE_ID }}">
|
||||||
|
<h3>{{ MAIN_DATE_TITLE }}</h3>
|
||||||
|
{{ MAIN_DATE_ITEMS }}
|
||||||
|
</div>
|
||||||
@@ -2,6 +2,13 @@
|
|||||||
<details>
|
<details>
|
||||||
<summary>{{ MAIN_ITEM_SUMMARY }}</summary>
|
<summary>{{ MAIN_ITEM_SUMMARY }}</summary>
|
||||||
|
|
||||||
|
<small><i>ID: {{ MAIN_ITEM_ID }}</i></small><br>
|
||||||
|
<small><i>Created: {{ MAIN_ITEM_CREATED }}</i></small><br>
|
||||||
|
<small><i>Modified: {{ MAIN_ITEM_MODIFIED }}</i></small><br>
|
||||||
|
Deadline: {{ MAIN_ITEM_DEADLINE }}<br>
|
||||||
|
Category: {{ MAIN_ITEM_CATEGORY }}<br>
|
||||||
|
<br>
|
||||||
|
|
||||||
<form action="./" method="POST">
|
<form action="./" method="POST">
|
||||||
<input type="hidden" name="action" value="delay" />
|
<input type="hidden" name="action" value="delay" />
|
||||||
<input type="hidden" name="delay_by" value="-1 week" />
|
<input type="hidden" name="delay_by" value="-1 week" />
|
||||||
@@ -35,6 +42,10 @@
|
|||||||
<div style="display:inline-block;width:1em;"></div>
|
<div style="display:inline-block;width:1em;"></div>
|
||||||
<div style="display:inline-block;width:1em;"></div>
|
<div style="display:inline-block;width:1em;"></div>
|
||||||
|
|
||||||
|
<form onsubmit="return false">
|
||||||
|
<input type="submit" value="Edit" onclick="editNote('{{ MAIN_ITEM_ID }}', '{{ MAIN_ITEM_TITLE }}', '{{ MAIN_ITEM_DESCRIPTION }}', '{{ MAIN_ITEM_DEADLINE }}', '{{ MAIN_ITEM_CATEGORY_RAW }}')" />
|
||||||
|
</form>
|
||||||
|
|
||||||
<form action="./" method="POST">
|
<form action="./" method="POST">
|
||||||
<input type="hidden" name="action" value="remove" />
|
<input type="hidden" name="action" value="remove" />
|
||||||
<input type="hidden" name="todo_item_id" value="{{ MAIN_ITEM_ID }}" />
|
<input type="hidden" name="todo_item_id" value="{{ MAIN_ITEM_ID }}" />
|
||||||
|
|||||||
@@ -13,4 +13,5 @@
|
|||||||
<input type="hidden" name="logout" value="1">
|
<input type="hidden" name="logout" value="1">
|
||||||
<input type="submit" value="Log out">
|
<input type="submit" value="Log out">
|
||||||
</form>
|
</form>
|
||||||
|
{{ GITHUB_LINK }}
|
||||||
</div>
|
</div>
|
||||||
@@ -21,4 +21,5 @@
|
|||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
<p>Have an account? <a href="./?">Log in!</a></p>
|
<p>Have an account? <a href="./?">Log in!</a></p>
|
||||||
|
{{ GITHUB_LINK }}
|
||||||
</div>
|
</div>
|
||||||
+30
-7
@@ -1,16 +1,39 @@
|
|||||||
|
var autoClose = true;
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", function(){
|
document.addEventListener("DOMContentLoaded", function(){
|
||||||
// Fetch all the details element.
|
// Fetch all the details element.
|
||||||
const details = document.querySelectorAll("details");
|
const details = document.querySelectorAll("details");
|
||||||
|
|
||||||
// Add the onclick listeners.
|
// Add the onclick listeners.
|
||||||
details.forEach((targetDetail) => {
|
details.forEach((targetDetail) => {
|
||||||
targetDetail.addEventListener("click", () => {
|
targetDetail.addEventListener("click", () => {
|
||||||
// Close all the details that are not targetDetail.
|
// Close all the details that are not targetDetail.
|
||||||
details.forEach((detail) => {
|
if (autoClose) {
|
||||||
if (detail !== targetDetail) {
|
details.forEach((detail) => {
|
||||||
detail.removeAttribute("open");
|
if (detail !== targetDetail) {
|
||||||
}
|
detail.removeAttribute("open");
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
});
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
function editNote(id, title, description, deadline, category) {
|
||||||
|
document.getElementById("add_form_action").value = "edit";
|
||||||
|
document.getElementById("add_form_button").value = "Edit";
|
||||||
|
|
||||||
|
document.getElementById("todo_item_id").value = id.toString();
|
||||||
|
document.getElementById("todo_title").value = title;
|
||||||
|
document.getElementById("todo_description").value = description;
|
||||||
|
document.getElementById("todo_deadline").value = deadline;
|
||||||
|
document.getElementById("todo_category").value = category;
|
||||||
|
|
||||||
|
setTimeout(
|
||||||
|
function() {
|
||||||
|
document.getElementById("addFormSummary").click();
|
||||||
|
},
|
||||||
|
5);
|
||||||
|
|
||||||
|
// document.getElementById("addFormSummary").click();
|
||||||
|
}
|
||||||
+13
-3
@@ -1,3 +1,7 @@
|
|||||||
|
* {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
font-family: 'Roboto', sans-serif;
|
font-family: 'Roboto', sans-serif;
|
||||||
background-color: #111111;
|
background-color: #111111;
|
||||||
@@ -43,7 +47,7 @@ h3 {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
.todo-item form input, .navbar-form input {
|
.todo-item form input, .navbar-form input, .todo-button {
|
||||||
border: 2px solid #333333;
|
border: 2px solid #333333;
|
||||||
padding: 5px;
|
padding: 5px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
@@ -51,12 +55,15 @@ h3 {
|
|||||||
color: white;
|
color: white;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
}
|
}
|
||||||
.todo-item form input:focus, .navbar-form input:focus {
|
.todo-item form input:focus, .navbar-form input:focus, .todo-button:focus {
|
||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
.todo-item form input:active, .navbar-form input:active {
|
.todo-item form input:active, .navbar-form input:active, .todo-button:active {
|
||||||
background-color: #222222;
|
background-color: #222222;
|
||||||
}
|
}
|
||||||
|
.todo-button {
|
||||||
|
margin: -5px;
|
||||||
|
}
|
||||||
|
|
||||||
summary, details[open] {
|
summary, details[open] {
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
@@ -117,6 +124,9 @@ summary:focus {
|
|||||||
.navbar {
|
.navbar {
|
||||||
text-align: right;
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user