@@ -16,9 +16,8 @@ class UserController extends Controller | |||||
{ | { | ||||
public function create(Request $request) { | public function create(Request $request) { | ||||
$validated = $request->validate([ | $validated = $request->validate([ | ||||
'name' => 'required', | |||||
'name' => 'required|max:30', | |||||
'email' => 'required|email|unique:users,email', | 'email' => 'required|email|unique:users,email', | ||||
/* 'password' => 'required' */ | |||||
'password' => 'required|confirmed|min:8|regex:/[a-z]/|regex:/[A-Z]/|regex:/[0-9]/' | 'password' => 'required|confirmed|min:8|regex:/[a-z]/|regex:/[A-Z]/|regex:/[0-9]/' | ||||
]); | ]); | ||||
@@ -87,7 +86,27 @@ class UserController extends Controller | |||||
/* Log::debug(Auth::user()->orders()->service_name); */ | /* Log::debug(Auth::user()->orders()->service_name); */ | ||||
return Auth::user()->orders()->with('service')->withCasts(['updated_at' | return Auth::user()->orders()->with('service')->withCasts(['updated_at' | ||||
=> 'datetime:d-m-Y'])->get(); | => 'datetime:d-m-Y'])->get(); | ||||
} | |||||
public function changeName(Request $request) { | |||||
$validated = $request->validate([ | |||||
'name' => 'required|max:30' | |||||
]); | |||||
$user = Auth::user(); | |||||
$user->name = $request->name; | |||||
$user->save(); | |||||
return $user; | |||||
} | |||||
public function changeEmail(Request $request) { | |||||
$validated = $request->validate([ | |||||
'email' => 'required|email|unique:users,email', | |||||
]); | |||||
} | } | ||||
public function changePassword(Request $request) { | |||||
$validated = $request->validate([ | |||||
'password' => 'required|confirmed|min:8|regex:/[a-z]/|regex:/[A-Z]/|regex:/[0-9]/' | |||||
]); | |||||
} | |||||
} | } |
@@ -0,0 +1 @@ | |||||
<svg data-set="loaders" data-loading="lazy" width="30px" height="30px" data-src="https://s2.svgbox.net/loaders.svg?ic=oval" data-icon="oval" viewBox="0 0 38 38" xmlns="http://www.w3.org/2000/svg" stroke="white" color="" data-attributes-set="viewBox,xmlns,stroke,color" data-rendered="true"><g transform="translate(1 1)" stroke-width="2" fill="none" fill-rule="evenodd"><circle stroke-opacity=".5" cx="18" cy="18" r="18"></circle><path d="M36 18c0-9.94-8.06-18-18-18"><animateTransform attributeName="transform" type="rotate" from="0 18 18" to="360 18 18" dur="1s" repeatCount="indefinite"></animateTransform></path></g></svg> |
@@ -137,8 +137,8 @@ if (window.location.pathname == '/') { | |||||
} else if (window.location.pathname == '/verify-email') { | } else if (window.location.pathname == '/verify-email') { | ||||
document.getElementById('resend_verification').addEventListener("click", resendLink) | document.getElementById('resend_verification').addEventListener("click", resendLink) | ||||
} else if (window.location.pathname == '/panel') { | } else if (window.location.pathname == '/panel') { | ||||
if (!token) {getToken(app)} | |||||
const app = createApp(Panel).mount('#panel') | const app = createApp(Panel).mount('#panel') | ||||
getToken().then(()=> {app.token = token}) | |||||
window.onhashchange = ()=>{app.active = location.hash} | window.onhashchange = ()=>{app.active = location.hash} | ||||
getUser(app) | getUser(app) | ||||
getOrders(app) | getOrders(app) | ||||
@@ -74,20 +74,21 @@ | |||||
<section class="change-name-pane"> | <section class="change-name-pane"> | ||||
<h3>Settings</h3> | <h3>Settings</h3> | ||||
<h4>Name</h4> | <h4>Name</h4> | ||||
<input name="name" type="text"> | |||||
<button>Save</button> | |||||
<input :value="user.name" name="name" id="changed_name" type="text"> | |||||
<button @click="changeName">Save <img class="loading-icon" src="../../images/loading-white.svg" alt=""></button> | |||||
<span></span> | |||||
</section> | </section> | ||||
<section class="change-email-pane"> | <section class="change-email-pane"> | ||||
<h4>Email</h4> | <h4>Email</h4> | ||||
<input name="email" type="text"> | |||||
<button>Save</button> | |||||
<input :value="user.email" name="email" type="text" id="changed_email"> | |||||
<button @click="changeName">Save<img class="loading-icon" src="../../images/loading-white.svg" alt=""></button> | |||||
</section> | </section> | ||||
<section class="change-password-pane"> | <section class="change-password-pane"> | ||||
<h4>Change Password</h4> | <h4>Change Password</h4> | ||||
<h5>Current Password</h5><input name="current_passowrd" type="password"> | |||||
<h5>New Password</h5><input name="passowrd" type="password"> | |||||
<h5>Confirm Password</h5><input name="confirm_passowrd" type="password"> | |||||
<button>Save</button> | |||||
<h5>Current Password</h5><input name="current_passowrd" id="current_password" type="password"> | |||||
<h5>New Password</h5><input id="changed_password" name="passowrd" type="password"> | |||||
<h5>Confirm Password</h5><input id="confirm_password" name="confirm_passowrd" type="password"> | |||||
<button @click="changePassword">Save<img class="loading-icon" src="../../images/loading-white.svg" alt=""></button> | |||||
</section> | </section> | ||||
</div> | </div> | ||||
</transition> | </transition> | ||||
@@ -119,6 +120,32 @@ function moveHistory(forward) { | |||||
} | } | ||||
} | } | ||||
function changeName() { | |||||
let name = document.getElementById('changed_name').value | |||||
let info = document.querySelector('.change-name-pane span') | |||||
let pane = document.querySelector('.change-name-pane') | |||||
pane.classList.add('loading') | |||||
fetch("/panel/change-name", { | |||||
method: 'POST', | |||||
headers: {'Content-Type': 'application/json', | |||||
'Accept': 'application/json', | |||||
'X-XSRF-TOKEN': this.token}, | |||||
body: JSON.stringify({'name': name}), | |||||
}).then(response => { | |||||
if (response.ok) { | |||||
response.json().then(data => {this.user = data}) | |||||
pane.classList.add('completed') | |||||
info.textContent = 'Completed' | |||||
} else { | |||||
pane.classList.add('error') | |||||
info.textContent = 'Error:' + response.status | |||||
} | |||||
pane.classList.remove('loading') | |||||
}) | |||||
} | |||||
export default { | export default { | ||||
components: { | components: { | ||||
Sidebar, | Sidebar, | ||||
@@ -127,6 +154,6 @@ export default { | |||||
return {active: window.location.hash, user: '', | return {active: window.location.hash, user: '', | ||||
token: '', orders: '', historyPage: 1} | token: '', orders: '', historyPage: 1} | ||||
}, | }, | ||||
methods: {togglePending, toggleOrderItem, moveHistory} | |||||
methods: {togglePending, toggleOrderItem, moveHistory, changeName} | |||||
} | } | ||||
</script> | </script> |
@@ -43,6 +43,12 @@ ul { | |||||
padding: 0; | padding: 0; | ||||
} | } | ||||
input { | |||||
border: 2px solid black; | |||||
border-radius: 20px; | |||||
padding: 4px; | |||||
} | |||||
.services-cards li { | .services-cards li { | ||||
padding-bottom: 8px; | padding-bottom: 8px; | ||||
&:before { | &:before { | ||||
@@ -915,18 +921,39 @@ main.panel { | |||||
display: inline-block; | display: inline-block; | ||||
margin-right: 2em; | margin-right: 2em; | ||||
margin-top: 0; | margin-top: 0; | ||||
margin-bottom: 0.5em; | |||||
color: vars.getColor('brand-orange'); | color: vars.getColor('brand-orange'); | ||||
} | } | ||||
input { | input { | ||||
display: inline-block; | |||||
display: block; | |||||
margin-bottom: 1em; | margin-bottom: 1em; | ||||
right: 2px; | right: 2px; | ||||
margin-left: auto; | |||||
position: relative; | position: relative; | ||||
} | } | ||||
button { | button { | ||||
display: block; | |||||
&>*{vertical-align: middle;} | |||||
margin-right: 10px; | |||||
display: inline-block; | |||||
@include vars.inverting-button(vars.getColor('text-blue-medium'), white); | @include vars.inverting-button(vars.getColor('text-blue-medium'), white); | ||||
} | } | ||||
.loading-icon { | |||||
width: 1.5em; | |||||
height: 1.5em; | |||||
display: none; | |||||
} | |||||
.loading .loading-icon { | |||||
display: inline; | |||||
} | |||||
.completed span { | |||||
color: vars.getColor('green'); | |||||
} | |||||
.error span { | |||||
color: vars.getColor('red-alert'); | |||||
} | |||||
} | } |
@@ -64,3 +64,12 @@ Route::get('/panel/orders', [UserController::class, | |||||
Route::get('/logout', [UserController::class, | Route::get('/logout', [UserController::class, | ||||
'logout'])->middleware('auth'); | 'logout'])->middleware('auth'); | ||||
Route::post('/panel/change-name', [UserController::class, | |||||
'changeName'])->middleware('auth'); | |||||
Route::post('/panel/change-email', [UserController::class, | |||||
'changeEmail'])->middleware('auth'); | |||||
Route::post('/panel/change-password', [UserController::class, | |||||
'changePassword'])->middleware('auth'); |