summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--app/Http/Controllers/SiteController.php48
-rw-r--r--resources/css/home.css4
-rwxr-xr-xresources/views/do.blade.php48
-rwxr-xr-xresources/views/home.blade.php4
-rwxr-xr-xresources/views/matrix.blade.php8
-rwxr-xr-xroutes/web.php29
6 files changed, 114 insertions, 27 deletions
diff --git a/app/Http/Controllers/SiteController.php b/app/Http/Controllers/SiteController.php
index 301e101..3ef641a 100644
--- a/app/Http/Controllers/SiteController.php
+++ b/app/Http/Controllers/SiteController.php
@@ -198,4 +198,52 @@ class SiteController extends Controller
}
}
+ public function updateTodo(Request $req){
+ $file = storage_path('app/todo.json');
+ $items = file_exists($file) ? json_decode(file_get_contents($file), true) ?? [] : [];
+ $op = $req->input('op', 'append');
+
+ if ($op === 'overwrite') {
+ $lines = array_filter(array_map('trim', explode("\n", $req->input('content', ''))));
+ $items = array_values($lines);
+ } elseif ($op === 'delete') {
+ $index = (int) $req->input('index');
+ array_splice($items, $index, 1);
+ } else {
+ // append (default)
+ $lines = array_filter(array_map('trim', explode("\n", $req->input('content', ''))));
+ $items = array_merge($items, $lines);
+ }
+
+ file_put_contents($file, json_encode(array_values($items), JSON_PRETTY_PRINT));
+ return redirect('/do')->with('status', 'List updated.');
+ }
+
+ public function updateTodoWithToken(Request $req){
+ $token = $req->input('token', $req->header('X-Token'));
+ if (!$token || $token !== env('TODO_TOKEN')) {
+ abort(403, 'Invalid token.');
+ }
+
+ $file = storage_path('app/todo.json');
+ $items = file_exists($file) ? json_decode(file_get_contents($file), true) ?? [] : [];
+ $op = $req->input('op', 'append');
+
+ if ($op === 'overwrite') {
+ $lines = array_filter(array_map('trim', explode("\n", $req->input('content', ''))));
+ $items = array_values($lines);
+ } elseif ($op === 'delete') {
+ $index = (int) $req->input('index');
+ array_splice($items, $index, 1);
+ } elseif ($op === 'list') {
+ return response()->json($items);
+ } else {
+ $lines = array_filter(array_map('trim', explode("\n", $req->input('content', ''))));
+ $items = array_merge($items, $lines);
+ }
+
+ file_put_contents($file, json_encode(array_values($items), JSON_PRETTY_PRINT));
+ return response()->json(['status' => 'ok', 'count' => count($items), 'items' => $items]);
+ }
+
}
diff --git a/resources/css/home.css b/resources/css/home.css
index 3223a44..9977bd6 100644
--- a/resources/css/home.css
+++ b/resources/css/home.css
@@ -38,12 +38,12 @@ p .light {
color: #787878;
}
section h3 {
- color: #3f6d87;
+ color: #454545;
text-decoration: none;
}
a {
font-weight: bold;
- color: #548226;
+ color: #676767;
text-decoration: none;
padding-bottom: .1rem;
border-bottom: 1px dashed gray;
diff --git a/resources/views/do.blade.php b/resources/views/do.blade.php
new file mode 100755
index 0000000..246c522
--- /dev/null
+++ b/resources/views/do.blade.php
@@ -0,0 +1,48 @@
+@extends('template')
+@section('content')
+<main>
+ <section style="background-color: hsl(0, 0%, 72%); padding: 1rem;">
+ <center>
+ <h2>To Do</h2>
+ </center>
+ </section>
+
+ <section>
+ @if(Auth::check() && Auth::user()->isAdmin())
+ <form method="POST" action="/do" style="margin-bottom: 1rem;">
+ @csrf
+ <textarea name="content" rows="3" placeholder="Add a todo item…" style="width: 100%; font-family: monospace; padding: 0.5rem;">{{ old('content') }}</textarea>
+ <div style="margin-top: 0.5rem; display: flex; gap: 0.5rem;">
+ <button type="submit" name="op" value="append">+ Append</button>
+ <button type="submit" name="op" value="overwrite" onclick="return confirm('This will replace the entire list. Continue?')">⤬ Overwrite</button>
+ </div>
+ </form>
+ @endif
+
+ @if(session('status'))
+ <p style="color: green;">{{ session('status') }}</p>
+ @endif
+ </section>
+
+ <section>
+ <h3>Current List</h3>
+ @if(count($items ?? []) === 0)
+ <p style="color: #888;"><em>Nothing here yet.</em></p>
+ @else
+ <ul style="font-family: monospace; line-height: 1.8;">
+ @foreach($items as $i => $item)
+ <li>
+ <form method="POST" action="/do" style="display: inline;">
+ @csrf
+ <input type="hidden" name="op" value="delete">
+ <input type="hidden" name="index" value="{{ $i }}">
+ <button type="submit" style="cursor:pointer; background:none; border:none; color:red;" title="Delete">✕</button>
+ </form>
+ {{ $item }}
+ </li>
+ @endforeach
+ </ul>
+ @endif
+ </section>
+</main>
+@endsection \ No newline at end of file
diff --git a/resources/views/home.blade.php b/resources/views/home.blade.php
index d6ac6ec..4bd4b74 100755
--- a/resources/views/home.blade.php
+++ b/resources/views/home.blade.php
@@ -11,7 +11,6 @@
<p>Welcome</p>
<center> . . . </center>
</section>
-UNDER CONSTRUCTION; APOLOGIES FOR LACKING FUNCTIONALITY.
<section id = "fileupload">
<div class = "widget" >
<p>File upload capability temporarily disabled</p>
@@ -32,6 +31,7 @@ UNDER CONSTRUCTION; APOLOGIES FOR LACKING FUNCTIONALITY.
<br><small>40912129 ( goob )</small>
</a></div>
</secton>
+<!--
<section>
<div class="widget">
<div class="widget-header">
@@ -61,7 +61,7 @@ UNDER CONSTRUCTION; APOLOGIES FOR LACKING FUNCTIONALITY.
</div>
</div>
</section>
-
+-->
<section class = "widget" id = "dunechapterexcerpts" >
<h4>Dune pre-chapter quotes: </h4>
<div id = "quote" hx-get = "/dq" hx-trigger = "load,click" hx-swap = "innerHTML">
diff --git a/resources/views/matrix.blade.php b/resources/views/matrix.blade.php
index b5deb92..95b10c1 100755
--- a/resources/views/matrix.blade.php
+++ b/resources/views/matrix.blade.php
@@ -3,8 +3,8 @@
<main>
<section style="background-color: hsl(0, 0%, 72%); padding: 1rem; ">
<center></center>
- <br><h3><a href = "https://matrix.org/">Matrix Communications System</a></h3>
- <h2>An open network for secure, decentralised communication</h2>
+ <br><h4><a href = "https://matrix.org/">Matrix Communications System</a></h4>
+ <h3>An open network for secure, decentralised communication</h3>
</center>
</section>
<section>
@@ -19,13 +19,13 @@
<h3>What is Matrix?</h3>
<p>
Matrix is an open standard and communication protocol for real-time messaging, voice, and video.
- Think of it like email — but for instant messaging. Just like you can send an email from Gmail to
+ Think of it like email, but for instant messaging. Just like you can send an email from Gmail to
a Yahoo address without either party needing to use the same service, Matrix lets you chat with
anyone on any Matrix server, from your own account which exists on some server.
</p>
<p>
You don't need to trust a corporation with your conversations. There's no single company running
- Matrix — it's a <strong><a href = "https://www.geeksforgeeks.org/system-design/federated-architecture-system-design">federated</a>, <a href = "https://en.wikipedia.org/wiki/Decentralization"></a>decentralized network</a></strong>. Thousands of servers run
+ Matrix. It's a <a href = "https://www.geeksforgeeks.org/system-design/federated-architecture-system-design">federated</a>, <a href = "https://en.wikipedia.org/wiki/Decentralization">decentralized network</a>. Thousands of servers run
independently and talk to each other. My server (<code>belthelziquor.com</code>) is one of them.
</p>
</section>
diff --git a/routes/web.php b/routes/web.php
index d98ed5d..6c44689 100755
--- a/routes/web.php
+++ b/routes/web.php
@@ -144,30 +144,21 @@ Route::get('/newtab', function() {
return view('newtab');
});
-//Route::post('/do', function(Request $req) {
+Route::get('/do', function(){
+ $data = [];
$file = storage_path('app/todo.json');
- $items = file_exists($file) ? json_decode(file_get_contents($file), true) ?? [] : [];
- $op = $req->input('op', 'append');
-
- if ($op === 'overwrite') {
- $lines = array_filter(array_map('trim', explode("\n", $req->input('content', ''))));
- $items = array_values($lines);
- } elseif ($op === 'delete') {
- $index = (int) $req->input('index');
- array_splice($items, $index, 1);
- } else {
- // append (default)
- $lines = array_filter(array_map('trim', explode("\n", $req->input('content', ''))));
- $items = array_merge($items, $lines);
- }
+ $data['items'] = file_exists($file) ? json_decode(file_get_contents($file), true) ?? [] : [];
+ return view('do', $data);
+});
- file_put_contents($file, json_encode(array_values($items), JSON_PRETTY_PRINT));
- return redirect('/do')->with('status', 'List updated.');
-})->middleware('auth');
+Route::post('/do', [SiteController::class, 'updateTodo'])->middleware('auth');
+
+// API-style todo endpoint — token auth, no CSRF needed
+Route::post('/api/do', [SiteController::class, 'updateTodoWithToken'])->middleware('throttle:public');
// Catch-all: only allow specific whitelisted views
Route::get('/{v}', function($v){
- $allowed = ['notes', 'kyanite', 'marked', 'v', '4', 'matrix', 'psql', 'do'];
+ $allowed = ['notes', 'kyanite', 'marked', 'v', '4', 'matrix', 'psql'];
if (!in_array($v, $allowed)) {
abort(404);
}