added profile editor
This commit is contained in:
parent
cebed5a145
commit
261ba469a1
|
@ -0,0 +1,46 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers;
|
||||||
|
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
use Illuminate\Support\Facades\Auth;
|
||||||
|
use Illuminate\Validation\ValidationException;
|
||||||
|
use Illuminate\Validation\Rule;
|
||||||
|
|
||||||
|
class ProfileController extends Controller {
|
||||||
|
public function update(Request $request) {
|
||||||
|
$user = Auth::user();
|
||||||
|
try {
|
||||||
|
$request->validate([
|
||||||
|
'name' => [
|
||||||
|
'required',
|
||||||
|
'string',
|
||||||
|
'max:28',
|
||||||
|
Rule::unique('users')->ignore($user->id), // Ignore current user
|
||||||
|
],
|
||||||
|
'email' => [
|
||||||
|
'required',
|
||||||
|
'string',
|
||||||
|
'email',
|
||||||
|
Rule::unique('users')->ignore($user->id), // Ignore current user
|
||||||
|
],
|
||||||
|
]);
|
||||||
|
} catch (ValidationException $e) {
|
||||||
|
return redirect()->back()->withInput($request->input())->withErrors($e->errors());
|
||||||
|
}
|
||||||
|
$user->name = $request->input('name');
|
||||||
|
$user->email = $request->input('email');
|
||||||
|
$user->save();
|
||||||
|
return redirect('profile')->with('success', 'Profile updated successfully');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updatePassword(Request $request) {
|
||||||
|
$user = Auth::user();
|
||||||
|
$request->validate([
|
||||||
|
'password' => 'required|string|min:8|confirmed'
|
||||||
|
]);
|
||||||
|
$user->password = bcrypt($request->input('password'));
|
||||||
|
$user->save();
|
||||||
|
return redirect('profile')->with('success', 'Password updated successfully');
|
||||||
|
}
|
||||||
|
}
|
|
@ -93,6 +93,16 @@ header nav a {
|
||||||
box-shadow: 3px 3px 10px 0 #0008;
|
box-shadow: 3px 3px 10px 0 #0008;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#profile-container {
|
||||||
|
margin: 5vh auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button-row {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
.form-container form {
|
.form-container form {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
|
@ -108,6 +118,12 @@ header nav a {
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.form-container form input.unmodifiable {
|
||||||
|
color: #aaa;
|
||||||
|
border: none;
|
||||||
|
pointer-events: none;
|
||||||
|
}
|
||||||
|
|
||||||
.form-container form label {
|
.form-container form label {
|
||||||
color: #666;
|
color: #666;
|
||||||
font-size: 0.8em;
|
font-size: 0.8em;
|
||||||
|
@ -139,6 +155,16 @@ header nav a {
|
||||||
background: #ff000028;
|
background: #ff000028;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.form-container .success {
|
||||||
|
width: 280px;
|
||||||
|
color: #00bb00;
|
||||||
|
background: #00ff0028;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 10px;
|
||||||
|
margin-bottom: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#banner-container {
|
#banner-container {
|
||||||
|
@ -367,6 +393,11 @@ header nav a {
|
||||||
|
|
||||||
#destination {
|
#destination {
|
||||||
max-width: 850px;
|
max-width: 850px;
|
||||||
|
word-break: break-all;
|
||||||
|
height: 1.2em;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
}
|
}
|
||||||
|
|
||||||
button {
|
button {
|
||||||
|
|
|
@ -19,9 +19,9 @@
|
||||||
@csrf
|
@csrf
|
||||||
<div id="info-container">
|
<div id="info-container">
|
||||||
<label id="destination-label" for="destination">Destination</label>
|
<label id="destination-label" for="destination">Destination</label>
|
||||||
<a href="{{ $shortlink->destination }}" target="_blank" id="destination">{{ $shortlink->destination }}<button title="Copy Link" id="destination_clipboard">🔗</button></a>
|
<a href="{{ $shortlink->destination }}" target="_blank" id="destination"><button title="Copy Link" id="destination_clipboard">🔗</button>{{ $shortlink->destination }}</a>
|
||||||
<label id="URL-label" for="url">URL</label>
|
<label id="URL-label" for="url">URL</label>
|
||||||
<a href="{{ url()->to($shortlink->shortid) }}" target="_blank" id="url">{{ url()->to($shortlink->shortid) }}<button title="Copy Link" id="url_clipboard">🔗</button></a>
|
<a href="{{ url()->to($shortlink->shortid) }}" target="_blank" id="url"><button title="Copy Link" id="url_clipboard">🔗</button>{{ url()->to($shortlink->shortid) }}</a>
|
||||||
<label id="maxclicks-label" for="maxclicks">Max Clicks</label>
|
<label id="maxclicks-label" for="maxclicks">Max Clicks</label>
|
||||||
<img id="maxclicks-info" class="info" src="{{ asset("img/icons/info.svg") }}" title="This link will stop working after the maximum number of clicks has been reached. Set this to 0 to allow an infinite number of uses.">
|
<img id="maxclicks-info" class="info" src="{{ asset("img/icons/info.svg") }}" title="This link will stop working after the maximum number of clicks has been reached. Set this to 0 to allow an infinite number of uses.">
|
||||||
<input id="maxclicks" name="maxclicks" type="number" value="{{ $shortlink->max_clicks }}" required>
|
<input id="maxclicks" name="maxclicks" type="number" value="{{ $shortlink->max_clicks }}" required>
|
||||||
|
@ -87,12 +87,28 @@
|
||||||
<th>Country</th>
|
<th>Country</th>
|
||||||
<th>Clicks</th>
|
<th>Clicks</th>
|
||||||
</thead>
|
</thead>
|
||||||
|
@php
|
||||||
|
$total = 0;
|
||||||
|
$rows = [];
|
||||||
|
@endphp
|
||||||
@foreach ($countrylist as $country)
|
@foreach ($countrylist as $country)
|
||||||
<tr>
|
@php
|
||||||
<td>{{ $country['emoji'] }}</td>
|
$total += $country['total'];
|
||||||
<td>{{ $country['country'] ?? 'Unknown' }}</td>
|
$row = "<tr>
|
||||||
<td>{{ $country['total'] }}</td>
|
<td>" . $country['emoji'] . "</td>
|
||||||
</tr>
|
<td>" . ($country['country'] ?? 'Unknown') . "</td>
|
||||||
|
<td>" . $country['total'] . "</td>
|
||||||
|
</tr>";
|
||||||
|
array_push($rows, $row);
|
||||||
|
@endphp
|
||||||
|
@endforeach
|
||||||
|
<tr>
|
||||||
|
<td>🌎</td>
|
||||||
|
<td>Total</td>
|
||||||
|
<td>{{ $total }}</td>
|
||||||
|
</tr>
|
||||||
|
@foreach ($rows as $row)
|
||||||
|
{!! $row !!}
|
||||||
@endforeach
|
@endforeach
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
<form method="post" action="login">
|
<form method="post" action="login">
|
||||||
@csrf
|
@csrf
|
||||||
<label for="email">Email</label>
|
<label for="email">Email</label>
|
||||||
<input type="email" name="email" id="email" value="{{ old('email') }}" required>
|
<input type="email" name="email" id="email" value="{{ old('email') }}">
|
||||||
<label for="password">Password</label>
|
<label for="password">Password</label>
|
||||||
<input type="password" name="password" id="password" required>
|
<input type="password" name="password" id="password" required>
|
||||||
<button type="submit">Log In</button>
|
<button type="submit">Log In</button>
|
||||||
|
|
|
@ -0,0 +1,24 @@
|
||||||
|
@extends('default')
|
||||||
|
|
||||||
|
@section('title')
|
||||||
|
Change Password
|
||||||
|
@endsection
|
||||||
|
|
||||||
|
@section('content')
|
||||||
|
<div id="register" class="form-container">
|
||||||
|
<h1>Change Password</h1>
|
||||||
|
<form method="post" action="change-password/update">
|
||||||
|
@csrf
|
||||||
|
<label for="name">Username</label>
|
||||||
|
<input type="text" name="name" id="name" class="unmodifiable" value="{{ Auth::user()->name }}" readonly required>
|
||||||
|
<label for="password">New Password</label>
|
||||||
|
<input type="password" name="password" id="password" required>
|
||||||
|
<label for="password_confirmation">Confirm Password</label>
|
||||||
|
<input type="password" name="password_confirmation" id="password_confirmation" required>
|
||||||
|
<button type="submit">Change Password</button>
|
||||||
|
</form>
|
||||||
|
@if ($errors->any())
|
||||||
|
<p class="error">{{ $errors->first() }}</p>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
@endsection
|
|
@ -5,13 +5,27 @@
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<div id="title-container" class="container">
|
<div id="profile-container" class="form-container"> <!-- TODO: Add ability to change & reverify email -->
|
||||||
<h1>Profile</h1>
|
<h1>Profile</h1>
|
||||||
</div>
|
<form method="post" action="profile/update">
|
||||||
<div id="profile-container" class="container"> <!-- TODO: Add ability to change & reverify email -->
|
@csrf
|
||||||
<p>Username: <em>{{ Auth::user()->name }}</em></p>
|
<label for="name">Username</label>
|
||||||
<p>Email: <em>{{ Auth::user()->email }}</em></p>
|
<input type="text" name="name" id="name" value="{{ Auth::user()->name }}" required>
|
||||||
<p>Created at: <em>{{ Auth::user()->created_at }}</em></p>
|
<label for="email">Email</label>
|
||||||
|
<input type="email" name="email" id="email" value="{{ Auth::user()->email }}" required>
|
||||||
|
<label for="created_at">Created On</label>
|
||||||
|
<input type="text" name="created_at" id="created_at" class="unmodifiable" value="{{ explode( " ", Auth::user()->created_at)[0] }}" required readonly>
|
||||||
|
<div class="button-row">
|
||||||
|
<button type="submit">Save</button>
|
||||||
|
<a href="profile/change-password"><button type="button">Change Password</button></a>
|
||||||
|
</div>
|
||||||
|
@if ($errors->any())
|
||||||
|
<p class="error">{{ $errors->first() }}</p>
|
||||||
|
@endif
|
||||||
|
@if (session('success'))
|
||||||
|
<p class="success">{{ session('success') }}</p>
|
||||||
|
@endif
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div id="table-container" class="container">
|
<div id="table-container" class="container">
|
||||||
<h2>My Short URLs</h2>
|
<h2>My Short URLs</h2>
|
||||||
|
|
|
@ -5,6 +5,7 @@ use Illuminate\Support\Facades\Route;
|
||||||
use App\Http\Controllers\RegisterController;
|
use App\Http\Controllers\RegisterController;
|
||||||
use App\Http\Controllers\LoginController;
|
use App\Http\Controllers\LoginController;
|
||||||
use App\Http\Controllers\ShortlinkController;
|
use App\Http\Controllers\ShortlinkController;
|
||||||
|
use App\Http\Controllers\ProfileController;
|
||||||
|
|
||||||
Route::get('/', function () {
|
Route::get('/', function () {
|
||||||
return redirect('/home');
|
return redirect('/home');
|
||||||
|
@ -35,6 +36,17 @@ Route::get('/logout', function () {
|
||||||
|
|
||||||
Route::get('/profile', [ShortlinkController::class, 'getLinksByUser']);
|
Route::get('/profile', [ShortlinkController::class, 'getLinksByUser']);
|
||||||
|
|
||||||
|
Route::get('/profile/change-password', function () {
|
||||||
|
if (!auth()->check()) {
|
||||||
|
return redirect('login');
|
||||||
|
}
|
||||||
|
return view('profile-change-password');
|
||||||
|
});
|
||||||
|
|
||||||
|
Route::post('/profile/update', [ProfileController::class, 'update']);
|
||||||
|
|
||||||
|
Route::post('/profile/change-password/update', [ProfileController::class, 'updatePassword']);
|
||||||
|
|
||||||
Route::get('/home', function () {
|
Route::get('/home', function () {
|
||||||
if (!auth()->check()) {
|
if (!auth()->check()) {
|
||||||
return view('home');
|
return view('home');
|
||||||
|
|
Loading…
Reference in New Issue