Compare commits
8 Commits
b2dd20a624
...
1c410ce074
Author | SHA1 | Date | |
---|---|---|---|
1c410ce074 | |||
a0f116c7a3 | |||
fb18db918a | |||
b12889089b | |||
814f0c8127 | |||
e84a55bd9a | |||
8874e011f9 | |||
2f7f84d896 |
@ -15,7 +15,7 @@ class BookmarkController extends Controller
|
|||||||
{
|
{
|
||||||
return view(
|
return view(
|
||||||
'bookmarks.index', [
|
'bookmarks.index', [
|
||||||
'bookmarks' => Bookmark::paginate(20),
|
'bookmarks' => Bookmark::orderByDesc('created_at')->paginate(20),
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -25,7 +25,7 @@ class BookmarkController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function create()
|
public function create()
|
||||||
{
|
{
|
||||||
//
|
return view('bookmarks.edit', ['bookmark' => null]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -33,7 +33,19 @@ class BookmarkController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function store(Request $request)
|
public function store(Request $request)
|
||||||
{
|
{
|
||||||
//
|
$bookmark = new Bookmark;
|
||||||
|
$bookmark->title = $request->post('title');
|
||||||
|
$bookmark->description = $request->post('description', '');
|
||||||
|
$bookmark->href = $request->post('href');
|
||||||
|
$bookmark->save();
|
||||||
|
|
||||||
|
$bookmark->syncTagsFromString($request->post('tags', ''));
|
||||||
|
|
||||||
|
return redirect()->action(
|
||||||
|
[self::class, "show"], [
|
||||||
|
"bookmark" => $bookmark,
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -55,7 +67,6 @@ class BookmarkController extends Controller
|
|||||||
{
|
{
|
||||||
return view(
|
return view(
|
||||||
'bookmarks.edit', [
|
'bookmarks.edit', [
|
||||||
'edit' => true,
|
|
||||||
'bookmark' => $bookmark,
|
'bookmark' => $bookmark,
|
||||||
]
|
]
|
||||||
);
|
);
|
||||||
@ -71,16 +82,7 @@ class BookmarkController extends Controller
|
|||||||
$bookmark->href = $request->post('href');
|
$bookmark->href = $request->post('href');
|
||||||
$bookmark->save();
|
$bookmark->save();
|
||||||
|
|
||||||
$tags_input = trim($request->post('tags', ''));
|
$bookmark->syncTagsFromString($request->post('tags', ''));
|
||||||
$tags_input = preg_split('/\s+/', $tags_input);
|
|
||||||
|
|
||||||
$tags = [];
|
|
||||||
foreach ($tags_input as $tag_input) {
|
|
||||||
$tag = Tag::firstOrCreate(['name' => $tag_input]);
|
|
||||||
$tags[$tag->id] = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
$bookmark->tags()->sync(array_keys($tags));
|
|
||||||
|
|
||||||
return redirect()->action(
|
return redirect()->action(
|
||||||
[self::class, "show"], [
|
[self::class, "show"], [
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
namespace App\Http\Controllers;
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Bookmark;
|
||||||
use App\Models\Tag;
|
use App\Models\Tag;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
@ -36,7 +37,13 @@ class TagController extends Controller
|
|||||||
*/
|
*/
|
||||||
public function show(Tag $tag)
|
public function show(Tag $tag)
|
||||||
{
|
{
|
||||||
return view('tag.show', [ 'tag' => $tag, ]);
|
return view(
|
||||||
|
'tag.show', [
|
||||||
|
'tag' => $tag,
|
||||||
|
'tag_count' => $tag->bookmarks()->count(),
|
||||||
|
'bookmarks' => $tag->bookmarks()->latest()->paginate(20),
|
||||||
|
]
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -13,6 +13,22 @@ class Bookmark extends Model
|
|||||||
|
|
||||||
protected $table = 'bookmarks';
|
protected $table = 'bookmarks';
|
||||||
|
|
||||||
|
protected $with = ['tags'];
|
||||||
|
|
||||||
|
public function syncTagsFromString(string $tags_string): array
|
||||||
|
{
|
||||||
|
$tags_input = trim($tags_string);
|
||||||
|
$tags_input = preg_split('/\s+/', $tags_input);
|
||||||
|
|
||||||
|
$tags = [];
|
||||||
|
foreach ($tags_input as $tag_input) {
|
||||||
|
$tag = Tag::firstOrCreate(['name' => $tag_input]);
|
||||||
|
$tags[$tag->id] = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $this->tags()->sync(array_keys($tags));
|
||||||
|
}
|
||||||
|
|
||||||
public function tags(): BelongsToMany
|
public function tags(): BelongsToMany
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(Tag::class);
|
return $this->belongsToMany(Tag::class);
|
||||||
|
@ -10,8 +10,6 @@ class BookmarkTag extends Pivot
|
|||||||
{
|
{
|
||||||
use HasFactory;
|
use HasFactory;
|
||||||
|
|
||||||
protected $table = 'bookmarks_tags';
|
|
||||||
|
|
||||||
public function parent()
|
public function parent()
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Bookmark::class, 'bookmark_id');
|
return $this->belongsTo(Bookmark::class, 'bookmark_id');
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
use Illuminate\Database\Migrations\Migration;
|
||||||
|
use Illuminate\Database\Schema\Blueprint;
|
||||||
|
use Illuminate\Support\Facades\Schema;
|
||||||
|
|
||||||
|
return new class extends Migration
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Get the migration connection name.
|
||||||
|
*/
|
||||||
|
public function getConnection(): ?string
|
||||||
|
{
|
||||||
|
return config('telescope.storage.database.connection');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Run the migrations.
|
||||||
|
*/
|
||||||
|
public function up(): void
|
||||||
|
{
|
||||||
|
$schema = Schema::connection($this->getConnection());
|
||||||
|
|
||||||
|
$schema->create('telescope_entries', function (Blueprint $table) {
|
||||||
|
$table->bigIncrements('sequence');
|
||||||
|
$table->uuid('uuid');
|
||||||
|
$table->uuid('batch_id');
|
||||||
|
$table->string('family_hash')->nullable();
|
||||||
|
$table->boolean('should_display_on_index')->default(true);
|
||||||
|
$table->string('type', 20);
|
||||||
|
$table->longText('content');
|
||||||
|
$table->dateTime('created_at')->nullable();
|
||||||
|
|
||||||
|
$table->unique('uuid');
|
||||||
|
$table->index('batch_id');
|
||||||
|
$table->index('family_hash');
|
||||||
|
$table->index('created_at');
|
||||||
|
$table->index(['type', 'should_display_on_index']);
|
||||||
|
});
|
||||||
|
|
||||||
|
$schema->create('telescope_entries_tags', function (Blueprint $table) {
|
||||||
|
$table->uuid('entry_uuid');
|
||||||
|
$table->string('tag');
|
||||||
|
|
||||||
|
$table->primary(['entry_uuid', 'tag']);
|
||||||
|
$table->index('tag');
|
||||||
|
|
||||||
|
$table->foreign('entry_uuid')
|
||||||
|
->references('uuid')
|
||||||
|
->on('telescope_entries')
|
||||||
|
->onDelete('cascade');
|
||||||
|
});
|
||||||
|
|
||||||
|
$schema->create('telescope_monitoring', function (Blueprint $table) {
|
||||||
|
$table->string('tag')->primary();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
$schema = Schema::connection($this->getConnection());
|
||||||
|
|
||||||
|
$schema->dropIfExists('telescope_entries_tags');
|
||||||
|
$schema->dropIfExists('telescope_entries');
|
||||||
|
$schema->dropIfExists('telescope_monitoring');
|
||||||
|
}
|
||||||
|
};
|
@ -12,11 +12,13 @@ body {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI Adjusted", "Segoe UI", "Liberation Sans", sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI Adjusted", "Segoe UI", "Liberation Sans", sans-serif;
|
||||||
background-color: #335C67;
|
background-color: #335C67;
|
||||||
|
color: #fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
@import 'components/bookmark';
|
@import 'components/bookmark';
|
||||||
@import 'components/pagination';
|
|
||||||
@import 'components/forms';
|
@import 'components/forms';
|
||||||
|
@import 'components/header';
|
||||||
|
@import 'components/pagination';
|
||||||
|
|
||||||
a {
|
a {
|
||||||
&,
|
&,
|
||||||
@ -30,12 +32,6 @@ a {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
h1 {
|
|
||||||
color: #FFF3B0;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
max-width: 40rem;
|
max-width: 40rem;
|
||||||
margin: 1em auto;
|
margin: 1em auto;
|
||||||
|
@ -9,6 +9,8 @@
|
|||||||
"date tags"
|
"date tags"
|
||||||
"actions actions";
|
"actions actions";
|
||||||
|
|
||||||
|
color: #000;
|
||||||
|
|
||||||
form & {
|
form & {
|
||||||
grid-template-areas:
|
grid-template-areas:
|
||||||
"title"
|
"title"
|
||||||
|
18
resources/sass/components/_header.scss
Normal file
18
resources/sass/components/_header.scss
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
header {
|
||||||
|
display: flex;
|
||||||
|
margin: 1em 0;
|
||||||
|
|
||||||
|
> h1 {
|
||||||
|
flex: 1;
|
||||||
|
margin: 0;
|
||||||
|
color: #FFF3B0;
|
||||||
|
text-align: left;
|
||||||
|
font-size: 2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
> a {
|
||||||
|
flex: 0;
|
||||||
|
font-size: 2rem;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
}
|
@ -1,39 +1,40 @@
|
|||||||
@extends('layouts.app')
|
@extends('layouts.app')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
|
<h2>{{ $bookmark ? "Edit Bookmark" : "Add Bookmark" }}</h2>
|
||||||
<p>
|
<p>
|
||||||
<a href="{{ action('BookmarkController@index') }}">← Back</a>
|
<a href="{{ action('BookmarkController@index') }}">← Back</a>
|
||||||
</p>
|
</p>
|
||||||
<form method="post" class="form" action="{{ action('BookmarkController@update', ['bookmark' => $bookmark]) }}">
|
<form method="post" class="form" action="{{ $bookmark ? action('BookmarkController@update', ['bookmark' => $bookmark]) : action('BookmarkController@store') }}">
|
||||||
@csrf
|
@csrf
|
||||||
<div class="bookmark">
|
<div class="bookmark">
|
||||||
<div class="bookmark-title form-row"g>
|
<div class="bookmark-title form-row">
|
||||||
<label class="form-label" for="title">
|
<label class="form-label" for="title">
|
||||||
Title:
|
Title:
|
||||||
</label>
|
</label>
|
||||||
<input type="text" class="form-input" name="title" value="{{ $bookmark->title }}">
|
<input type="text" class="form-input" name="title" value="{{ $bookmark?->title }}" tabindex="1">
|
||||||
</div>
|
</div>
|
||||||
<div class="bookmark-href form-row form-row-stacked">
|
<div class="bookmark-href form-row form-row-stacked">
|
||||||
<label class="form-label" for="href">
|
<label class="form-label" for="href">
|
||||||
URL:
|
URL:
|
||||||
</label>
|
</label>
|
||||||
<input type="text" class="form-input" name="href" value="{{ $bookmark->href }}">
|
<input type="text" class="form-input" name="href" value="{{ $bookmark?->href }}" tabindex="3">
|
||||||
</div>
|
</div>
|
||||||
<div class="bookmark-description form-row form-row-stacked">
|
<div class="bookmark-description form-row form-row-stacked">
|
||||||
<label class="form-label" for="description">
|
<label class="form-label" for="description">
|
||||||
Description:
|
Description:
|
||||||
</label>
|
</label>
|
||||||
<textarea name="description" class="form-textarea">{{ $bookmark->description }}</textarea>
|
<textarea name="description" class="form-textarea" tabindex="2">{{ $bookmark?->description }}</textarea>
|
||||||
</div>
|
</div>
|
||||||
<div class="bookmark-tags form-row form-row-stacked">
|
<div class="bookmark-tags form-row form-row-stacked">
|
||||||
<label class="form-label" for="description">
|
<label class="form-label" for="description">
|
||||||
Tags:
|
Tags:
|
||||||
</label>
|
</label>
|
||||||
<input type="text" class="form-input" name="tags" value="@foreach ($bookmark->tags as $tag){{ $tag->name }} @endforeach">
|
<input type="text" class="form-input" name="tags" tabindex="4" value="@foreach ($bookmark?->tags ?? [] as $tag){{ $tag->name }} @endforeach">
|
||||||
</div>
|
</div>
|
||||||
<div class="form-row align-right bookmark-actions">
|
<div class="form-row align-right bookmark-actions">
|
||||||
<a class="form-button" href="{{ action('BookmarkController@show', ['bookmark' => $bookmark]) }}">Cancel</a>
|
<a class="form-button" tabindex="5" href="{{ $bookmark ? action('BookmarkController@show', ['bookmark' => $bookmark]) : action('BookmarkController@index') }}">Cancel</a>
|
||||||
<input type="submit" class="form-button" value="Save">
|
<input type="submit" tabindex="6" class="form-button" value="Save">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
@ -6,7 +6,10 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
<header>
|
||||||
<h1><a href="{{ url("/") }}">url snail</a></h1>
|
<h1><a href="{{ url("/") }}">url snail</a></h1>
|
||||||
|
<a href="{{ action('BookmarkController@create') }}">+</a>
|
||||||
|
</header>
|
||||||
@yield('content')
|
@yield('content')
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
|
@ -1,9 +1,12 @@
|
|||||||
@extends('layouts.app')
|
@extends('layouts.app')
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
|
<h2>Tag: {{ $tag->name }} ({{ $tag_count }})</h2>
|
||||||
|
{{ $bookmarks->links() }}
|
||||||
<div>
|
<div>
|
||||||
@foreach ($tag->bookmarks as $bookmark)
|
@foreach ($bookmarks as $bookmark)
|
||||||
<x-bookmark :bookmark="$bookmark" />
|
<x-bookmark :bookmark="$bookmark" />
|
||||||
@endforeach
|
@endforeach
|
||||||
</div>
|
</div>
|
||||||
|
{{ $bookmarks->links() }}
|
||||||
@endsection
|
@endsection
|
||||||
|
Loading…
Reference in New Issue
Block a user