creating/deleting rows and sections
This commit is contained in:
parent
89efc1ccc0
commit
34256263ac
7 changed files with 180 additions and 18 deletions
4
TODO.md
Normal file
4
TODO.md
Normal file
|
@ -0,0 +1,4 @@
|
|||
- saving section info
|
||||
- account deletion
|
||||
- admin page
|
||||
- invite codes
|
|
@ -16,21 +16,24 @@ $db_username = "postgres";
|
|||
$db_password = "postgres";
|
||||
|
||||
// DO NOT CHANGE THIS!!!
|
||||
$lang = json_decode(file_get_contents("lang/$language.json"), true);
|
||||
$db_info = "host=$db_host dbname=$db_name user=$db_username password=$db_password";
|
||||
$db = pg_connect($db_info);
|
||||
|
||||
// default schema
|
||||
// DON'T CHANGE THIS UNLESS YOU KNOW WHAT YOU'RE DOING!!!
|
||||
$lang = json_decode(file_get_contents("lang/$language.json"), true);
|
||||
$default_format = "For %C<b>%t</b>%c - %d";
|
||||
$default_section_name = "New Section";
|
||||
$default_row_name = "New Row";
|
||||
|
||||
$default_schema = array(
|
||||
"general" => array(
|
||||
"name" => "General",
|
||||
"show_subtitle" => false,
|
||||
"items" => array(
|
||||
"general" => array(
|
||||
"name" => "",
|
||||
"display_format" => "For %C<b>%t</b>%c - %d"
|
||||
"name" => $default_row_name,
|
||||
"display_format" => $default_format
|
||||
)
|
||||
)
|
||||
)
|
||||
|
|
16
css/base.css
16
css/base.css
|
@ -33,7 +33,7 @@ body {
|
|||
font-size: 18px;
|
||||
}
|
||||
|
||||
h3 {
|
||||
h3, h4 {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
|
||||
|
@ -87,6 +87,12 @@ details:not([open]) summary {
|
|||
color: var(--subtext);
|
||||
}
|
||||
|
||||
blockquote {
|
||||
margin: 10px 0;
|
||||
padding-left: 10px;
|
||||
border-left: 4px solid var(--subtext);
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: monospace;
|
||||
padding: 1px 3px;
|
||||
|
@ -138,3 +144,11 @@ code {
|
|||
flex-wrap: wrap;
|
||||
gap: 3px 30px;
|
||||
}
|
||||
|
||||
#section-config {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
flex-wrap: nowrap;
|
||||
gap: 10px;
|
||||
margin-bottom: 10px;
|
||||
}
|
||||
|
|
131
index.php
131
index.php
|
@ -20,17 +20,53 @@ if ($user === false) {
|
|||
} else if ($_SERVER["REQUEST_METHOD"] === "POST") {
|
||||
$intent = $_POST["intent"];
|
||||
|
||||
if ($intent === "create-item") {
|
||||
// TODO: update-texts
|
||||
if ($intent === "create-section") {
|
||||
$section_id = generate_id();
|
||||
|
||||
pg_insert(
|
||||
$db, "section", array(
|
||||
"id" => $section_id,
|
||||
"users" => $user["id"],
|
||||
"name" => $default_section_name,
|
||||
"show_subtitle" => false
|
||||
)
|
||||
);
|
||||
|
||||
pg_insert(
|
||||
$db, "row", array(
|
||||
"id" => generate_id(),
|
||||
"section" => $section_id,
|
||||
"name" => $default_row_name,
|
||||
"display_format" => $default_format
|
||||
)
|
||||
);
|
||||
} else if ($intent === "create-row") {
|
||||
$section_id = $_POST["section"];
|
||||
|
||||
if (strlen($section_id) !== 64 || !preg_match("/[a-f0-9]{64}/", $section_id)) {
|
||||
$err = $lang["add"]["errors"]["invalid_id"];
|
||||
} else {
|
||||
pg_insert(
|
||||
$db, "row", array(
|
||||
"id" => generate_id(),
|
||||
"section" => $section_id,
|
||||
"name" => $default_row_name,
|
||||
"display_format" => $default_format
|
||||
)
|
||||
);
|
||||
}
|
||||
} else if ($intent === "create-item") {
|
||||
$row_id = $_POST["row"];
|
||||
$date = strtotime($_POST["date"]);
|
||||
$description = $_POST["description"];
|
||||
|
||||
if (strlen($row_id) !== 64 || !preg_match("/[a-f0-9]{64}/", $row_id)) {
|
||||
$err = lang["add"]["errors"]["invalid_id"];
|
||||
$err = $lang["add"]["errors"]["invalid_id"];
|
||||
} else if ($date === false) {
|
||||
$err = lang["add"]["errors"]["date"];
|
||||
$err = $lang["add"]["errors"]["date"];
|
||||
} else if (strlen($description) === 0 || strlen($description) > 256) {
|
||||
$err = lang["add"]["errors"]["description_length"];
|
||||
$err = $lang["add"]["errors"]["description_length"];
|
||||
} else {
|
||||
$repopulate = array(
|
||||
"row_id" => $row_id,
|
||||
|
@ -75,25 +111,47 @@ if ($user === false) {
|
|||
$err = $lang["account"]["errors"]["incorrect_password"];
|
||||
}
|
||||
}
|
||||
} else if ($_GET["del"] && strlen($_GET["del"]) === 64 && preg_match("/[a-f0-9]{64}/", $_GET["del"])) {
|
||||
pg_query($db, "DELETE FROM item WHERE id='{$_GET['del']}';");
|
||||
} else if ($_GET["del"]) {
|
||||
$del_type = explode("-", $_GET["del"])[0];
|
||||
$del_id = explode("-", $_GET["del"])[1];
|
||||
|
||||
if (strlen($del_id) === 64 && preg_match("/[a-f0-9]{64}/", $del_id) && ($del_type === "item" || $del_type === "row" || $del_type === "section")) {
|
||||
pg_query($db, "DELETE FROM $del_type WHERE id='$del_id';");
|
||||
}
|
||||
}
|
||||
|
||||
include "boilerplate/head.php";
|
||||
|
||||
$select_options = "";
|
||||
$todo_list = "";
|
||||
$section_conf = "";
|
||||
$section_forms = "";
|
||||
|
||||
$q = "SELECT * FROM section WHERE users='{$user['id']}' ORDER BY LOWER(name) ASC;";
|
||||
$q = "SELECT * FROM section WHERE users='{$user['id']}' ORDER BY LOWER(name) ASC, id ASC;";
|
||||
$sections = pg_fetch_all(pg_query($db, $q));
|
||||
|
||||
foreach ($sections as $section) {
|
||||
$q = "SELECT * FROM row WHERE section='{$section['id']}' ORDER BY LOWER(name) ASC;";
|
||||
$rows = pg_fetch_all(pg_query($db, $q));
|
||||
$show_subtitle = $section["show_subtitle"] === "t";
|
||||
$q = "SELECT * FROM row WHERE section='{$section['id']}' ORDER BY LOWER(name) ASC, id ASC;";
|
||||
$rows = pg_fetch_all(pg_query($db, $q));
|
||||
$enable_optgroup = $show_subtitle || count($rows) !== 1;
|
||||
|
||||
$todo_list .= "<h3>" . htmlspecialchars($section["name"]) . "</h3>";
|
||||
$section_conf .= "<blockquote>
|
||||
<div><label>
|
||||
{$lang['settings']['sections']['section']['title']}
|
||||
<input maxlength=\"128\" placeholder='{$lang['settings']['sections']['section']['placeholder']}' value=\"" . htmlspecialchars($section["name"]) . "\" required name=\"section-{$section['id']}-name\">
|
||||
</label></div>
|
||||
<div><label>
|
||||
{$lang['settings']['sections']['section']['show_subtitle']}
|
||||
<input type=\"checkbox\" name=\"section-{$section['id']}-subtitle\"" . ($show_subtitle ? " checked" : "") . ">
|
||||
</label></div>
|
||||
<div>
|
||||
<a class=\"plain\" href=\"index.php?del=section-{$section['id']}\">
|
||||
<button type=\"button\" tabindex=\"-1\">{$lang['settings']['sections']['section']['delete']}</button>
|
||||
</a>
|
||||
</div>
|
||||
";
|
||||
|
||||
if ($enable_optgroup) {
|
||||
$select_options .= "<optgroup label=\"" . htmlspecialchars($section["name"]) . "\">";
|
||||
|
@ -114,7 +172,21 @@ foreach ($sections as $section) {
|
|||
$todo_list .= "<strong>" . htmlspecialchars($row["name"]) . "</strong>";
|
||||
}
|
||||
|
||||
$q = "SELECT * FROM item WHERE row='{$row['id']}' ORDER BY date ASC, LOWER(description) ASC;";
|
||||
$section_conf .= "<blockquote><div><label>
|
||||
{$lang['settings']['sections']['row']['title']}
|
||||
<input required placeholder=\"{$lang['settings']['sections']['row']['placeholder']}\" maxlength=\"128\" name=\"row-{$row['id']}-name\" value=\"" . htmlspecialchars($row["name"]) . "\">
|
||||
</label></div>
|
||||
<div><label>
|
||||
{$lang['settings']['sections']['row']['format']}
|
||||
<input placeholder=\"{$lang['settings']['sections']['row']['format_placeholder']}\" maxlength=\"128\" name=\"row-{$row['id']}-format\" value=\"" . htmlspecialchars($row["display_format"]) . "\">
|
||||
</label></div>
|
||||
<div><a class=\"plain\" href=\"index.php?del=row-{$row['id']}\">
|
||||
<button tabindex=\"-1\" type=\"button\">
|
||||
{$lang['settings']['sections']['row']['delete']}
|
||||
</button>
|
||||
</a></div></blockquote>";
|
||||
|
||||
$q = "SELECT * FROM item WHERE row='{$row['id']}' ORDER BY date ASC, LOWER(description) ASC, id ASC;";
|
||||
$items = pg_fetch_all(pg_query($db, $q));
|
||||
$todo_list .= "<ul>";
|
||||
|
||||
|
@ -132,7 +204,7 @@ foreach ($sections as $section) {
|
|||
)
|
||||
)
|
||||
)
|
||||
) . " <a class=\"plain\" href=\"index.php?del={$item['id']}\"><button tabindex=\"-1\">{$lang['list']['remove']}</button></a></li>";
|
||||
) . " <a class=\"plain\" href=\"index.php?del=item-{$item['id']}\"><button tabindex=\"-1\">{$lang['list']['remove']}</button></a></li>";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -141,6 +213,12 @@ foreach ($sections as $section) {
|
|||
$first = false;
|
||||
}
|
||||
|
||||
$section_forms .= "<form method=\"POST\" id=\"section-{$section['id']}-new\">
|
||||
<input type=\"hidden\" name=\"intent\" value=\"create-row\">
|
||||
<input type=\"hidden\" name=\"section\" value=\"{$section['id']}\">
|
||||
</form>";
|
||||
$section_conf .= "<input type=\"submit\" form=\"section-{$section['id']}-new\" value=\"{$lang['settings']['sections']['row']['new']}\"></blockquote>";
|
||||
|
||||
if ($enable_optgroup) {
|
||||
$select_options .= "</optgroup>";
|
||||
}
|
||||
|
@ -185,6 +263,37 @@ foreach ($sections as $section) {
|
|||
<div id="settings-container">
|
||||
<div>
|
||||
<h3><?php echo $lang["settings"]["sections"]["title"]; ?></h3>
|
||||
|
||||
<?php echo $section_forms; ?>
|
||||
|
||||
<form method="POST" id="create-section">
|
||||
<input type="hidden" name="intent" value="create-section">
|
||||
</form>
|
||||
|
||||
<form method="POST">
|
||||
<div id="section-config">
|
||||
<?php echo $section_conf; ?>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="intent" value="update-texts">
|
||||
<input type="submit" value="<?php echo $lang["settings"]["sections"]["save"]; ?>">
|
||||
<input type="submit" form="create-section" value="<?php echo $lang["settings"]["sections"]["section"]["new"]; ?>">
|
||||
</form>
|
||||
|
||||
<h4><?php echo $lang["settings"]["sections"]["format"]["title"]; ?></h4>
|
||||
<ul>
|
||||
<li><?php echo $lang["settings"]["sections"]["format"]["alphabetical"]; ?></li>
|
||||
<li><?php echo $lang["settings"]["sections"]["format"]["html"]; ?></li>
|
||||
<li>
|
||||
<?php echo $lang["settings"]["sections"]["format"]["replacements"]["title"] ?>
|
||||
<ul>
|
||||
<li><code>%t</code> - <?php echo $lang["settings"]["sections"]["format"]["replacements"]["%t"]; ?></li>
|
||||
<li><code>%d</code> - <?php echo $lang["settings"]["sections"]["format"]["replacements"]["%d"]; ?></li>
|
||||
<li><code>%C</code> - <?php echo $lang["settings"]["sections"]["format"]["replacements"]["%C"]; ?></li>
|
||||
<li><code>%c</code> - <?php echo $lang["settings"]["sections"]["format"]["replacements"]["%c"]; ?></li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
|
|
|
@ -43,7 +43,39 @@
|
|||
|
||||
"settings": {
|
||||
"sections": {
|
||||
"title": "Configure Sections"
|
||||
"section": {
|
||||
"title": "Title:",
|
||||
"placeholder": "Section title",
|
||||
"delete": "Delete section",
|
||||
"new": "New section",
|
||||
"show_subtitle": "Show separate title for first item?"
|
||||
},
|
||||
|
||||
"row": {
|
||||
"title": "Title:",
|
||||
"placeholder": "Row title",
|
||||
"delete": "Delete row",
|
||||
"new": "New row",
|
||||
"format": "Item display format:",
|
||||
"format_placeholder": "For %C<b>%t</b>%c - %d"
|
||||
},
|
||||
|
||||
"format": {
|
||||
"replacements": {
|
||||
"title": "Item display format replacements:",
|
||||
"%t": "date",
|
||||
"%d": "item description",
|
||||
"%C": "start color",
|
||||
"%c": "end color"
|
||||
},
|
||||
|
||||
"title": "Formatting Information",
|
||||
"alphabetical": "Sorted alphabetically by row/section title",
|
||||
"html": "Displayed as raw HTML"
|
||||
},
|
||||
|
||||
"title": "Configure Sections",
|
||||
"save": "Save"
|
||||
},
|
||||
|
||||
"account": {
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
$token = get_token($u, $user["password_hash"]);
|
||||
setcookie(
|
||||
"token", $token,
|
||||
time() + 60 * 60 * 24 * 30 * 265 // 1 year from now
|
||||
time() + 60 * 60 * 24 * 265 // 1 year from now
|
||||
);
|
||||
header("Location: index.php");
|
||||
exit();
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
$token = get_token($u, $pw_hash);
|
||||
setcookie(
|
||||
"token", $token,
|
||||
time() + 60 * 60 * 24 * 30 * 265 // 1 year from now
|
||||
time() + 60 * 60 * 24 * 365 // 1 year from now
|
||||
);
|
||||
header("Location: index.php");
|
||||
exit();
|
||||
|
|
Loading…
Reference in a new issue