fuck: IDK, man. Lots of good stuff. Mostly styling. Also Subs!
This commit is contained in:
parent
c8aae69ffb
commit
0e3902d16b
14
.env.example
14
.env.example
|
|
@ -25,17 +25,3 @@ MAIL_PASSWORD=null
|
||||||
MAIL_ENCRYPTION=null
|
MAIL_ENCRYPTION=null
|
||||||
MAIL_FROM_ADDRESS="hello@example.com"
|
MAIL_FROM_ADDRESS="hello@example.com"
|
||||||
MAIL_FROM_NAME="${APP_NAME}"
|
MAIL_FROM_NAME="${APP_NAME}"
|
||||||
|
|
||||||
AWS_ACCESS_KEY_ID=
|
|
||||||
AWS_SECRET_ACCESS_KEY=
|
|
||||||
AWS_DEFAULT_REGION=us-east-1
|
|
||||||
AWS_BUCKET=
|
|
||||||
AWS_USE_PATH_STYLE_ENDPOINT=false
|
|
||||||
|
|
||||||
PUSHER_APP_ID=
|
|
||||||
PUSHER_APP_KEY=
|
|
||||||
PUSHER_APP_SECRET=
|
|
||||||
PUSHER_HOST=
|
|
||||||
PUSHER_PORT=443
|
|
||||||
PUSHER_SCHEME=https
|
|
||||||
PUSHER_APP_CLUSTER=mt1
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,25 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use App\Models\Subscriber;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Http\RedirectResponse;
|
||||||
|
|
||||||
|
class ReaderController extends Controller
|
||||||
|
{
|
||||||
|
public function subscribe(Request $request): RedirectResponse
|
||||||
|
{
|
||||||
|
// Validate email
|
||||||
|
$validated = $request->validate([
|
||||||
|
'email' => 'required|email|max:512',
|
||||||
|
]);
|
||||||
|
|
||||||
|
if($validated['email']) {
|
||||||
|
Subscriber::firstOrCreate(['email' => $validated['email']]);
|
||||||
|
return redirect(route('subscribe-success'));
|
||||||
|
} else {
|
||||||
|
return redirect(route('subscribe-fail'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -2,10 +2,12 @@
|
||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||||
use Illuminate\Support\Str;
|
use Illuminate\Support\Str;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Support\Carbon;
|
||||||
|
|
||||||
class Article extends Model
|
class Article extends Model
|
||||||
{
|
{
|
||||||
|
|
@ -27,12 +29,34 @@ class Article extends Model
|
||||||
'processed_at',
|
'processed_at',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/** ---------------------------------------
|
||||||
|
* ACCESSORS
|
||||||
|
* ---------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
protected function publishedAt(): Attribute
|
||||||
|
{
|
||||||
|
return Attribute::make(
|
||||||
|
get: fn (string $value) => Carbon::parse($value)->format('D, M jS o, g:i A'),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** ---------------------------------------
|
||||||
|
* RELATIONSHIPS
|
||||||
|
* ---------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
/** The person that wrote the article. */
|
/** The person that wrote the article. */
|
||||||
public function author(): BelongsTo
|
public function author(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Author::class);
|
return $this->belongsTo(Author::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** ---------------------------------------
|
||||||
|
* MODEL METHODS
|
||||||
|
* ---------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
public function convertMarkdownToMarkup()
|
public function convertMarkdownToMarkup()
|
||||||
{
|
{
|
||||||
if (is_null($this->markdown_body)) return null;
|
if (is_null($this->markdown_body)) return null;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
|
||||||
|
class Subscriber extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
/** The name of the database table storing this Model's records. */
|
||||||
|
protected $table = 'subscribers';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates if the model should be timestamped.
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public $timestamps = false;
|
||||||
|
|
||||||
|
/** The attributes on the Model that can be mass-assigned */
|
||||||
|
protected $fillable = [
|
||||||
|
'email',
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
@ -16,7 +16,7 @@ return [
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'name' => env('APP_NAME', 'Laravel'),
|
'name' => env('APP_NAME', 'Word Salad'),
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
@ -70,7 +70,7 @@ return [
|
||||||
|
|
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
'timezone' => 'UTC',
|
'timezone' => 'America/Denver',
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|--------------------------------------------------------------------------
|
|--------------------------------------------------------------------------
|
||||||
|
|
|
||||||
|
|
@ -42,13 +42,13 @@ class ArticleFactory extends Factory
|
||||||
public function definition(): array
|
public function definition(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
'title' => fake()->words(3, true),
|
'title' => $this->getRandomTitle(),
|
||||||
'slug' => fake()->unique()->slug(),
|
'slug' => fake()->unique()->slug(),
|
||||||
'author_id' => static::$author->id ??= Author::factory()->create()->id,
|
'author_id' => static::$author->id ??= Author::factory()->create()->id,
|
||||||
'subtitle' => fake()->sentence(),
|
'subtitle' => $this->getRandomSentence(),
|
||||||
'body' => '', // We'll update it after making using the on-Model method
|
'body' => '', // We'll update it after making using the on-Model method
|
||||||
'published_at' => $this->generateRandomPublishDate(),
|
'published_at' => $this->generateRandomPublishDate(),
|
||||||
'header_image_url' => fake()->imageUrl(),
|
'header_image_url' => null,
|
||||||
'markdown_body' => $this->generateMarkdown(),
|
'markdown_body' => $this->generateMarkdown(),
|
||||||
'processed_at' => fake()->date('Y-m-d H:m:s'),
|
'processed_at' => fake()->date('Y-m-d H:m:s'),
|
||||||
];
|
];
|
||||||
|
|
@ -98,4 +98,60 @@ class ArticleFactory extends Factory
|
||||||
return now()->addDays(rand(0,50));
|
return now()->addDays(rand(0,50));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private function getRandomTitle(): string
|
||||||
|
{
|
||||||
|
$possibilities = [
|
||||||
|
'What\'s in a Title? Hopefully More Than This',
|
||||||
|
'This One Will Leave You Speechless',
|
||||||
|
'Finally, The Pizza of Your Dreams',
|
||||||
|
'We Came, We Saw, and Then...',
|
||||||
|
'The Incomprehensibility of Aluminum',
|
||||||
|
'You Merely Adopted this Format, I Was Born In It, Molded by It',
|
||||||
|
'Vector Math is for Cowards',
|
||||||
|
'When Two Packets Love Each Other Very Much',
|
||||||
|
'I\'m Slipping, I\'m Sliding (I\'m on a Slip \'n Slide)',
|
||||||
|
'Tips On Giving Up (Maximum Efficiency)',
|
||||||
|
'Top 10 Reasons to Give Up Completely',
|
||||||
|
'Even the Monsters Are Disappointed',
|
||||||
|
];
|
||||||
|
|
||||||
|
return $possibilities[random_int(0, count($possibilities) - 1)];
|
||||||
|
}
|
||||||
|
|
||||||
|
private function getRandomSentence(): string
|
||||||
|
{
|
||||||
|
$possibilities = [
|
||||||
|
'That page would not bring the reward that was promised.',
|
||||||
|
'However, his tendency toward love was endearing, I miss that most of all.',
|
||||||
|
'The jellyfish doesn\'t care what you think, that\'s hubris.',
|
||||||
|
'And yet.',
|
||||||
|
'I find it distasteful, the smell lingering in the air for weeks and months while officials dragged their feet.',
|
||||||
|
'I think it was down this hill, maybe.',
|
||||||
|
'Cold eyes, I never liked them.',
|
||||||
|
'You can call me fit, or the love of your life, if you want.',
|
||||||
|
'The kei truck proves its superiority yet again in the quarter-mile.',
|
||||||
|
'He knocked, but heard nothing.',
|
||||||
|
'First base!',
|
||||||
|
'But these histories are still lost to us, despite our vast technical advances.',
|
||||||
|
'In the sincerest way possible, I am begging you to start the fire.',
|
||||||
|
'They drifted up high over head and then sank reluctantly.',
|
||||||
|
'I\'m so proud of you, no matter how belated!',
|
||||||
|
'She gripped the handle, but didn\'t have the heart to turn it.',
|
||||||
|
'If this, then that, so to speak.',
|
||||||
|
'Mapping the source column onto the target column should be strictly validated to ensure no missing fields.',
|
||||||
|
'Would there be something in there, though?',
|
||||||
|
'The wood splintering echoed down the hall.',
|
||||||
|
'I simply do not understand.',
|
||||||
|
'The radio tower nearly scraped the belly of the bomber as it strained against the immense pressure.',
|
||||||
|
'What\'s actually left after that?',
|
||||||
|
'Yes, but it needs more spice.',
|
||||||
|
'Backtracking is good, actually.',
|
||||||
|
'Scan has always been the problem.',
|
||||||
|
'Smell first, then you can think about licking.',
|
||||||
|
];
|
||||||
|
|
||||||
|
return $possibilities[random_int(0, count($possibilities) - 1)];
|
||||||
|
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace Database\Factories;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @extends \Illuminate\Database\Eloquent\Factories\Factory<\App\Models\Subscriber>
|
||||||
|
*/
|
||||||
|
class SubscriberFactory extends Factory
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Define the model's default state.
|
||||||
|
*
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
|
public function definition(): array
|
||||||
|
{
|
||||||
|
return [
|
||||||
|
'email' => fake()->safeEmail(),
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,27 @@
|
||||||
|
<?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('subscribers', function (Blueprint $table) {
|
||||||
|
$table->id();
|
||||||
|
$table->string('email', 512)->unique();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reverse the migrations.
|
||||||
|
*/
|
||||||
|
public function down(): void
|
||||||
|
{
|
||||||
|
Schema::dropIfExists('subscribers');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
@ -5,6 +5,7 @@ namespace Database\Seeders;
|
||||||
use App\Models\User;
|
use App\Models\User;
|
||||||
use App\Models\Author;
|
use App\Models\Author;
|
||||||
use App\Models\Article;
|
use App\Models\Article;
|
||||||
|
use App\Models\Subscriber;
|
||||||
use Illuminate\Database\Seeder;
|
use Illuminate\Database\Seeder;
|
||||||
use Illuminate\Support\Facades\Hash;
|
use Illuminate\Support\Facades\Hash;
|
||||||
|
|
||||||
|
|
@ -23,7 +24,7 @@ class DatabaseSeeder extends Seeder
|
||||||
|
|
||||||
$test_author = Author::factory()->user($test_user)->create();
|
$test_author = Author::factory()->user($test_user)->create();
|
||||||
|
|
||||||
Article::factory()->author($test_author)->count(30)->create();
|
Article::factory()->author($test_author)->count(50)->create();
|
||||||
|
|
||||||
$random_article = Article::where('id', '<', 10)->inRandomOrder()->first();
|
$random_article = Article::where('id', '<', 10)->inRandomOrder()->first();
|
||||||
|
|
||||||
|
|
@ -31,5 +32,7 @@ class DatabaseSeeder extends Seeder
|
||||||
alert('oh shit. XSS might be possible here!')
|
alert('oh shit. XSS might be possible here!')
|
||||||
</script>";
|
</script>";
|
||||||
$random_article->save();
|
$random_article->save();
|
||||||
|
|
||||||
|
Subscriber::factory()->count(10)->create();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,26 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
body {
|
body {
|
||||||
background-color: #813d9c; /* Primary Purple */
|
/* background-color: #813d9c; /* Old Purple */
|
||||||
|
background-color: #2d033e; /* New Purple */
|
||||||
color: white;
|
color: white;
|
||||||
text-shadow: 1px 1px 2px blueviolet;
|
text-shadow: 1px 1px 2px blueviolet;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
main {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
article {
|
||||||
|
max-width: 60vw;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 1250px) {
|
||||||
|
article {
|
||||||
|
max-width: 90vw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
a {
|
a {
|
||||||
|
|
@ -14,19 +31,71 @@ a {
|
||||||
}
|
}
|
||||||
|
|
||||||
#top-bar {
|
#top-bar {
|
||||||
padding: 0.5em;
|
padding: 0.5em 0em;
|
||||||
background-color: rgba(red, green, blue, 0.2);
|
background-color: #ffffff3d;
|
||||||
border-bottom: 1px solid white;
|
border-bottom: 1px solid white;
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
font-size: smaller;
|
||||||
|
}
|
||||||
|
|
||||||
|
nav {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
|
||||||
|
#nav-logo > a {
|
||||||
|
text-decoration: none;
|
||||||
|
color: #ff9344;
|
||||||
|
font-size: x-large;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 0.3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#article-header-separator {
|
||||||
|
width: 60%;
|
||||||
|
color: white;
|
||||||
|
margin: 2em auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.bubble-panel {
|
footer {
|
||||||
|
min-height: 7em;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
#subscribe-form {
|
||||||
|
border-radius: 1.5em;
|
||||||
|
border-color: white;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 1px;
|
||||||
|
padding: 1.4em;
|
||||||
|
margin-top: 1.5em;
|
||||||
|
margin-bottom: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
#subscribe-form > form {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#subscribe-form .email-input {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
#subscribe-button {
|
||||||
|
background-color: #ff9344;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* .bubble-panel {
|
||||||
border-radius: 50px;
|
border-radius: 50px;
|
||||||
background: #813d9c;
|
background: #813d9c;
|
||||||
box-shadow: -33px 33px 65px #66307b,
|
box-shadow: -33px 33px 65px #66307b,
|
||||||
33px -33px 65px #9c4abd;
|
33px -33px 65px #9c4abd;
|
||||||
padding: 2em;
|
padding: 2em;
|
||||||
}
|
}*/
|
||||||
|
|
|
||||||
|
|
@ -10,5 +10,7 @@
|
||||||
@empty
|
@empty
|
||||||
<h4>No articles found, unlucky.</h4>
|
<h4>No articles found, unlucky.</h4>
|
||||||
@endforelse
|
@endforelse
|
||||||
|
|
||||||
|
{{ $all_articles->links() }}
|
||||||
</div>
|
</div>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
|
||||||
|
|
@ -8,19 +8,28 @@
|
||||||
<p><i>{{ config('blog.subheading') }}</i></p>
|
<p><i>{{ config('blog.subheading') }}</i></p>
|
||||||
</section>
|
</section>
|
||||||
<section>
|
<section>
|
||||||
@forelse($articles as $article)
|
@if(count($articles) > 0)
|
||||||
<article>
|
@foreach($articles as $article)
|
||||||
<h3>
|
<article>
|
||||||
<a href="{{ route('article', ['article_slug' => $article->slug]) }}">
|
<h3>
|
||||||
{{ $article->title }}
|
<a href="{{ route('article', ['article_slug' => $article->slug]) }}">
|
||||||
</a>
|
{{ $article->title }}
|
||||||
</h3>
|
</a>
|
||||||
<h4>
|
</h3>
|
||||||
{{ $article->subtitle }}
|
<h4>
|
||||||
</h4>
|
{{ $article->subtitle }}
|
||||||
</article>
|
</h4>
|
||||||
@empty
|
</article>
|
||||||
|
@endforeach
|
||||||
|
{{--
|
||||||
|
<section>
|
||||||
|
<a href="{{ route('all-articles') }}">
|
||||||
|
See All Articles
|
||||||
|
</a>
|
||||||
|
</section>
|
||||||
|
--}}
|
||||||
|
@else
|
||||||
<div>No articles published yet. Check back soon!</div>
|
<div>No articles published yet. Check back soon!</div>
|
||||||
@endforelse
|
@endif
|
||||||
</section>
|
</section>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
<nav id="main-nav">
|
||||||
|
<div id="nav-logo"><a href="/">{{ config('app.name') }}</a></div>
|
||||||
|
<div>
|
||||||
|
{{--
|
||||||
|
<form action="{{route('search')}}">
|
||||||
|
<input type="search" id="site-search" name="q" />
|
||||||
|
<button>Search</button>
|
||||||
|
</form>
|
||||||
|
--}}
|
||||||
|
</div>
|
||||||
|
</nav>
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
@extends('layouts.guest')
|
||||||
|
|
||||||
|
@section('title', 'Subscription Failed')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<section>
|
||||||
|
<h1>Subscription Error</h1>
|
||||||
|
<p>Something went wrong while marking your interest. Sorry.</p>
|
||||||
|
</section>
|
||||||
|
@endsection
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
@extends('layouts.guest')
|
||||||
|
|
||||||
|
@section('title', 'Subscription Confirmed')
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<section>
|
||||||
|
<h1>Subscription Confirmed</h1>
|
||||||
|
<p>You'll be the first to know about future posts. Thank you.</p>
|
||||||
|
</section>
|
||||||
|
@endsection
|
||||||
|
|
@ -9,7 +9,11 @@
|
||||||
<title>{{ config('blog.publishing_name') }} | @yield('title')</title>
|
<title>{{ config('blog.publishing_name') }} | @yield('title')</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@include('guest.top-bar')
|
<header>
|
||||||
|
@include('guest.top-bar')
|
||||||
|
|
||||||
|
@include('guest.main-nav')
|
||||||
|
</header>
|
||||||
|
|
||||||
<section id="error-bag">
|
<section id="error-bag">
|
||||||
@foreach($errors->all() as $error)
|
@foreach($errors->all() as $error)
|
||||||
|
|
@ -21,4 +25,9 @@
|
||||||
@yield('content', 'Nothing to see here.')
|
@yield('content', 'Nothing to see here.')
|
||||||
</main>
|
</main>
|
||||||
</body>
|
</body>
|
||||||
|
@if(! in_array(Route::currentRouteName(), ['subscribe-success', 'subscribe-fail']))
|
||||||
|
<footer>
|
||||||
|
@include('shared.subscribe-form')
|
||||||
|
</footer>
|
||||||
|
@endif
|
||||||
</html>
|
</html>
|
||||||
|
|
|
||||||
|
|
@ -1,16 +1,22 @@
|
||||||
<article>
|
<article>
|
||||||
<a href="{{ url()->previous() }}"> ← Go Back</a>
|
@if($article['header_image_url'])
|
||||||
<img src="{{ $article['header_image_url'] }}" />
|
<img src="{{ $article['header_image_url'] }}" />
|
||||||
|
@endif
|
||||||
<h1>{{ $article['title'] }}</h1>
|
<h1>{{ $article['title'] }}</h1>
|
||||||
<h2>{{ $article['subtitle'] }}</h2>
|
<h2>{{ $article['subtitle'] }}</h2>
|
||||||
<p>{{ $article['author']['display_name'] }}</p>
|
<p>Written By: {{ $article['author']['display_name'] }}</p>
|
||||||
<p>Published At: {{ $article['published_at'] }}</p>
|
<p>Published: {{ $article['published_at'] }}</p>
|
||||||
|
{{--
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="{{ $article['primary_link'] }}">Link 1</a></li>
|
<li><a href="{{ $article['primary_link'] }}">Link 1</a></li>
|
||||||
<li><a href="{{ $article['secondary_link'] }}">Link 2</a></li>
|
<li><a href="{{ $article['secondary_link'] }}">Link 2</a></li>
|
||||||
<li><a href="{{ $article['mastodon_handle'] }}">Mastodon</a></li>
|
<li><a href="{{ $article['mastodon_handle'] }}">Mastodon</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
<main>
|
--}}
|
||||||
|
|
||||||
|
<hr id="article-header-separator" />
|
||||||
|
|
||||||
|
<section>
|
||||||
{!! $article['body'] !!}
|
{!! $article['body'] !!}
|
||||||
</main>
|
</section>
|
||||||
</article>
|
</article>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
<div id="subscribe-form">
|
||||||
|
<form action="{{ route('subscribe') }}" method="POST">
|
||||||
|
@csrf
|
||||||
|
<div class="email-input">
|
||||||
|
<label for="email">Email Address</label>
|
||||||
|
<input type="email" name="email" id="email" required placeholder="coolperson@example.com" />
|
||||||
|
</div>
|
||||||
|
<button id="subscribe-button" type="submit">Subscribe</button>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
|
@ -1,7 +1,9 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Http\Controllers\ReaderController;
|
||||||
use App\Http\Controllers\WriterController;
|
use App\Http\Controllers\WriterController;
|
||||||
use App\Models\Article;
|
use App\Models\Article;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
use Illuminate\Support\Facades\Route;
|
use Illuminate\Support\Facades\Route;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -24,10 +26,10 @@ Route::get('/test-insert', function () {
|
||||||
return view('test-insert');
|
return view('test-insert');
|
||||||
})->name('test-insert');
|
})->name('test-insert');
|
||||||
|
|
||||||
Route::get('/recent-articles', function () {
|
Route::get('/all-articles', function () {
|
||||||
$all_articles = Article::where('published_at', '<', now())->limit(10)->get();
|
$all_articles = Article::where('published_at', '<', now())->paginate(25);
|
||||||
return view('guest.all-articles', ['all_articles' => $all_articles]);
|
return view('guest.all-articles', ['all_articles' => $all_articles]);
|
||||||
})->name('recent-articles');
|
})->name('all-articles');
|
||||||
|
|
||||||
Route::get('/post/{article_slug}', function ($article_slug) {
|
Route::get('/post/{article_slug}', function ($article_slug) {
|
||||||
$active_article = Article::with('author')
|
$active_article = Article::with('author')
|
||||||
|
|
@ -45,6 +47,16 @@ Route::get('/writer/login', function () {
|
||||||
return view('writer.login');
|
return view('writer.login');
|
||||||
})->name('login');
|
})->name('login');
|
||||||
|
|
||||||
|
Route::post('/subscribe', [ReaderController::class, 'subscribe'])->name('subscribe');
|
||||||
|
|
||||||
|
Route::get('/subscribe-success', function() {
|
||||||
|
return view('guest.subscribe-success');
|
||||||
|
})->name('subscribe-success');
|
||||||
|
|
||||||
|
Route::get('/subscribe-fail', function() {
|
||||||
|
return view('guest.subscribe-fail');
|
||||||
|
})->name('subscribe-fail');
|
||||||
|
|
||||||
Route::post('/writer/authenticate', [WriterController::class, 'authenticate'])->name('authenticate');
|
Route::post('/writer/authenticate', [WriterController::class, 'authenticate'])->name('authenticate');
|
||||||
|
|
||||||
Route::middleware('auth')->group(function () {
|
Route::middleware('auth')->group(function () {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue