diff --git a/boilerplate/head.php b/boilerplate/head.php index 308679e..8cfe8fd 100644 --- a/boilerplate/head.php +++ b/boilerplate/head.php @@ -1,6 +1,6 @@ - + <?php if ($title) { @@ -8,7 +8,7 @@ } echo $site_name; ?> - + @@ -31,4 +31,3 @@ echo "
$err
"; } ?> - diff --git a/config.php b/config.php index 8fed913..60502b4 100644 --- a/config.php +++ b/config.php @@ -3,6 +3,7 @@ // site config $site_name = "Todo List Manager"; $signups = "invite"; // true, false, "invite" - treats it as true if no users currently exist, invite requires an admin to invite the user +$language = "en-US"; // an item from the lang folder. exclude the ".json" $admin_users = array( // "username1", "username2", ... @@ -20,6 +21,8 @@ $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%t%c - %d"; $default_schema = array( "general" => array( "name" => "General", @@ -27,7 +30,7 @@ $default_schema = array( "items" => array( "general" => array( "name" => "", - "display_format" => "For %d - %c" + "display_format" => "For %C%t%c - %d" ) ) ) diff --git a/css/base.css b/css/base.css index 23b3aa2..35da159 100644 --- a/css/base.css +++ b/css/base.css @@ -33,7 +33,12 @@ body { font-size: 18px; } -input { +h3 { + margin-bottom: 0; +} + +input, +select { background-color: var(--input-background); color: var(--color); border: 1px solid var(--border); @@ -42,7 +47,8 @@ input { margin: 2px; } -input:focus { +input:focus, +select:focus { outline: 2px solid var(--subtext); } @@ -63,6 +69,15 @@ i { color: var(--subtext); } +ul { + margin: 0; + padding-left: 25px; +} + +.right { + text-align: right; +} + .err { color: var(--red); border: 2px dashed var(--red); diff --git a/helper.php b/helper.php index 21d3f5d..d68b643 100644 --- a/helper.php +++ b/helper.php @@ -28,7 +28,7 @@ function is_logged_in(): false | array { ); if ($user_object && get_token($user_object[0]["username"], $user_object[0]["password_hash"]) === $token) { - return $user_object; + return $user_object[0]; } return false; diff --git a/index.php b/index.php index 134362e..618eb29 100644 --- a/index.php +++ b/index.php @@ -1,19 +1,109 @@ +include "config.php"; +include "helper.php"; +include "boilerplate/head.php"; -Log In +$user = is_logged_in(); + +if ($user === false) { + echo "{$lang['account']['log_in']}"; -Sign Up"; + echo " - {$lang['account']['sign_up']}"; } include "boilerplate/foot.php"; + exit(); +} + + +$select_options = ""; +$todo_list = ""; + +$q = "SELECT * FROM section WHERE users='{$user['id']}' ORDER BY LOWER(name) 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"; + $enable_optgroup = $show_subtitle || count($rows) !== 1; + + $todo_list .= "

" . htmlspecialchars($section["name"]) . "

"; + + if ($enable_optgroup) { + $select_options .= ""; + } + + $first = true; + foreach ($rows as $row) { + $select_options .= ""; + $first = false; + } + + if ($enable_optgroup) { + $select_options .= ""; + } +} + +?> + +
+

+
+ + + + + + + + + + + + + + + + + +
+ +
" name="description" id="description" required>
">
+
+ +

+ +
+ + diff --git a/lang/en-US.json b/lang/en-US.json new file mode 100644 index 0000000..cb60387 --- /dev/null +++ b/lang/en-US.json @@ -0,0 +1,36 @@ +{ + "account": { + "errors": { + "bad_request": "Bad request", + "username_length": "Username must be between 1 and 64 characters", + "username_characters": "Username can only include a-z, 0-9, _, and -", + "user_not_found": "User '%u' not found", + "user_exists": "User '%u' already exists", + "incorrect_password": "Incorrect password", + "password_match": "Passwords don't match" + }, + + "log_in": "Log In", + "log_in_instead": "Log in instead?", + "sign_up": "Sign Up", + "sign_up_instead": "Sign up instead?", + "username": "Username", + "password": "Password", + "verify": "Verify password" + }, + + "add": { + "title": "Add Item", + "section": "Section:", + "date": "Date:", + "description": "Description:", + "description_placeholder": "Important thing", + "button": "Add" + }, + + "list": { + "title": "Current Todo List", + "remove": "Completed", + "none": "None" + } +} diff --git a/login.php b/login.php index 2d817c3..47545de 100644 --- a/login.php +++ b/login.php @@ -15,18 +15,18 @@ $p = $_POST["password"]; if (!($u && $p)) { - $err = "Bad request, missing username or password parameter"; + $err = $lang["account"]["errors"]["bad_request"]; } else if (strlen($u) > 64 || strlen($u) === 0) { - $err = "Username must be 1-64 chars"; + $err = $lang["account"]["errors"]["username_length"]; } else if (!preg_match("/^[a-z0-9_-]{1,64}$/", $u)) { - $err = "Username can only include a-z, 0-9, _, and -"; + $err = $lang["account"]["errors"]["username_characters"]; } else { $query = "SELECT password_hash FROM users WHERE username='$u' LIMIT 1;"; $response = pg_query($db, $query); if (pg_num_rows($response) === 0) { - $err = "User '" . htmlspecialchars($u) . "' not found"; + $err = str_replace("%u", htmlspecialchars($u), $lang["account"]["errors"]["user_not_found"]); } else { $user = pg_fetch_array($response); if (password_verify($p, $user["password_hash"])) { @@ -38,27 +38,27 @@ header("Location: index.php"); exit(); } else { - $err = "Incorrect password"; + $err = $lang["account"]["errors"]["incorrect_password"]; } } } } - $title = "Log In"; + $title = $lang["account"]["log_in"]; include "boilerplate/head.php"; ?>
-
-
-
+
" name="username" value="" maxlength="64" required>
+
" name="password" type="password" value="" required>
+
">
Sign up instead?

"; + echo "

{$lang['account']['sign_up_instead']}

"; } include "boilerplate/foot.php"; diff --git a/setup.php b/setup.php index c1b72ef..706476d 100644 --- a/setup.php +++ b/setup.php @@ -6,7 +6,10 @@ $queries = array( "CREATE TABLE IF NOT EXISTS users ( id VARCHAR(64) PRIMARY KEY, username VARCHAR(64) UNIQUE NOT NULL, - password_hash VARCHAR(256) NOT NULL + password_hash VARCHAR(256) NOT NULL, + enable_colors BOOLEAN NOT NULL, + yellow_threshold INT NOT NULL, + gray_threshold INT NOT NULL );", "CREATE TABLE IF NOT EXISTS section ( id VARCHAR(64) PRIMARY KEY, @@ -17,8 +20,8 @@ $queries = array( "CREATE TABLE IF NOT EXISTS row ( id VARCHAR(64) PRIMARY KEY, section VARCHAR(64) NOT NULL REFERENCES section(id), - name VARCHAR(128), - display_format VARCHAR(128) NOT NULL -- %d - date, %c - description + name VARCHAR(128), -- ignored if first item and show_subtitle is enabled + display_format VARCHAR(128) NOT NULL -- %t - date, %d - description, %C - start color, %c - end color );", "CREATE TABLE IF NOT EXISTS item ( id VARCHAR(64) PRIMARY KEY, diff --git a/signup.php b/signup.php index 1e0b0a4..fe0e838 100644 --- a/signup.php +++ b/signup.php @@ -16,13 +16,13 @@ $v = $_POST["verify"]; if ($v != $p) { - $err = "Passwords don't match"; + $err = $lang["account"]["errors"]["password_match"]; } else if (!($u && $p && $v)) { - $err = "Bad request, missing username, password, or verify parameter"; + $err = $lang["account"]["errors"]["bad_request"]; } else if (strlen($u) > 64 || strlen($u) === 0) { - $err = "Username must be 1-64 chars"; + $err = $lang["account"]["errors"]["username_length"]; } else if (!preg_match("/^[a-z0-9_-]{1,64}$/", $u)) { - $err = "Username can only include a-z, 0-9, _, and -"; + $err = $lang["account"]["errors"]["username_characters"]; } else { $query = "SELECT count(*) FROM users WHERE username='$u' LIMIT 1;"; @@ -35,11 +35,14 @@ $user_parameters = array( "id" => $user_id, "username" => $u, - "password_hash" => $pw_hash + "password_hash" => $pw_hash, + "enable_colors" => true, + "yellow_threshold" => 2, + "gray_threshold" => 60 ); pg_insert($db, "users", $user_parameters); - + foreach ($default_schema as $section_id => $section_data) { $section_id = generate_id(); $section_parameters = array( @@ -66,28 +69,27 @@ $token = get_token($u, $pw_hash); setcookie( - "token", - $token, + "token", $token, time() + 60 * 60 * 24 * 30 * 265 // 1 year from now ); header("Location: index.php"); exit(); } else { - $err = "User '" . htmlspecialchars($u) . "' already exists"; + $err = str_replace("%u", htmlspecialchars($u), $lang["account"]["errors"]["user_exists"]); } } } - $title = "Sign Up"; + $title = $lang["account"]["sign_up"]; include "boilerplate/head.php"; ?>
-
-
-
-
-

Log in instead?

+
" name="username" value="" maxlength="64" required>
+
" name="password" type="password" value="" required>
+
" name="verify" type="password" required>
+
">
+