summaryrefslogtreecommitdiff
path: root/resources
diff options
context:
space:
mode:
Diffstat (limited to 'resources')
-rw-r--r--resources/js/app.js1
-rw-r--r--resources/js/bootstrap.js41
-rw-r--r--resources/lang/en/auth.php19
-rw-r--r--resources/lang/en/pagination.php19
-rw-r--r--resources/lang/en/passwords.php22
-rw-r--r--resources/lang/en/validation.php151
-rw-r--r--resources/sass/_background.scss26
-rw-r--r--resources/sass/_navbar.scss16
-rw-r--r--resources/sass/_variables.scss19
-rw-r--r--resources/sass/app.scss11
-rw-r--r--resources/views/auth/login.blade.php73
-rw-r--r--resources/views/auth/passwords/confirm.blade.php49
-rw-r--r--resources/views/auth/passwords/email.blade.php47
-rw-r--r--resources/views/auth/passwords/reset.blade.php65
-rw-r--r--resources/views/auth/register.blade.php77
-rw-r--r--resources/views/auth/verify.blade.php28
-rw-r--r--resources/views/home.blade.php23
-rw-r--r--resources/views/index.blade.php25
-rw-r--r--resources/views/layouts/app.blade.php115
-rw-r--r--resources/views/list.blade.php126
-rw-r--r--resources/views/search.blade.php19
-rw-r--r--resources/views/topicindex.blade.php18
-rw-r--r--resources/views/welcome.blade.php100
23 files changed, 1090 insertions, 0 deletions
diff --git a/resources/js/app.js b/resources/js/app.js
new file mode 100644
index 0000000..40c55f6
--- /dev/null
+++ b/resources/js/app.js
@@ -0,0 +1 @@
+require('./bootstrap');
diff --git a/resources/js/bootstrap.js b/resources/js/bootstrap.js
new file mode 100644
index 0000000..8eaba1b
--- /dev/null
+++ b/resources/js/bootstrap.js
@@ -0,0 +1,41 @@
+window._ = require('lodash');
+
+/**
+ * We'll load jQuery and the Bootstrap jQuery plugin which provides support
+ * for JavaScript based Bootstrap features such as modals and tabs. This
+ * code may be modified to fit the specific needs of your application.
+ */
+
+try {
+ window.Popper = require('popper.js').default;
+ window.$ = window.jQuery = require('jquery');
+
+ require('bootstrap');
+} catch (e) {}
+
+/**
+ * We'll load the axios HTTP library which allows us to easily issue requests
+ * to our Laravel back-end. This library automatically handles sending the
+ * CSRF token as a header based on the value of the "XSRF" token cookie.
+ */
+
+window.axios = require('axios');
+
+window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
+
+/**
+ * Echo exposes an expressive API for subscribing to channels and listening
+ * for events that are broadcast by Laravel. Echo and event broadcasting
+ * allows your team to easily build robust real-time web applications.
+ */
+
+// import Echo from 'laravel-echo';
+
+// window.Pusher = require('pusher-js');
+
+// window.Echo = new Echo({
+// broadcaster: 'pusher',
+// key: process.env.MIX_PUSHER_APP_KEY,
+// cluster: process.env.MIX_PUSHER_APP_CLUSTER,
+// encrypted: true
+// });
diff --git a/resources/lang/en/auth.php b/resources/lang/en/auth.php
new file mode 100644
index 0000000..e5506df
--- /dev/null
+++ b/resources/lang/en/auth.php
@@ -0,0 +1,19 @@
+<?php
+
+return [
+
+ /*
+ |--------------------------------------------------------------------------
+ | Authentication Language Lines
+ |--------------------------------------------------------------------------
+ |
+ | The following language lines are used during authentication for various
+ | messages that we need to display to the user. You are free to modify
+ | these language lines according to your application's requirements.
+ |
+ */
+
+ 'failed' => 'These credentials do not match our records.',
+ 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
+
+];
diff --git a/resources/lang/en/pagination.php b/resources/lang/en/pagination.php
new file mode 100644
index 0000000..d481411
--- /dev/null
+++ b/resources/lang/en/pagination.php
@@ -0,0 +1,19 @@
+<?php
+
+return [
+
+ /*
+ |--------------------------------------------------------------------------
+ | Pagination Language Lines
+ |--------------------------------------------------------------------------
+ |
+ | The following language lines are used by the paginator library to build
+ | the simple pagination links. You are free to change them to anything
+ | you want to customize your views to better match your application.
+ |
+ */
+
+ 'previous' => '&laquo; Previous',
+ 'next' => 'Next &raquo;',
+
+];
diff --git a/resources/lang/en/passwords.php b/resources/lang/en/passwords.php
new file mode 100644
index 0000000..2345a56
--- /dev/null
+++ b/resources/lang/en/passwords.php
@@ -0,0 +1,22 @@
+<?php
+
+return [
+
+ /*
+ |--------------------------------------------------------------------------
+ | Password Reset Language Lines
+ |--------------------------------------------------------------------------
+ |
+ | The following language lines are the default lines which match reasons
+ | that are given by the password broker for a password update attempt
+ | has failed, such as for an invalid token or invalid new password.
+ |
+ */
+
+ 'reset' => 'Your password has been reset!',
+ 'sent' => 'We have emailed your password reset link!',
+ 'throttled' => 'Please wait before retrying.',
+ 'token' => 'This password reset token is invalid.',
+ 'user' => "We can't find a user with that email address.",
+
+];
diff --git a/resources/lang/en/validation.php b/resources/lang/en/validation.php
new file mode 100644
index 0000000..a65914f
--- /dev/null
+++ b/resources/lang/en/validation.php
@@ -0,0 +1,151 @@
+<?php
+
+return [
+
+ /*
+ |--------------------------------------------------------------------------
+ | Validation Language Lines
+ |--------------------------------------------------------------------------
+ |
+ | The following language lines contain the default error messages used by
+ | the validator class. Some of these rules have multiple versions such
+ | as the size rules. Feel free to tweak each of these messages here.
+ |
+ */
+
+ 'accepted' => 'The :attribute must be accepted.',
+ 'active_url' => 'The :attribute is not a valid URL.',
+ 'after' => 'The :attribute must be a date after :date.',
+ 'after_or_equal' => 'The :attribute must be a date after or equal to :date.',
+ 'alpha' => 'The :attribute may only contain letters.',
+ 'alpha_dash' => 'The :attribute may only contain letters, numbers, dashes and underscores.',
+ 'alpha_num' => 'The :attribute may only contain letters and numbers.',
+ 'array' => 'The :attribute must be an array.',
+ 'before' => 'The :attribute must be a date before :date.',
+ 'before_or_equal' => 'The :attribute must be a date before or equal to :date.',
+ 'between' => [
+ 'numeric' => 'The :attribute must be between :min and :max.',
+ 'file' => 'The :attribute must be between :min and :max kilobytes.',
+ 'string' => 'The :attribute must be between :min and :max characters.',
+ 'array' => 'The :attribute must have between :min and :max items.',
+ ],
+ 'boolean' => 'The :attribute field must be true or false.',
+ 'confirmed' => 'The :attribute confirmation does not match.',
+ 'date' => 'The :attribute is not a valid date.',
+ 'date_equals' => 'The :attribute must be a date equal to :date.',
+ 'date_format' => 'The :attribute does not match the format :format.',
+ 'different' => 'The :attribute and :other must be different.',
+ 'digits' => 'The :attribute must be :digits digits.',
+ 'digits_between' => 'The :attribute must be between :min and :max digits.',
+ 'dimensions' => 'The :attribute has invalid image dimensions.',
+ 'distinct' => 'The :attribute field has a duplicate value.',
+ 'email' => 'The :attribute must be a valid email address.',
+ 'ends_with' => 'The :attribute must end with one of the following: :values.',
+ 'exists' => 'The selected :attribute is invalid.',
+ 'file' => 'The :attribute must be a file.',
+ 'filled' => 'The :attribute field must have a value.',
+ 'gt' => [
+ 'numeric' => 'The :attribute must be greater than :value.',
+ 'file' => 'The :attribute must be greater than :value kilobytes.',
+ 'string' => 'The :attribute must be greater than :value characters.',
+ 'array' => 'The :attribute must have more than :value items.',
+ ],
+ 'gte' => [
+ 'numeric' => 'The :attribute must be greater than or equal :value.',
+ 'file' => 'The :attribute must be greater than or equal :value kilobytes.',
+ 'string' => 'The :attribute must be greater than or equal :value characters.',
+ 'array' => 'The :attribute must have :value items or more.',
+ ],
+ 'image' => 'The :attribute must be an image.',
+ 'in' => 'The selected :attribute is invalid.',
+ 'in_array' => 'The :attribute field does not exist in :other.',
+ 'integer' => 'The :attribute must be an integer.',
+ 'ip' => 'The :attribute must be a valid IP address.',
+ 'ipv4' => 'The :attribute must be a valid IPv4 address.',
+ 'ipv6' => 'The :attribute must be a valid IPv6 address.',
+ 'json' => 'The :attribute must be a valid JSON string.',
+ 'lt' => [
+ 'numeric' => 'The :attribute must be less than :value.',
+ 'file' => 'The :attribute must be less than :value kilobytes.',
+ 'string' => 'The :attribute must be less than :value characters.',
+ 'array' => 'The :attribute must have less than :value items.',
+ ],
+ 'lte' => [
+ 'numeric' => 'The :attribute must be less than or equal :value.',
+ 'file' => 'The :attribute must be less than or equal :value kilobytes.',
+ 'string' => 'The :attribute must be less than or equal :value characters.',
+ 'array' => 'The :attribute must not have more than :value items.',
+ ],
+ 'max' => [
+ 'numeric' => 'The :attribute may not be greater than :max.',
+ 'file' => 'The :attribute may not be greater than :max kilobytes.',
+ 'string' => 'The :attribute may not be greater than :max characters.',
+ 'array' => 'The :attribute may not have more than :max items.',
+ ],
+ 'mimes' => 'The :attribute must be a file of type: :values.',
+ 'mimetypes' => 'The :attribute must be a file of type: :values.',
+ 'min' => [
+ 'numeric' => 'The :attribute must be at least :min.',
+ 'file' => 'The :attribute must be at least :min kilobytes.',
+ 'string' => 'The :attribute must be at least :min characters.',
+ 'array' => 'The :attribute must have at least :min items.',
+ ],
+ 'not_in' => 'The selected :attribute is invalid.',
+ 'not_regex' => 'The :attribute format is invalid.',
+ 'numeric' => 'The :attribute must be a number.',
+ 'password' => 'The password is incorrect.',
+ 'present' => 'The :attribute field must be present.',
+ 'regex' => 'The :attribute format is invalid.',
+ 'required' => 'The :attribute field is required.',
+ 'required_if' => 'The :attribute field is required when :other is :value.',
+ 'required_unless' => 'The :attribute field is required unless :other is in :values.',
+ 'required_with' => 'The :attribute field is required when :values is present.',
+ 'required_with_all' => 'The :attribute field is required when :values are present.',
+ 'required_without' => 'The :attribute field is required when :values is not present.',
+ 'required_without_all' => 'The :attribute field is required when none of :values are present.',
+ 'same' => 'The :attribute and :other must match.',
+ 'size' => [
+ 'numeric' => 'The :attribute must be :size.',
+ 'file' => 'The :attribute must be :size kilobytes.',
+ 'string' => 'The :attribute must be :size characters.',
+ 'array' => 'The :attribute must contain :size items.',
+ ],
+ 'starts_with' => 'The :attribute must start with one of the following: :values.',
+ 'string' => 'The :attribute must be a string.',
+ 'timezone' => 'The :attribute must be a valid zone.',
+ 'unique' => 'The :attribute has already been taken.',
+ 'uploaded' => 'The :attribute failed to upload.',
+ 'url' => 'The :attribute format is invalid.',
+ 'uuid' => 'The :attribute must be a valid UUID.',
+
+ /*
+ |--------------------------------------------------------------------------
+ | Custom Validation Language Lines
+ |--------------------------------------------------------------------------
+ |
+ | Here you may specify custom validation messages for attributes using the
+ | convention "attribute.rule" to name the lines. This makes it quick to
+ | specify a specific custom language line for a given attribute rule.
+ |
+ */
+
+ 'custom' => [
+ 'attribute-name' => [
+ 'rule-name' => 'custom-message',
+ ],
+ ],
+
+ /*
+ |--------------------------------------------------------------------------
+ | Custom Validation Attributes
+ |--------------------------------------------------------------------------
+ |
+ | The following language lines are used to swap our attribute placeholder
+ | with something more reader friendly such as "E-Mail Address" instead
+ | of "email". This simply helps us make our message more expressive.
+ |
+ */
+
+ 'attributes' => [],
+
+];
diff --git a/resources/sass/_background.scss b/resources/sass/_background.scss
new file mode 100644
index 0000000..452d4d2
--- /dev/null
+++ b/resources/sass/_background.scss
@@ -0,0 +1,26 @@
+html {
+ height: 100%;
+}
+
+body {
+ width: 100%;
+ height: auto;
+ min-height:35rem;
+ background: linear-gradient(to bottom, rgba(1,1,1,.25) 0%, rgba(1,1,1,.45) 90%, rgba(2, 11, 26, 0.65) 100%), url("/img/world-bg.jpg");
+ background-color: rgba(2, 11, 26, 0.65);
+ background-position: center;
+ background-repeat: no-repeat;
+ background-attachment: scroll;
+ background-size: cover;
+}
+.cover-container {
+ color: white;
+ max-width: 42em;
+}
+.cover {
+ padding: 0 1.5rem;
+}
+.cover .btn-lg {
+ padding: .75rem 1.25rem;
+ font-weight: 700;
+}
diff --git a/resources/sass/_navbar.scss b/resources/sass/_navbar.scss
new file mode 100644
index 0000000..1542944
--- /dev/null
+++ b/resources/sass/_navbar.scss
@@ -0,0 +1,16 @@
+.navbar {
+ background-color: rgba(0,0,0,0) !important;
+}
+.navbar-toggler {
+ border-color: #808080;
+}
+
+.navbar-dark .nav-link {
+ color: darken( #fff, 10% ) !important;
+}
+
+@media( min-width: 768px ) {
+ .navbar-searchform {
+ margin-left: 0.5rem;
+ }
+}
diff --git a/resources/sass/_variables.scss b/resources/sass/_variables.scss
new file mode 100644
index 0000000..0407ab5
--- /dev/null
+++ b/resources/sass/_variables.scss
@@ -0,0 +1,19 @@
+// Body
+$body-bg: #f8fafc;
+
+// Typography
+$font-family-sans-serif: 'Nunito', sans-serif;
+$font-size-base: 0.9rem;
+$line-height-base: 1.6;
+
+// Colors
+$blue: #3490dc;
+$indigo: #6574cd;
+$purple: #9561e2;
+$pink: #f66d9b;
+$red: #e3342f;
+$orange: #f6993f;
+$yellow: #ffed4a;
+$green: #38c172;
+$teal: #4dc0b5;
+$cyan: #6cb2eb;
diff --git a/resources/sass/app.scss b/resources/sass/app.scss
new file mode 100644
index 0000000..f01e9ac
--- /dev/null
+++ b/resources/sass/app.scss
@@ -0,0 +1,11 @@
+// Fonts
+@import url('https://fonts.googleapis.com/css?family=Nunito');
+
+// Variables
+@import 'variables';
+
+// Bootstrap
+@import '~bootstrap/scss/bootstrap';
+
+@import 'background';
+@import 'navbar';
diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php
new file mode 100644
index 0000000..c12b97e
--- /dev/null
+++ b/resources/views/auth/login.blade.php
@@ -0,0 +1,73 @@
+@extends('layouts.app')
+
+@section('content')
+<div class="container">
+ <div class="row justify-content-center">
+ <div class="col-md-8">
+ <div class="card">
+ <div class="card-header">{{ __('Login') }}</div>
+
+ <div class="card-body">
+ <form method="POST" action="{{ route('login') }}">
+ @csrf
+
+ <div class="form-group row">
+ <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
+
+ <div class="col-md-6">
+ <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
+
+ @error('email')
+ <span class="invalid-feedback" role="alert">
+ <strong>{{ $message }}</strong>
+ </span>
+ @enderror
+ </div>
+ </div>
+
+ <div class="form-group row">
+ <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
+
+ <div class="col-md-6">
+ <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
+
+ @error('password')
+ <span class="invalid-feedback" role="alert">
+ <strong>{{ $message }}</strong>
+ </span>
+ @enderror
+ </div>
+ </div>
+
+ <div class="form-group row">
+ <div class="col-md-6 offset-md-4">
+ <div class="form-check">
+ <input class="form-check-input" type="checkbox" name="remember" id="remember" {{ old('remember') ? 'checked' : '' }}>
+
+ <label class="form-check-label" for="remember">
+ {{ __('Remember Me') }}
+ </label>
+ </div>
+ </div>
+ </div>
+
+ <div class="form-group row mb-0">
+ <div class="col-md-8 offset-md-4">
+ <button type="submit" class="btn btn-primary">
+ {{ __('Login') }}
+ </button>
+
+ @if (Route::has('password.request'))
+ <a class="btn btn-link" href="{{ route('password.request') }}">
+ {{ __('Forgot Your Password?') }}
+ </a>
+ @endif
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+@endsection
diff --git a/resources/views/auth/passwords/confirm.blade.php b/resources/views/auth/passwords/confirm.blade.php
new file mode 100644
index 0000000..ca78fc1
--- /dev/null
+++ b/resources/views/auth/passwords/confirm.blade.php
@@ -0,0 +1,49 @@
+@extends('layouts.app')
+
+@section('content')
+<div class="container">
+ <div class="row justify-content-center">
+ <div class="col-md-8">
+ <div class="card">
+ <div class="card-header">{{ __('Confirm Password') }}</div>
+
+ <div class="card-body">
+ {{ __('Please confirm your password before continuing.') }}
+
+ <form method="POST" action="{{ route('password.confirm') }}">
+ @csrf
+
+ <div class="form-group row">
+ <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
+
+ <div class="col-md-6">
+ <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="current-password">
+
+ @error('password')
+ <span class="invalid-feedback" role="alert">
+ <strong>{{ $message }}</strong>
+ </span>
+ @enderror
+ </div>
+ </div>
+
+ <div class="form-group row mb-0">
+ <div class="col-md-8 offset-md-4">
+ <button type="submit" class="btn btn-primary">
+ {{ __('Confirm Password') }}
+ </button>
+
+ @if (Route::has('password.request'))
+ <a class="btn btn-link" href="{{ route('password.request') }}">
+ {{ __('Forgot Your Password?') }}
+ </a>
+ @endif
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+@endsection
diff --git a/resources/views/auth/passwords/email.blade.php b/resources/views/auth/passwords/email.blade.php
new file mode 100644
index 0000000..1fea984
--- /dev/null
+++ b/resources/views/auth/passwords/email.blade.php
@@ -0,0 +1,47 @@
+@extends('layouts.app')
+
+@section('content')
+<div class="container">
+ <div class="row justify-content-center">
+ <div class="col-md-8">
+ <div class="card">
+ <div class="card-header">{{ __('Reset Password') }}</div>
+
+ <div class="card-body">
+ @if (session('status'))
+ <div class="alert alert-success" role="alert">
+ {{ session('status') }}
+ </div>
+ @endif
+
+ <form method="POST" action="{{ route('password.email') }}">
+ @csrf
+
+ <div class="form-group row">
+ <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
+
+ <div class="col-md-6">
+ <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email" autofocus>
+
+ @error('email')
+ <span class="invalid-feedback" role="alert">
+ <strong>{{ $message }}</strong>
+ </span>
+ @enderror
+ </div>
+ </div>
+
+ <div class="form-group row mb-0">
+ <div class="col-md-6 offset-md-4">
+ <button type="submit" class="btn btn-primary">
+ {{ __('Send Password Reset Link') }}
+ </button>
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+@endsection
diff --git a/resources/views/auth/passwords/reset.blade.php b/resources/views/auth/passwords/reset.blade.php
new file mode 100644
index 0000000..989931d
--- /dev/null
+++ b/resources/views/auth/passwords/reset.blade.php
@@ -0,0 +1,65 @@
+@extends('layouts.app')
+
+@section('content')
+<div class="container">
+ <div class="row justify-content-center">
+ <div class="col-md-8">
+ <div class="card">
+ <div class="card-header">{{ __('Reset Password') }}</div>
+
+ <div class="card-body">
+ <form method="POST" action="{{ route('password.update') }}">
+ @csrf
+
+ <input type="hidden" name="token" value="{{ $token }}">
+
+ <div class="form-group row">
+ <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
+
+ <div class="col-md-6">
+ <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ $email ?? old('email') }}" required autocomplete="email" autofocus>
+
+ @error('email')
+ <span class="invalid-feedback" role="alert">
+ <strong>{{ $message }}</strong>
+ </span>
+ @enderror
+ </div>
+ </div>
+
+ <div class="form-group row">
+ <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
+
+ <div class="col-md-6">
+ <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">
+
+ @error('password')
+ <span class="invalid-feedback" role="alert">
+ <strong>{{ $message }}</strong>
+ </span>
+ @enderror
+ </div>
+ </div>
+
+ <div class="form-group row">
+ <label for="password-confirm" class="col-md-4 col-form-label text-md-right">{{ __('Confirm Password') }}</label>
+
+ <div class="col-md-6">
+ <input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
+ </div>
+ </div>
+
+ <div class="form-group row mb-0">
+ <div class="col-md-6 offset-md-4">
+ <button type="submit" class="btn btn-primary">
+ {{ __('Reset Password') }}
+ </button>
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+@endsection
diff --git a/resources/views/auth/register.blade.php b/resources/views/auth/register.blade.php
new file mode 100644
index 0000000..d236a48
--- /dev/null
+++ b/resources/views/auth/register.blade.php
@@ -0,0 +1,77 @@
+@extends('layouts.app')
+
+@section('content')
+<div class="container">
+ <div class="row justify-content-center">
+ <div class="col-md-8">
+ <div class="card">
+ <div class="card-header">{{ __('Register') }}</div>
+
+ <div class="card-body">
+ <form method="POST" action="{{ route('register') }}">
+ @csrf
+
+ <div class="form-group row">
+ <label for="name" class="col-md-4 col-form-label text-md-right">{{ __('Name') }}</label>
+
+ <div class="col-md-6">
+ <input id="name" type="text" class="form-control @error('name') is-invalid @enderror" name="name" value="{{ old('name') }}" required autocomplete="name" autofocus>
+
+ @error('name')
+ <span class="invalid-feedback" role="alert">
+ <strong>{{ $message }}</strong>
+ </span>
+ @enderror
+ </div>
+ </div>
+
+ <div class="form-group row">
+ <label for="email" class="col-md-4 col-form-label text-md-right">{{ __('E-Mail Address') }}</label>
+
+ <div class="col-md-6">
+ <input id="email" type="email" class="form-control @error('email') is-invalid @enderror" name="email" value="{{ old('email') }}" required autocomplete="email">
+
+ @error('email')
+ <span class="invalid-feedback" role="alert">
+ <strong>{{ $message }}</strong>
+ </span>
+ @enderror
+ </div>
+ </div>
+
+ <div class="form-group row">
+ <label for="password" class="col-md-4 col-form-label text-md-right">{{ __('Password') }}</label>
+
+ <div class="col-md-6">
+ <input id="password" type="password" class="form-control @error('password') is-invalid @enderror" name="password" required autocomplete="new-password">
+
+ @error('password')
+ <span class="invalid-feedback" role="alert">
+ <strong>{{ $message }}</strong>
+ </span>
+ @enderror
+ </div>
+ </div>
+
+ <div class="form-group row">
+ <label for="password-confirm" class="col-md-4 col-form-label text-md-right">{{ __('Confirm Password') }}</label>
+
+ <div class="col-md-6">
+ <input id="password-confirm" type="password" class="form-control" name="password_confirmation" required autocomplete="new-password">
+ </div>
+ </div>
+
+ <div class="form-group row mb-0">
+ <div class="col-md-6 offset-md-4">
+ <button type="submit" class="btn btn-primary">
+ {{ __('Register') }}
+ </button>
+ </div>
+ </div>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+@endsection
diff --git a/resources/views/auth/verify.blade.php b/resources/views/auth/verify.blade.php
new file mode 100644
index 0000000..9f8c1bc
--- /dev/null
+++ b/resources/views/auth/verify.blade.php
@@ -0,0 +1,28 @@
+@extends('layouts.app')
+
+@section('content')
+<div class="container">
+ <div class="row justify-content-center">
+ <div class="col-md-8">
+ <div class="card">
+ <div class="card-header">{{ __('Verify Your Email Address') }}</div>
+
+ <div class="card-body">
+ @if (session('resent'))
+ <div class="alert alert-success" role="alert">
+ {{ __('A fresh verification link has been sent to your email address.') }}
+ </div>
+ @endif
+
+ {{ __('Before proceeding, please check your email for a verification link.') }}
+ {{ __('If you did not receive the email') }},
+ <form class="d-inline" method="POST" action="{{ route('verification.resend') }}">
+ @csrf
+ <button type="submit" class="btn btn-link p-0 m-0 align-baseline">{{ __('click here to request another') }}</button>.
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+@endsection
diff --git a/resources/views/home.blade.php b/resources/views/home.blade.php
new file mode 100644
index 0000000..05dfca9
--- /dev/null
+++ b/resources/views/home.blade.php
@@ -0,0 +1,23 @@
+@extends('layouts.app')
+
+@section('content')
+<div class="container">
+ <div class="row justify-content-center">
+ <div class="col-md-8">
+ <div class="card">
+ <div class="card-header">Dashboard</div>
+
+ <div class="card-body">
+ @if (session('status'))
+ <div class="alert alert-success" role="alert">
+ {{ session('status') }}
+ </div>
+ @endif
+
+ You are logged in!
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+@endsection
diff --git a/resources/views/index.blade.php b/resources/views/index.blade.php
new file mode 100644
index 0000000..659cc06
--- /dev/null
+++ b/resources/views/index.blade.php
@@ -0,0 +1,25 @@
+@extends('layouts.app')
+
+@section('styles')
+@endsection
+
+@section('content')
+
+@if ( "index" == Request::route()->getName() )
+<div class="text-center">
+ <div class="cover-container d-flex w-100 h-100 p-3 mx-auto flex-column">
+
+ <div role="main" class="inner cover">
+ <h1 class="cover-heading">The Worlds Knowledge - Curated and Filtered.</h1>
+ <p class="lead">
+ Best of Wikipedia, filtered, tagged and discussed. <br>For the curious reader.
+ </p>
+ <p class="lead">
+ <a href="{{ route('popular') }}" class="btn btn-lg btn-outline-primary">Most Popular</a>
+ </p>
+ </div>
+
+</div>
+</div>
+ @endif
+@endsection
diff --git a/resources/views/layouts/app.blade.php b/resources/views/layouts/app.blade.php
new file mode 100644
index 0000000..a9cbf37
--- /dev/null
+++ b/resources/views/layouts/app.blade.php
@@ -0,0 +1,115 @@
+<!doctype html>
+<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
+<head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+
+ <!-- CSRF Token -->
+ <meta name="csrf-token" content="{{ csrf_token() }}">
+
+ <title>{{ config('app.name', 'Laravel') }}@if( "index" != Request::route()->getName() ) - {{ ucwords(Request::route()->getName()) }} Articles @endif</title>
+
+ <!-- Scripts -->
+ <script src="{{ asset('js/app.js') }}" defer></script>
+
+ <!-- Fonts -->
+ <link rel="dns-prefetch" href="//fonts.gstatic.com">
+ <link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet">
+
+ <!-- Styles -->
+ <link href="{{ asset('css/app.css') }}" rel="stylesheet">
+
+ <style>
+ @yield('styles')
+ </style>
+</head>
+<body>
+ <div id="app">
+ <nav class="navbar navbar-expand-md navbar-dark shadow-sm">
+ <div class="container">
+ <a class="navbar-brand" href="{{ url('/') }}">
+ {{ config('app.name', 'Laravel') }}
+ </a>
+ <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="{{ __('Toggle navigation') }}">
+ <span class="navbar-toggler-icon"></span>
+ </button>
+
+ <div class="collapse navbar-collapse" id="navbarSupportedContent">
+ <!-- Left Side Of Navbar -->
+ <ul class="navbar-nav mr-auto">
+
+ </ul>
+
+ <!-- Right Side Of Navbar -->
+ <ul class="navbar-nav ml-auto">
+ <!-- Authentication Links -->
+ @guest
+ @if (Route::has('login'))
+ <li class="nav-item">
+ <a class="nav-link" href="{{ route('login') }}">{{ __('Login') }}</a>
+ </li>
+ @endif
+ @if (Route::has('register'))
+ <li class="nav-item">
+ <a class="nav-link" href="{{ route('register') }}">{{ __('Register') }}</a>
+ </li>
+ @endif
+ <li class="nav-item">
+ <a class="nav-link" href="{{ route('newest') }}">{{ __('New') }}</a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" href="{{ route('popular') }}">{{ __('Popular') }}</a>
+ </li>
+ <li class="nav-item">
+ <a class="nav-link" href="{{ route('random') }}">{{ __('Random') }}</a>
+ </li>
+ @else
+ <li class="nav-item dropdown">
+ <a id="navbarDropdown" class="nav-link dropdown-toggle" href="#" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false" v-pre>
+ {{ Auth::user()->name }} <span class="caret"></span>
+ </a>
+
+ <div class="dropdown-menu dropdown-menu-right" aria-labelledby="navbarDropdown">
+ <a class="dropdown-item" href="{{ route('logout') }}"
+ onclick="event.preventDefault();
+ document.getElementById('logout-form').submit();">
+ {{ __('Logout') }}
+ </a>
+
+ <form id="logout-form" action="{{ route('logout') }}" method="POST" style="display: none;">
+ @csrf
+ </form>
+ </div>
+ </li>
+ @endguest
+ <form class="form-inline mt-2 mt-md-0 navbar-searchform" action="{{ route('search') }}">
+ <input name="q" class="form-control mr-sm-2" type="text" placeholder="Search" aria-label="Search" required>
+ <button class="btn btn-outline-primary my-2 my-sm-0" type="submit">Search</button>
+ </form>
+ </ul>
+ </div>
+ </div>
+ </nav>
+
+ <main class="py-4">
+ @yield('content')
+ </main>
+ </div>
+@if ( "" != env( "MATOMO_ID" ) )
+<script type="text/javascript">
+ var _paq = window._paq || [];
+ /* tracker methods like "setCustomDimension" should be called before "trackPageView" */
+ _paq.push(['trackPageView']);
+ _paq.push(['enableLinkTracking']);
+ (function() {
+ var u="https://a.iamfabulous.de/";
+ _paq.push(['setTrackerUrl', u+'matomo.php']);
+ _paq.push(['setSiteId', '{{env( "MATOMO_ID" )}}']);
+ var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
+ g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
+ })();
+</script>
+<noscript><p><img src="https://a.iamfabulous.de/matomo.php?idsite=39&amp;rec=1" style="border:0;" alt="" /></p></noscript>
+@endif
+</body>
+</html>
diff --git a/resources/views/list.blade.php b/resources/views/list.blade.php
new file mode 100644
index 0000000..82d53e5
--- /dev/null
+++ b/resources/views/list.blade.php
@@ -0,0 +1,126 @@
+@extends('layouts.app')
+
+@section('styles')
+@if ( 0 != $count )
+html {
+ height: inherit;
+}
+.hn {
+ display: inline-block;
+ font-size: inherit;
+ height: 1em;
+ overflow: visible;
+ vertical-align: -.125em;
+ fill: #ff6600;
+}
+@endif
+@endsection
+
+@section('content')
+ <div class="container">
+
+ <div style="margin-top: 20px"></div>
+ <div class="card">
+ @if ( "search" == Request::route()->getName() )
+ <h1 class="card-header">
+ Search for <strong>"{{ Request::input("q") }}"</strong>
+ @if ( "1" != $articles->currentPage() )
+ (Page {{ $articles->currentPage() }})
+ @endif
+ </h1>
+ <div class="card-body">
+ <p class="card-text">
+ You searched for <strong>"{{ Request::input("q") }}"</strong>. We found {{ $count }} matches.
+ </p>
+ @include("search")
+ </div>
+ @elseif ( "topic" == Request::route()->getName() )
+ <h1 class="card-header">
+ Topic: <strong>{{ Request::route()->parameters()["topic"] }}</strong>
+ @if ( "1" != $articles->currentPage() )
+ (Page {{ $articles->currentPage() }})
+ @endif
+ </h1>
+ <div class="card-body">
+ <p class="card-text">
+ You are looking at all articles with the topic <strong>"{{ Request::route()->parameters()["topic"] }}"</strong>. We found {{ $count }} matches.
+ </p>
+ </div>
+ @elseif ( "random" == Request::route()->getName() )
+ <h1 class="card-header">
+ {{ ucwords(Request::route()->getName()) }} Articles
+ @if ( "1" != $articles->currentPage() )
+ (Page {{ $articles->currentPage() }})
+ @endif
+ </h1>
+ <div class="card-body">
+ <p class="card-text">
+ Have a deep view into what people are curious about.
+ </p>
+ </div>
+ @else
+ <h1 class="card-header">
+ Most {{ ucwords(Request::route()->getName()) }} Articles
+ @if ( "1" != $articles->currentPage() )
+ (Page {{ $articles->currentPage() }})
+ @endif
+ </h1>
+
+ @endif
+ </div>
+ <div style="margin-bottom: 20px"></div>
+
+ @foreach( $articles->all() as $article)
+ <div class="card">
+ <h1 class="card-header">
+ <a style="color:inherit;" href="{{ $article->url }}" title="{{ $article->title }}">
+ {{ $article->title }}
+ </a>
+ </h1>
+ <div class="card-body">
+ @if ( ! is_null($article->getCategories()) )
+ @foreach ( $article->getCategories()->get() as $cat )
+ <a class="badge badge-pill badge-primary" href="/topic/{{ $cat->name }}">
+ {{ $cat->name }}
+ </a>
+ @endforeach
+ @endif
+ <p class="card-text">
+ {!! $article->excerpt_html !!}
+ </p>
+
+
+ @if ( 0 != $article->comments )
+ <div class="row">
+ <div class="col">
+ <h3 class="card-subtitle">Discussed on</h3>
+ <ul class="list-unstyled">
+ @foreach ( $article->where('id', $article->article_id)->first()->getDiscussions()->orderBy('comments', 'desc')->get() as $discussion )
+ @if ( 0 != $discussion->comments )
+ <li>
+ <a class="card-links" href="{{ $discussion->source_url }}">
+ @if ( "HN" == $discussion->source )
+ {!! file_get_contents(public_path() . "/img/y-combinator.svg") !!}
+ @endif
+ "{{ $discussion->title }}"
+ </a>
+ | {{ \App\Libraries\Helper::formatTimestamp($discussion->posted_on) }} |
+ <span class="badge badge-pill badge-secondary">{{ $discussion->upvotes }} Upvotes</span>
+ <span class="badge badge-pill badge-secondary">{{ $discussion->comments }} Comments </span>
+ </li>
+ @endif
+ @endforeach
+ </ul>
+ </div>
+ </div>
+ @endif
+ </div>
+ </div>
+
+ <div style="margin-bottom: 20px"></div>
+ @endforeach
+
+ {{ $articles->links() }}
+
+ </div>
+@endsection
diff --git a/resources/views/search.blade.php b/resources/views/search.blade.php
new file mode 100644
index 0000000..74669be
--- /dev/null
+++ b/resources/views/search.blade.php
@@ -0,0 +1,19 @@
+ <form>
+ <div class="form-row align-items-center">
+ <div class="col-auto">
+ <label class="sr-only" for="inlineFormInput">Search</label>
+ <input type="text" class="form-control mb-2" id="q" name="q" placeholder="Search..." required>
+ </div>
+ <div class="col-auto">
+ <div class="form-check mb-2">
+ <input class="form-check-input" type="checkbox" id="onlypopular" name="onlypopular">
+ <label class="form-check-label" for="onlypopular">
+ Click to filter for only popular entries
+ </label>
+ </div>
+ </div>
+ <div class="col-auto">
+ <button type="submit" class="btn btn-primary mb-2">Search</button>
+ </div>
+ </div>
+ </form>
diff --git a/resources/views/topicindex.blade.php b/resources/views/topicindex.blade.php
new file mode 100644
index 0000000..8ef2114
--- /dev/null
+++ b/resources/views/topicindex.blade.php
@@ -0,0 +1,18 @@
+@extends('layouts.app')
+
+@section('styles')
+html {
+ height: inherit;
+}
+@endsection
+
+@section('content')
+
+<div class="text-center container">
+@foreach ($topics->get() as $topic)
+ @if ( "" != $topic->name )
+ <a href="{{ route('topic', $topic->name) }}" class="btn btn-lg btn-outline-primary">{{ ucwords($topic->name) }}</a>
+ @endif
+@endforeach
+</div>
+@endsection
diff --git a/resources/views/welcome.blade.php b/resources/views/welcome.blade.php
new file mode 100644
index 0000000..3fb48cc
--- /dev/null
+++ b/resources/views/welcome.blade.php
@@ -0,0 +1,100 @@
+<!DOCTYPE html>
+<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
+ <head>
+ <meta charset="utf-8">
+ <meta name="viewport" content="width=device-width, initial-scale=1">
+
+ <title>Laravel</title>
+
+ <!-- Fonts -->
+ <link href="https://fonts.googleapis.com/css?family=Nunito:200,600" rel="stylesheet">
+
+ <!-- Styles -->
+ <style>
+ html, body {
+ background-color: #fff;
+ color: #636b6f;
+ font-family: 'Nunito', sans-serif;
+ font-weight: 200;
+ height: 100vh;
+ margin: 0;
+ }
+
+ .full-height {
+ height: 100vh;
+ }
+
+ .flex-center {
+ align-items: center;
+ display: flex;
+ justify-content: center;
+ }
+
+ .position-ref {
+ position: relative;
+ }
+
+ .top-right {
+ position: absolute;
+ right: 10px;
+ top: 18px;
+ }
+
+ .content {
+ text-align: center;
+ }
+
+ .title {
+ font-size: 84px;
+ }
+
+ .links > a {
+ color: #636b6f;
+ padding: 0 25px;
+ font-size: 13px;
+ font-weight: 600;
+ letter-spacing: .1rem;
+ text-decoration: none;
+ text-transform: uppercase;
+ }
+
+ .m-b-md {
+ margin-bottom: 30px;
+ }
+ </style>
+ </head>
+ <body>
+ <div class="flex-center position-ref full-height">
+ @if (Route::has('login'))
+ <div class="top-right links">
+ @auth
+ <a href="{{ url('/home') }}">Home</a>
+ @else
+ <a href="{{ route('login') }}">Login</a>
+
+ @if (Route::has('register'))
+ <a href="{{ route('register') }}">Register</a>
+ @endif
+ @endauth
+ </div>
+ @endif
+
+ <div class="content">
+ <div class="title m-b-md">
+ Laravel
+ </div>
+
+ <div class="links">
+ <a href="https://laravel.com/docs">Docs</a>
+ <a href="https://laracasts.com">Laracasts</a>
+ <a href="https://laravel-news.com">News</a>
+ <a href="https://blog.laravel.com">Blog</a>
+ <a href="https://nova.laravel.com">Nova</a>
+ <a href="https://forge.laravel.com">Forge</a>
+ <a href="https://vapor.laravel.com">Vapor</a>
+ <a href="https://github.com/laravel/laravel">GitHub</a>
+ </div>
+ </div>
+ </div>
+ </body>
+</html>