@@ -34,7 +34,8 @@ class UserController extends Controller | |||
$user->active = true; | |||
$user->password = Hash::make($request->password); | |||
$user->customer_id = Customer::create(['email' => | |||
$request->email], 'name' => $request->name, 'metadata' => ['user_id' => $user->id])->id; | |||
$request->email, 'name' => $request->name, 'metadata' => ['user_id' | |||
=> $user->id]])->id; | |||
$user->save(); | |||
event(new Registered($user)); | |||
@@ -91,7 +92,6 @@ class UserController extends Controller | |||
//It should have an orderBy clause to make sure the most recent are first | |||
//This should limit non pending orders to 50. Should also return a json of all services | |||
public function getOrders(Request $request) { | |||
/* Log::debug(Auth::user()->orders()->service_name); */ | |||
return Auth::user()->orders()->with('service')->withCasts(['updated_at' | |||
=> 'datetime:d-m-Y'])->latest()->get(); | |||
} | |||
@@ -123,6 +123,7 @@ class UserController extends Controller | |||
public function resetEmail(Request $request) { | |||
Stripe::setApiKey(env('STRIPE_SECRET')); | |||
if (! $request->hasValidSignature()) { | |||
abort(401); | |||
} | |||
@@ -20,7 +20,8 @@ class CreateUsersTable extends Migration | |||
$table->string('customer_id')->unique(); | |||
$table->timestamp('email_verified_at')->nullable(); | |||
$table->string('password'); | |||
$table->string('role'); | |||
$table->enum('role', ['client', 'guest', 'admin']); | |||
$table->string('payment_method'); | |||
$table->boolean('active')->default(true); | |||
$table->unsignedBigInteger('credits')->default(0); | |||
$table->rememberToken(); | |||
@@ -0,0 +1,87 @@ | |||
<template> | |||
<div v-if="cards && cards.length > 0"> | |||
<div class="saved-cards-heading"> | |||
<h5>Card</h5> <h5>Default</h5> <h5>Delete</h5> | |||
</div> | |||
<div v-for="(card, index) in cards" :key="card.id" class="saved-card"> | |||
<span>{{card.card.brand[0].toUpperCase() + card.card.brand.substring(1)}} | |||
(••••{{card.card.last4}})</span> | |||
<span><input :checked="index === 0" :value="card.id" name="selected-card" type="radio" | |||
@change="change(card.id)"></span> | |||
<span><img @click="remove(card.id)" src="../../images/close-icon-black.svg"/></span> | |||
</div> | |||
<p id="billing-error"></p> | |||
</div> | |||
</template> | |||
<script> | |||
function get() { | |||
fetch('/panel/cards', { | |||
method: 'GET', | |||
headers: {'Content-Type': 'application/json', | |||
'Accept': 'application/json', | |||
'X-XSRF-TOKEN': this.token} | |||
}).then((response) => {response.json().then(data => { | |||
this.cards = data.data | |||
})}) | |||
} | |||
function change(card) { | |||
fetch('/panel/change-card', { | |||
method: 'POST', | |||
headers: {'Content-Type': 'application/json', | |||
'Accept': 'application/json', | |||
'X-XSRF-TOKEN': this.token}, | |||
body: JSON.stringify({'card': card}) | |||
}).then((response) => { | |||
if (response.ok) { | |||
console.log('ok') | |||
response.json().then((data) => { | |||
this.cards = data | |||
}) | |||
} else { | |||
console.log('bad') | |||
document.getElementById("billing-error").textContent = | |||
`${response.status}: ${response.statusText}` | |||
} | |||
response.json().then(data => { | |||
console.log(data)} | |||
) | |||
}) | |||
} | |||
function remove(card) { | |||
fetch('/panel/delete-card', { | |||
method: 'POST', | |||
headers: {'Content-Type': 'application/json', | |||
'Accept': 'application/json', | |||
'X-XSRF-TOKEN': this.token}, | |||
body: JSON.stringify({'card': card}) | |||
}).then((response) => { | |||
if (response.ok) { | |||
console.log('ok') | |||
response.json().then((data) => { | |||
this.cards = data | |||
}) | |||
} else { | |||
console.log('bad') | |||
document.getElementById("billing-error").textContent = | |||
`${response.status}: ${response.statusText}` | |||
} | |||
response.json().then(data => { | |||
console.log(data)} | |||
) | |||
}) | |||
} | |||
export default { | |||
data() { | |||
return {cards: null} | |||
}, | |||
methods: {get, change, remove}, | |||
created() { | |||
this.get() | |||
}, | |||
props: ['token',], | |||
} | |||
</script> |
@@ -1,8 +1,11 @@ | |||
<template> | |||
<div> | |||
<section class="change-name-pane"> | |||
<h3>Settings</h3> | |||
<section class="billing-pane"> | |||
<h4>Billing</h4> | |||
<edit-cards :token="token"></edit-cards> | |||
</section> | |||
<section class="change-name-pane"> | |||
<h4>Name</h4> | |||
<input :value="user.name" name="name" id="changed_name" type="text"> | |||
<button @click="changeName">Save <loading src="../../images/loading-white.svg" alt=""></loading></button> | |||
@@ -27,6 +30,7 @@ | |||
<script> | |||
import Loading from '../icons/loading.vue' | |||
import EditCards from './edit-cards.vue' | |||
function changeName() { | |||
let name = document.getElementById('changed_name').value | |||
@@ -107,7 +111,7 @@ function changePassword() { | |||
} | |||
export default { | |||
components: {Loading}, | |||
components: {Loading, EditCards}, | |||
methods: { | |||
changePassword, changeName, changeEmail | |||
}, | |||
@@ -1272,3 +1272,42 @@ div#card-errors { | |||
display: block; | |||
} | |||
} | |||
.saved-cards-heading { | |||
display: flex; | |||
align-items: center; | |||
justify-content: space-around; | |||
max-width: 25em; | |||
margin: auto; | |||
h5 { | |||
margin: 0; | |||
} | |||
} | |||
.settings-page .saved-card { | |||
max-width: 25em; | |||
// align-items: start; | |||
justify-content: space-between; | |||
margin-top: 1em; | |||
> * { | |||
min-width: 20%; | |||
} | |||
img { | |||
width: 15px; | |||
display: block; | |||
} | |||
input { | |||
display: block; | |||
margin: auto; | |||
} | |||
} | |||
.saved-card button { | |||
width: 3em; | |||
height: 2em; | |||
} |