Design Refresh

This commit is contained in:
Roscoe 2026-01-23 23:16:08 +00:00
commit e7202174f7
Signed by: RoscoeDaWah
SSH key fingerprint: SHA256:Hqn452XQ1ETzUt/FthJu6+OFkS4NBxCv5VQSEvuk7CE
44 changed files with 593 additions and 228 deletions

View file

@ -1,5 +1,10 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Development Server (External)" type="PhpLocalRunConfigurationType" factoryName="PHP Console" path="$PROJECT_DIR$/artisan" scriptParameters="serve --host 0.0.0.0 --port 8000">
<CommandLine>
<envs>
<env name="COLUMNS" value="160" />
</envs>
</CommandLine>
<method v="2" />
</configuration>
</component>

View file

@ -1,5 +1,10 @@
<component name="ProjectRunConfigurationManager">
<configuration default="false" name="Development Server" type="PhpLocalRunConfigurationType" factoryName="PHP Console" path="$PROJECT_DIR$/artisan" scriptParameters="serve">
<CommandLine>
<envs>
<env name="COLUMNS" value="160" />
</envs>
</CommandLine>
<method v="2" />
</configuration>
</component>

View file

@ -0,0 +1,40 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller {
public function showLoginForm() {
return view('auth.login');
}
public function login(Request $request) {
$credentials = $request->validate([
'username' => 'required|string|max:50',
'password' => 'required|string',
]);
if (Auth::attempt($credentials)) {
$request->session()->regenerate();
return redirect()->intended('/');
}
return back()->withErrors([
'username' => 'Invalid credentials',
])->withInput();
}
public function logout(Request $request) {
Auth::logout();
$request->session()->invalidate();
$request->session()->regenerateToken();
return redirect('/');
}
}

View file

@ -4,6 +4,9 @@
use App\Models\BookmarkSite;
use App\Models\BookmarkCategory;
use App\Models\GuestbookEntry;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
use Illuminate\View\View;
class BookmarksController extends Controller
@ -12,4 +15,40 @@ public function show() : View {
$categories = BookmarkCategory::with('sites')->get();
return view('bookmarks', compact('categories'));
}
public function createBookmark() {
$categories = BookmarkCategory::all();
return view('admin.create-bookmark', [
'categories' => $categories
]);
}
public function addBookmark(Request $request): RedirectResponse {
$newEntry = BookmarkSite::create($request);
return redirect()->route('bookmarks');
}
public function destroyBookmark($id): RedirectResponse {
$site = BookmarkSite::findOrFail($id);
$site->delete();
return redirect()->route('bookmarks');
}
public function createCategory() {
return view('admin.create-category');
}
public function addCategory(Request $request): RedirectResponse {
$newEntry = BookmarkCategory::create($request);
return redirect()->route('bookmarks');
}
public function destroyCategory($id): RedirectResponse {
if (BookmarkSite::where('category', $id)->count() <= 0) {
$category = BookmarkCategory::findOrFail($id);
$category->delete();
}
return redirect()->route('bookmarks');
}
}

View file

@ -6,12 +6,13 @@
use Illuminate\Http\Request;
use Illuminate\Http\RedirectResponse;
use Illuminate\Contracts\View\View;
use Illuminate\Support\Facades\Http;
use Illuminate\Validation\ValidationException;
use UAParser\Parser;
class GuestbookController extends Controller {
public function show(): View {
$entries = GuestbookEntry::selectEntries();
$entries = GuestbookEntry::get();
$parser = Parser::create();
return view('guestbook')
@ -27,7 +28,46 @@ public function show(): View {
* @throws ValidationException
*/
public function addEntry(Request $request): RedirectResponse {
GuestbookEntry::insertGuestbookEntry($request);
$newEntry = GuestbookEntry::create($request);
$response = Http::withBasicAuth(config('services.mailjet.key'), config('services.mailjet.secret'))->post('https://api.mailjet.com/v3.1/send', [
'Messages' => [
[
'From' => [
'Email' => 'wah@wah.moe',
'Name' => 'wah dot moe'
],
'To' => [
[
'Email' => 'roscoe@wah.moe',
'Name' => 'Roscoe D. Wah'
]
],
'Subject' => 'New Guestbook Entry!',
'HtmlPart' => '
<style> td { padding: 5px } </style>
<table border="1">
<tr><td><b>Name:</b></td><td>'.htmlentities($newEntry->name).'</td></tr>
<tr><td><b>IP:</b></td><td>'.$newEntry->ip.'</td></tr>
<tr><td><b>Agent:</b></td><td>'.htmlentities($newEntry->agent).'</td></tr>
<tr><td><b>Message:</b></td><td>'.htmlentities($newEntry->message).'</td></tr>
</table>'
]
]
]);
return back()->with('success', 'Entry submitted successfully!');
}
public function destroy($id): RedirectResponse {
$entry = GuestbookEntry::findOrFail($id);
$entry->delete();
return redirect()->route('guestbook');
}
public function flag($id): RedirectResponse {
$entry = GuestbookEntry::where("id", $id)->get()->first;
$entry->update([
"flagged" => !$entry->flagged,
]);
return redirect()->route('guestbook');
}
}

View file

@ -4,18 +4,29 @@
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Http\Request;
class BookmarkCategory extends Model
{
use HasFactory;
protected $table = "bookmark__categories";
protected $fillable = ['name'];
protected $fillable = ['name', 'shuffled'];
protected $casts = ['shuffled' => 'boolean'];
public function sites() {
return $this->hasMany(BookmarkSite::class, 'category');
}
public static function insertBookmarkCategory(string $name) {
public static function create(Request $request): BookmarkCategory {
$newCategory = new BookmarkCategory();
$newCategory->name = $request->get('name');
$newCategory->shuffled = $request->has('shuffled');
$newCategory->save();
return $newCategory;
}
public static function insertBookmarkCategory(string $name): void {
$newBookmarkCategory = new BookmarkCategory;
$newBookmarkCategory->name = $name;
$newBookmarkCategory->save();
@ -24,13 +35,4 @@ public static function selectBookmarks(int $id) {
$bookmarks = BookmarkSite::where('category', '=', $id)->firstOrFail();
return $bookmarks;
}
public static function importBookmarkCategory(array $data) {
foreach ($data as $category) {
$newBookmarkCategory = new BookmarkCategory;
$newBookmarkCategory->name = $category['name'];
$newBookmarkCategory->priority = intval($category['priority']);
$newBookmarkCategory->save();
}
}
}

View file

@ -4,16 +4,31 @@
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Http\RedirectResponse;
use Illuminate\Http\Request;
class BookmarkSite extends Model {
use HasFactory;
protected $table = "bookmark__sites";
protected $fillable = ['name', 'description', 'url', 'category'];
public function category() {
public function category(): BelongsTo {
return $this->belongsTo(BookmarkCategory::class, 'category');
}
public static function insertBookmark(string $name, string $url, int $category) {
public static function create(Request $request): BookmarkSite {
$category = BookmarkCategory::where('id', $request->get('category'))->firstOrFail();
$newSite = new BookmarkSite;
$newSite->name = $request->get('name');
$newSite->url = $request->get('url');
$newSite->description = $request->get('description');
$newSite->category = $category->id;
$newSite->save();
return $newSite;
}
public static function insertBookmark(string $name, string $url, int $category): void {
$category = BookmarkCategory::where('id', $category)->firstOrFail();
$newBookmark = new BookmarkSite;
$newBookmark->name = $name;
@ -21,15 +36,4 @@ public static function insertBookmark(string $name, string $url, int $category)
$newBookmark->category = $category->id;
$newBookmark->save();
}
public static function importBookmark(array $data) {
foreach ($data as $site) {
$newBookmark = new BookmarkSite;
$newBookmark->name = $site['name'];
$newBookmark->description = $site['description'];
$newBookmark->url = $site['url'];
$newBookmark->category = $site['category_id'];
$newBookmark->save();
}
}
}

View file

@ -5,46 +5,37 @@
use Illuminate\Http\Request;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\Auth;
class GuestbookEntry extends Model
{
use HasFactory;
protected $table = "guestbook__entries";
protected $fillable = ['name', 'message'];
protected $fillable = ['name', 'message',
'flagged'
];
/**
* Creates a new guestbook entry.
*
* @param Request $request The HTTP POST request
* @return void
* @return GuestbookEntry
*/
public static function insertGuestbookEntry(Request $request) {
public static function create(Request $request): GuestbookEntry {
$newEntry = new GuestbookEntry;
$newEntry->name = $request->get('name');
$newEntry->message = $request->get('message');
$newEntry->ip = $request->ip();
$newEntry->agent = $request->userAgent();
$newEntry->legacy_flagged = isLegacy();
$newEntry->flagged = true;
$newEntry->save();
return $newEntry;
}
public static function selectEntries() {
$entries = GuestbookEntry::where("legacy_flagged", false)->orderBy('created_at', 'desc')->get();
return $entries;
}
public static function importGuestbookEntry(array $data) {
foreach ($data as $entry) {
$dt = new \DateTime('@' . $entry['timestamp']);
$newEntry = new GuestbookEntry;
$newEntry->name = $entry['name'];
$newEntry->ip = $entry['ip_address'];
$newEntry->agent = $entry['agent'];
$newEntry->admin = $entry['site_owner'];
$newEntry->message = $entry['message'];
$newEntry->created_at = $dt;
$newEntry->updated_at = $dt;
$newEntry->save();
public static function get() {
if (Auth::check()) {
return GuestbookEntry::select()->orderBy('created_at', 'desc')->get();
}
return GuestbookEntry::where("flagged", false)->orderBy('created_at', 'desc')->get();
}
}

42
app/Models/User.php Normal file
View file

@ -0,0 +1,42 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Foundation\Auth\User as Authenticatable;
use Illuminate\Notifications\Notifiable;
class User extends Authenticatable {
use HasFactory, Notifiable;
/**
* The attributes that are mass assignable.
*
* @var array<int, string>
*/
protected $fillable = [
'username',
'email',
'password',
];
/**
* The attributes that should be hidden for serialization.
*
* @var array<int, string>
*/
protected $hidden = [
'password',
'remember_token',
];
/**
* The attributes that should be cast.
*
* @var array<string, string>
*/
protected $casts = [
'email_verified_at' => 'datetime',
'password' => 'hashed',
];
}

View file

@ -15,7 +15,8 @@
"scrivo/highlight.php": "v9.18.1.10",
"spatie/laravel-honeypot": "^4.3",
"spatie/laravel-html": "^3.4",
"ua-parser/uap-php": "^3.9.14"
"ua-parser/uap-php": "^3.9.14",
"ext-pdo": "*"
},
"require-dev": {
"fakerphp/faker": "^1.9.1",

View file

@ -5,7 +5,7 @@
return [
'name' => env('APP_NAME', 'wah.moe'),
'version' => '2026.01.09',
'version' => '2026.01.23',
'env' => env('APP_ENV', 'production'),
'debug' => (bool)env('APP_DEBUG', false),
'url' => env('APP_URL', 'http://localhost'),

View file

@ -55,40 +55,12 @@
'lock_path' => storage_path('framework/cache/data'),
],
'memcached' => [
'driver' => 'memcached',
'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
'sasl' => [
env('MEMCACHED_USERNAME'),
env('MEMCACHED_PASSWORD'),
],
'options' => [
// Memcached::OPT_CONNECT_TIMEOUT => 2000,
],
'servers' => [
[
'host' => env('MEMCACHED_HOST', '127.0.0.1'),
'port' => env('MEMCACHED_PORT', 11211),
'weight' => 100,
],
],
],
'redis' => [
'driver' => 'redis',
'connection' => 'cache',
'lock_connection' => 'default',
],
'dynamodb' => [
'driver' => 'dynamodb',
'key' => env('AWS_ACCESS_KEY_ID'),
'secret' => env('AWS_SECRET_ACCESS_KEY'),
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
'table' => env('DYNAMODB_CACHE_TABLE', 'cache'),
'endpoint' => env('DYNAMODB_ENDPOINT'),
],
'octane' => [
'driver' => 'octane',
],

View file

@ -1,7 +1,5 @@
<?php
use Illuminate\Support\Str;
return [
'default' => env('DB_CONNECTION', 'mysql'),

View file

@ -17,5 +17,9 @@
'lastfm' => [
'key' => env('LASTFM_KEY'),
'user' => env('LASTFM_USER'),
],
'mailjet' => [
'key' => env('MAILJET_API'),
'secret' => env('MAILJET_SECRET'),
]
];

View file

@ -2,20 +2,19 @@
namespace Database\Factories;
use App\Models\BookmarkCategory;
use Illuminate\Database\Eloquent\Factories\Factory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\BookmarkCategory>
* @extends Factory<BookmarkCategory>
*/
class BookmarkCategoryFactory extends Factory
{
class BookmarkCategoryFactory extends Factory {
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
public function definition(): array {
return [
'name' => $this->faker->word,
];

View file

@ -2,21 +2,20 @@
namespace Database\Factories;
use App\Models\BookmarkSite;
use Illuminate\Database\Eloquent\Factories\Factory;
use App\Models\BookmarkCategory;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\BookmarkSite>
* @extends Factory<BookmarkSite>
*/
class BookmarkSiteFactory extends Factory
{
class BookmarkSiteFactory extends Factory {
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array
{
public function definition(): array {
return [
'name' => $this->faker->name,
'description' => $this->faker->sentence,

View file

@ -0,0 +1,35 @@
<?php
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
/**
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\User>
*/
class UserFactory extends Factory {
/**
* Define the model's default state.
*
* @return array<string, mixed>
*/
public function definition(): array {
return [
'username' => fake()->userName(),
'email' => fake()->unique()->safeEmail(),
'email_verified_at' => now(),
'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
'remember_token' => Str::random(10),
];
}
/**
* Indicate that the model's email address should be unverified.
*/
public function unverified(): static {
return $this->state(fn(array $attributes) => [
'email_verified_at' => null,
]);
}
}

View file

@ -14,7 +14,7 @@ public function up(): void
Schema::create('bookmark__categories', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->unsignedBigInteger('priority')->nullable();
$table->boolean('shuffled');
$table->timestamps();
});
}

View file

@ -4,13 +4,11 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
public function up(): void {
Schema::create('bookmark__sites', function (Blueprint $table) {
$table->id();
$table->string('name');
@ -28,8 +26,7 @@ public function up(): void
/**
* Reverse the migrations.
*/
public function down(): void
{
public function down(): void {
Schema::dropIfExists('bookmarks');
}
};

View file

@ -4,20 +4,18 @@
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void
{
public function up(): void {
Schema::create('guestbook__entries', function (Blueprint $table) {
$table->id();
$table->string('name');
$table->string('ip');
$table->string('agent');
$table->longText('message');
$table->boolean('admin');
$table->boolean('flagged');
$table->timestamps();
});
}
@ -25,8 +23,7 @@ public function up(): void
/**
* Reverse the migrations.
*/
public function down(): void
{
public function down(): void {
Schema::dropIfExists('guestbook__entries');
}
};

View file

@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration {
/**
* Run the migrations.
*/
public function up(): void {
Schema::create('users', function (Blueprint $table) {
$table->id();
$table->string('username');
$table->string('email')->unique();
$table->timestamp('email_verified_at')->nullable();
$table->string('password');
$table->rememberToken();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*/
public function down(): void {
Schema::dropIfExists('users');
}
};

View file

@ -1,30 +0,0 @@
<?php
namespace Database\Seeders;
use App\Models\BookmarkCategory;
use App\Models\BookmarkSite;
use Illuminate\Database\Seeder;
class BookmarkCategoriesTableSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void {
// BookmarkCategory::factory()->count(5)->create()->each(function ($category) {
// $category->sites()->saveMany(BookmarkSite::factory()->count(3)->make());
// });
$category = new BookmarkCategory([
'name' => 'cool people',
]);
$category->save();
$site = new BookmarkSite([
'name' => 'campos',
'description' => 'Cool brazilian dude, does programming and stuff',
'url' => 'https://campos02.me/',
'category' => 1,
]);
$site->save();
}
}

View file

@ -141,16 +141,16 @@ a:hover {
}
div.page-container {
width: 800px;
width: 950px;
margin: 5px auto;
}
div.page-container > div {
background-color: var(--background);
filter: var(--shadow);
padding: 10px;
border: var(--border);
margin-bottom: 20px;
}
div.page-container > hr {
padding: 3px 0;
}
div.page-container > div:last-child {
@ -166,6 +166,10 @@ header {
align-items: center;
}
header div:nth-child(2) {
padding-left: 14px;
}
header img {
image-rendering: pixelated;
}
@ -190,20 +194,28 @@ main>div::after {
clear: both;
}
div#footer {
footer,
div.footer-footer div {
text-align: center;
}
div.footer-footer {
display: grid;
grid-template-columns: auto 1fr;
grid-template-columns: 1fr 1fr 1fr;
grid-template-rows: 1fr;
grid-column-gap: 0;
grid-row-gap: 0;
align-items: center;
}
div#footer div:last-child {
div.footer-footer div:first-child {
text-align: left;
}
div.footer-footer div:last-child {
text-align: right;
}
div#footer div:last-child img {
footer img {
image-rendering: pixelated;
margin: 0;
padding: 0;
@ -240,9 +252,9 @@ div.wah img {
}
/** Guestbook **/
table.form input,
table.form textarea,
table.form button {
form input,
form textarea,
form button {
background-color: var(--background);
border: var(--border);
filter: var(--shadow-small);
@ -272,10 +284,19 @@ div.gb-entry {
border: var(--border);
filter: var(--shadow-small);
background-color: var(--background);
width: 75%;
padding: 10px;
}
div.gb-entry form {
display: inline;
}
div.gb-entry-flagged {
border-color: red;
filter: drop-shadow(3px 3px hsla(0, 100%, 50%, 0.4));
}
/** Music **/
table.music-top10 {
border: var(--border);

View file

@ -1,13 +1,13 @@
html { color-scheme: light; }
body { color: #2a271c; background-color: #f2efbd; font-family: serif; }
body { color: #1d232b; background-color: #bfd5f2; font-family: serif; }
h1, h2, h4, ul, p { margin: 0; }
h1 { font-weight: normal; }
h4 { margin-bottom: 5px; }
ul { padding: 5px 30px; }
a { color: hsl(183, 93%, 27%); text-decoration: underline dotted; }
a:hover { color: hsl(183, 93%, 15%); text-decoration: underline solid; }
a { color: #293647; text-decoration: underline dotted; }
a:hover { color: #1c2531; text-decoration: underline solid; }
code { font-family: monospace; }
code.addr { font-size: 24px; }
table { border: #f27405 2px solid; background-color: #f2efbd; filter: drop-shadow(3px 3px hsla(11, 96%, 43%, 0.4)); }
img { border: #f27405 2px solid; filter: drop-shadow(3px 3px hsla(11, 96%, 43%, 0.4)); }
hr { border: none; border-bottom: 2px solid #f27405; }
table { border: #056bf0 2px solid; background-color: #bfd5f2; filter: drop-shadow(3px 3px hsla(214, 96%, 43%, 0.4)); }
img { border: #056bf0 2px solid; filter: drop-shadow(3px 3px hsla(214, 96%, 43%, 0.4)); }
hr { border: none; border-bottom: 2px solid #056bf0; }

Binary file not shown.

After

Width:  |  Height:  |  Size: 850 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

BIN
public/images/login.jpg Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 261 KiB

View file

@ -0,0 +1,40 @@
<style>
body {
background-image: url('/images/login.jpg');
background-size: cover;
}
input, button { border: black 1px solid }
</style>
<p><font color="#FF0000">TEMPORARY FORM REPLACE THIS BEFORE PUSHING TO PROD</font></p>
<form method="POST" action="{{ route('bookmarks.create-bookmark') }}">
@csrf
<table>
<tr>
<td><label for="name"><strong>Name:</strong></label></td>
<td><input name="name" type="text" id="name"></td>
</tr>
<tr>
<td><label for="url"><strong>URL:</strong></label>/td></td>
<td><input name="url" type="text" id="url"></td>
</tr>
<tr>
<td><label for="description"><strong>Description:</strong></label></td>
<td><input name="description" type="text" id="description"></td>
</tr>
<tr>
<td><label for="category"><strong>Category:</strong></label></td>
<td>
<select id="category" name="category">
<option value="" disabled>-- Select Category --</option>
@foreach ($categories as $category)
<option value="{{$category->id}}"> {{$category->name}} </option>
@endforeach
</select>
</td>
</tr>
</table>
<button type="submit">Submit</button>
</form>
<a href="{{ route('bookmarks') }}"><img src="/images/buttons/elwiwi.png"> el wiwi</a>

View file

@ -0,0 +1,25 @@
<style>
body {
background-image: url('/images/login.jpg');
background-size: cover;
}
input, button { border: black 1px solid }
</style>
<p><font color="#FF0000">TEMPORARY FORM REPLACE THIS BEFORE PUSHING TO PROD</font></p>
<form method="POST" action="{{ route('bookmarks.create-category') }}">
@csrf
<table>
<tr>
<td><label for="name"><strong>Name:</strong></label></td>
<td><input name="name" type="text" id="name"></td>
</tr>
<tr>
<td><label for="shuffled"><strong>Shuffle?</strong></label></td>
<td><input type="checkbox" name="shuffled" class="switch-input" value="1" {{ old('shuffled') ? 'checked="checked"' : '' }}/></td>
</tr>
</table>
<button type="submit">Submit</button>
</form>
<a href="{{ route('bookmarks') }}"><img src="/images/buttons/elwiwi.png"> el wiwi</a>

View file

@ -0,0 +1,34 @@
<style>
body {
background-image: url('/images/login.jpg');
background-size: cover;
}
input, button { border: black 1px solid }
</style>
<p><font color="#FF0000">TEMPORARY LOGIN REPLACE THIS BEFORE PUSHING TO PROD</font></p>
<h1>what your login</h1>
<p>twust him with youw wogin infowmation</p>
<form action="{{ route('login') }}" method="post" class="form login-form">
<table>
@csrf
<tr>
<td><label for="username">usewnyame</label></td>
<td><input type="text" name="username" placeholder="who r u" id="username" value="{{ old('username') }}" required></td>
</tr>
<tr>
<td><label for="password">passwowd</label></td>
<td><input type="password" name="password" placeholder="im not looking i swear" id="password" required></td>
</tr>
</table>
@if ($errors->any())
<div>
<h2>wuh oh</h2>
@foreach ($errors->all() as $error)
<p>{{ $error }}</p>
@endforeach
</div>
@endif
<button type="submit">wemme in</button>
<p class="register-link">don't have an account? <a href="/">explode immediately</a></p>
</form>

View file

@ -1,9 +1,21 @@
<x-layout>
<x-slot:title>Bookmarks</x-slot:title>
@if(auth()->check())
<a href="{{ route('bookmarks.create-category') }}">new category pretty please</a><br>
<a href="{{ route('bookmarks.create-bookmark') }}">new bookmark pretty please</a>
@endif
@foreach($categories as $category)
<div class="bookmark-category">
<h2>{{ $category->name }}</h2>
@if($category->id == 1)
@if(Auth::check())
<hr>
<form action="{{ route('bookmarks.destroy-category',$category->id) }}" method="POST">
@csrf
@method('DELETE')
<button type="submit">Delete</button>
</form>
@endif
@if($category->shuffled)
<p><em>(These are shuffled every load)</em></p>
@php
$sites = $category->sites->shuffle();
@ -16,7 +28,17 @@
<hr>
<ul>
@foreach($sites as $site)
<li><a href="{{ $site->url }}"><font color="#000000">{{ $site->name }}</font></a> - {{ $site->description }}</li>
<li>
<a href="{{ $site->url }}"><font color="#000000">{{ $site->name }}</font></a> - {{ $site->description }}
@if(Auth::check())
<hr>
<form action="{{ route('bookmarks.destroy-bookmark',$site->id) }}" method="POST">
@csrf
@method('DELETE')
<button type="submit">Delete</button>
</form>
@endif
</li>
@endforeach
</ul>
</div>

View file

@ -24,10 +24,9 @@
<img src="{{ asset('/images/progress.svg') }}" width="120" height="120" alt="progressive pride flag">
</a>
<div class="page-container">
<div id="header">
<header>
<div>
<img class="logo_paw" src="{{ asset('/images/logo-v2.png') }}" width="65" alt="A pixel art depiction of a paw, in three alternating shades of blue.">
<img class="logo_paw" src="{{ asset('/images/logo-v2.png') }}" width="84" alt="A pixel art depiction of a paw, in three alternating shades of blue.">
</div>
<div>
<h1>wah!</h1>
@ -37,40 +36,49 @@
<x-navigation></x-navigation>
</div>
</header>
</div>
<div id="content">
<hr>
<main>
{{ $slot }}
<div class="clear"></div>
</main>
</div>
<div>
<hr>
<footer>
<div id="footer">
<div>
<span>
&copy; RoscoeDaWah 2021-{{ date('Y') }}<br>
v{{ config('app.version') }}, <a href="https://git.frzn.dev/RoscoeDaWah/wah.moe/releases/latest">Source</a><br>
<a href="https://webring.julimiro.eu/api/previous/wah.moe">&lt;</a> <a href="https://webring.julimiro.eu/">the basename ring</a> <a href="https://webring.julimiro.eu/api/next/wah.moe">&gt;</a>
</span>
</div>
<div>
<img src="{{ URL::asset('images/buttons/wah.png') }}" alt="wah! (dot moe)">
<a href="https://aliceisvery.gay/"><img src="{{ URL::asset('images/buttons/cnfunknown.gif') }}" alt="ConfusionUnknown"></a>
<a href="https://julimiro.eu/"><img src="{{ URL::asset('images/buttons/juli.gif') }}" alt="Julimiro.eu"></a>
<a href="https://x86.isafox.gay/"><img src="{{ URL::asset('images/buttons/x86.gif') }}" alt="x86Overflow"></a>
<a href="https://thinliquid.dev/"><img src="{{ URL::asset('images/buttons/thnlqd.png') }}" alt="thinliquid"></a>
<a href="https://dimden.dev/"><img src="https://dimden.dev/services/images/88x31.gif" alt="Dimden's website"></a><br>
<a href="https://lunaisafox.xyz/"><img src="{{ URL::asset('images/buttons/x86.gif') }}" alt="x86Overflow"></a>
<a href="https://lim95.com/gggg"><img src="{{ URL::asset('images/buttons/gggg.png') }}" alt="green guy goes grappling"></a>
<a href="https://dimden.dev/"><img src="https://dimden.dev/services/images/88x31.gif" alt="Dimden's website"></a>
<a href="https://un1x.hs.vc/"><img src="{{ URL::asset('images/buttons/violet.png') }}" alt="Violet"></a>
<a href="https://sillydomain.name/"><img src="{{ URL::asset('images/buttons/benjae.png') }}" alt="ben"></a>
<a href="https://doskel.net/DSKLwiki"><img src="{{ URL::asset('images/buttons/doskel2.png') }}" alt="doskel"></a>
<a href="https://synth.download"><img src="https://synth.download/assets/buttons/sneexy.svg" alt="Sneexy"></a><br>
<img src="{{ URL::asset('images/buttons/servfail.png') }}" alt="Servfail DNS">
<a href="https://linux.org/"><img src="{{ URL::asset('images/buttons/linuxnow.gif') }}" alt="Linux NOW!"></a>
<img src="{{ URL::asset('images/buttons/paws-aliased.png') }}" alt="Made with my own two paws">
<img src="{{ URL::asset('images/buttons/transrights.gif') }}" alt="Trans Rights NOW!">
<a href="https://www.vim.org/"><img src="{{ URL::asset('images/buttons/vim.gif') }}" alt="Vim"></a>
<img src="{{ URL::asset('images/buttons/aliasing.png') }}" alt="I Heart Aliasing">
<img src="{{ URL::asset('images/buttons/csshard.gif') }}" alt="CSS is hard">
<img src="{{ URL::asset('images/buttons/krisbtn.gif') }}" alt="Kris where tf are we">
<a href="https://crosstalk.im/"><img src="{{ URL::asset('images/buttons/yahoo.gif') }}" alt="Send instant messages on Yahoo!"></a>
<img src="{{ URL::asset('images/buttons/notcompliant.gif') }}" alt="HTML 4.0 Non-compliant">
<div class="footer-footer">
<div>
<span>
&copy; RoscoeDaWah 2021-{{ date('Y') }}
</span>
</div>
<div>
<a href="https://webring.julimiro.eu/api/previous/wah.moe">&lt;</a> <a href="https://webring.julimiro.eu/">the basename ring</a> <a href="https://webring.julimiro.eu/api/next/wah.moe">&gt;</a>
</div>
<div>
<a href="https://git.frzn.dev/RoscoeDaWah/wah.moe/releases/tag/v{{ config('app.version') }}">v{{ config('app.version') }}</a>, served by {{ gethostname() }}
</div>
</div>
</div>
</footer>
</div>
</div>
</body>
</html>

View file

@ -7,4 +7,7 @@
<a href="/guestbook">guestbook</a> |
<a href="/music">music</a> |
<a href="/pandamonium">pandamonium</a>
@if(Auth::check())
| <a href="{{ route('logout') }}">logout</a>
@endif
</nav>

View file

@ -103,7 +103,7 @@
@php
$user_agent = $parser->parse($entry->agent);
@endphp
<div class="gb-entry">
<div class="gb-entry{{ $entry->flagged ? " gb-entry-flagged" : "" }}">
Submitted by <strong>{{ $entry->name }}</strong>
on <strong>{{ $entry->created_at->format('Y-m-d') }}</strong>
at <strong>{{ $entry->created_at->format('h:i:s A (e)') }}</strong>
@ -120,6 +120,21 @@
on <strong>{{ $user_agent->os->toString() }}</strong></address>
@endif
@endif
@if(Auth::check())
<hr>
@if($entry->flagged)
<form action="{{ route('guestbook.flag',$entry->id) }}" method="GET">
@csrf
<button type="submit">Remove Flag</button>
</form>
&nbsp;
@endif
<form action="{{ route('guestbook.destroy',$entry->id) }}" method="POST">
@csrf
@method('DELETE')
<button type="submit">Delete</button>
</form>
@endif
</div>
<br>
@endforeach

View file

@ -7,9 +7,6 @@
<p>Hi! This is my personal homepage on the <strong>W</strong>orld <strong>W</strong>ide
<strong>W</strong>eb.
</p>
@if(!isLegacy())
<br>
@endif
<h3>Some quick facts about me:</h3>
<ul>
<li>{{ $age }} y/o, he/him, British</li>
@ -20,12 +17,9 @@
Minecraft, Stardew Valley, N++ and Starbound</li>
<li><a href="http://wxqa.com/"><font color="#000000">CWOP</font></a> member</li>
</ul>
@if(!isLegacy())
<br>
@endif
<h3>Interests:</h3>
<ul>
<li><strong>Tech Theatre</strong> - Lighting, Stage Management, etc.</li>
<li><strong>Tech Theatre</strong> - Lighting, Sound, etc.</li>
<li><strong>Programming</strong> - HTML, CSS, JavaScript, C#, Java, PHP, Ruby, Python (<a
href="https://github.com/RoscoeDaWah"><font color="#000000">GitHub</font></a>)</li>
<li><strong>Photography</strong> - <a href="https://www.flickr.com/photos/roscoedawah/"><font color="#000000">Flickr</font></a></li>

View file

@ -1,10 +1,12 @@
<?php
use App\Http\Controllers\Auth\LoginController;
use App\Http\Controllers\BookmarksController;
use App\Http\Controllers\GuestbookController;
use App\Http\Controllers\HomeController;
use App\Http\Controllers\MusicController;
use App\Http\Controllers\RoscoLekoController;
use GuzzleHttp\Client as GuzzleClient;
use Illuminate\Support\Facades\Route;
/*
@ -19,26 +21,58 @@
*/
Route::get('/', [HomeController::class, 'show']);
Route::get('/bookmarks', [BookmarksController::class, 'show']);
Route::get('/guestbook', [GuestbookController::class, 'show']);
Route::get('/bookmarks', [BookmarksController::class, 'show'])
->name('bookmarks');
Route::get('/music', [MusicController::class, 'show']);
Route::get('/pandamonium', [RoscoLekoController::class, 'show']);
Route::get('/guestbook', [GuestbookController::class, 'show']);
Route::post('/guestbook', [GuestbookController::class, 'addEntry'])
->name('guestbook')
->middleware('validator')
->middleware('rate_limit');
Route::get('/proxy/wah/{image}', function (string $image) {
$client = new \GuzzleHttp\Client();
Route::middleware('auth')->group(function () {
Route::get('/bookmarks/bookmark/new', [BookmarksController::class, 'createBookmark'])
->name('bookmarks.create-bookmark');
Route::post('/bookmarks/bookmark/new', [BookmarksController::class, 'addBookmark']);
Route::delete('/bookmarks/bookmark/{id}', [BookmarksController::class, 'destroyBookmark'])
->name('bookmarks.destroy-bookmark');
Route::get('/bookmarks/category/new', [BookmarksController::class, 'createCategory'])
->name('bookmarks.create-category');
Route::post('/bookmarks/category/new', [BookmarksController::class, 'addCategory']);
Route::delete('/bookmarks/category/{id}', [BookmarksController::class, 'destroyCategory'])
->name('bookmarks.destroy-category');
Route::delete('/guestbook/{id}', [GuestbookController::class, 'destroy'])
->name('guestbook.destroy');
Route::get('/guestbook/{id}/flag', [GuestbookController::class, 'flag'])
->name('guestbook.flag');
});
/* Authentication */
Route::prefix('auth')->group(function() {
Route::get('login', [LoginController::class, 'showLoginForm']);
Route::post('login', [LoginController::class, 'login'])->name('login');
Route::get('logout', [LoginController::class, 'logout'])->name('logout');
});
/* Legacy Proxies */
Route::prefix('proxy')->group(function () {
Route::get('/wah/{image}', function (string $image) {
$client = new GuzzleClient();
$response = $client->request('GET', 'https://api.tinyfox.dev/hourly/wahs/'.$image);
return response($response->getBody())
->header('Content-Type', $response->getHeader('Content-Type'));
});
Route::get('/proxy/lastfm/{image}', function (string $image) {
$client = new \GuzzleHttp\Client();
Route::get('/lastfm/{image}', function (string $image) {
$client = new GuzzleClient();
$response = $client->request('GET', 'https://lastfm.freetls.fastly.net/i/u/174s/'.$image);
return response($response->getBody())
->header('Content-Type', $response->getHeader('Content-Type'));
});
});