diff options
Diffstat (limited to 'resources')
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' => '« Previous', + 'next' => 'Next »', + +]; 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&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> |
