added avatar & etc. to customer

master
A1Gard 3 weeks ago
parent d518446aef
commit 388a22f9cb

@ -10,6 +10,7 @@ use App\Models\Credit;
use App\Models\Customer;
use Illuminate\Http\Request;
use App\Helper;
use Spatie\Image\Image;
use function App\Helpers\hasCreateRoute;
class CustomerController extends XController
@ -50,6 +51,8 @@ class CustomerController extends XController
public function save($customer, $request)
{
// dd($request->all());
$customer->name = $request->input('name');
if ($customer->credit != $request->input('credit') && $customer->id != null){
$diff = $request->input('credit') - $customer->credit;
@ -67,11 +70,43 @@ class CustomerController extends XController
$customer->email = $request->input('email');
}
$customer->mobile = $request->input('mobile');
$customer->sex = $request->input('sex');
if ($request->has('height') && trim($request->input('height')) != '') {
$customer->height = $request->input('height',null);
}
if ($request->has('weight') && trim($request->input('weight')) != '') {
$customer->weight = $request->input('weight', null);
}
$customer->description = $request->input('description');
if (trim($request->input('password')) != '') {
$customer->password = bcrypt($request->input('password'));
}
if ($request->has('dob') && $request->dob != ''){
$customer->dob = date('Y-m-d',floor($request->dob));
}else{
$customer->dob = null;
}
if ($request->hasFile('avatar')) {
$name = time() . '.' . request()->avatar->getClientOriginalExtension();
$customer->avatar = $name;
$request->file('avatar')->storeAs('public/customers', $name);
$format = $request->file('avatar')->guessExtension();
$format = 'webp';
$key = 'avatar';
$i = Image::load($request->file($key)->getPathname())
->optimize()
->width(500)
->height(500)
->crop(500, 500)
// ->nonQueued()
->format($format);
$i->save(storage_path() . '/app/public/customers/'. $customer->avatar);
}
$customer->colleague = $request->has('colleague');
$customer->save();
return $customer;

@ -11,6 +11,10 @@ use chillerlan\QRCode\QRCode;
use chillerlan\QRCode\QROptions;
use Illuminate\Http\Request;
use Illuminate\Validation\Rules\In;
use Spatie\Image\Enums\AlignPosition;
use Spatie\Image\Enums\Fit;
use Spatie\Image\Enums\Unit;
use Spatie\Image\Image;
class CustomerController extends Controller
{
@ -62,16 +66,59 @@ class CustomerController extends Controller
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255'],
'mobile' => ['required', 'string', 'max:255'],
'height' => ['nullable', 'numeric'],
'weight' => ['nullable', 'numeric'],
'password' => ['nullable', 'string', 'min:8', 'confirmed'],
'sex' => ['required', 'in:MALE,FEMALE'],
'dob' => ['nullable', 'date'],
'avatar' => ['nullable', 'image', 'mimes:jpeg','max:2048'],
]);
// dd($request->all());
$customer = auth('customer')->user();
$customer->name = $request->name;
$customer->email = $request->email;
$customer->sex = $request->input('sex');
if ($request->has('height') && trim($request->input('height')) != '') {
$customer->height = $request->input('height', null);
}
if ($request->has('weight') && trim($request->input('weight')) != '') {
$customer->weight = $request->input('weight', null);
}
$customer->description = $request->input('description');
if (trim($request->input('password')) != '') {
$customer->password = bcrypt($request->input('password'));
}
if ($request->has('dob') && $request->dob != '') {
$customer->dob = date('Y-m-d', floor($request->dob));
} else {
$customer->dob = null;
}
// $customer->mobile = $request->mobile;
if ($request->has('password') && trim($request->input('password')) != '') {
$customer->password = bcrypt($request->password);
}
if ($request->hasFile('avatar')) {
$name = time() . '.' . request()->avatar->getClientOriginalExtension();
$customer->avatar = $name;
$request->file('avatar')->storeAs('public/customers', $name);
$format = $request->file('avatar')->guessExtension();
$format = 'webp';
$key = 'avatar';
$i = Image::load($request->file($key)->getPathname())
->optimize()
->width(500)
->height(500)
->crop(500, 500)
// ->nonQueued()
->format($format);
$i->save(storage_path() . '/app/public/customers/'. $customer->avatar);
}
$customer->save();
return redirect()->route('client.profile')->with('message', __('Profile updated successfully'));
}
@ -87,13 +134,13 @@ class CustomerController extends Controller
$subtitle = __("Invoice ID:") . ' ' . $invoice->hash;
$options = new QROptions([
'version' => 5,
'version' => 5,
'outputType' => QRCode::OUTPUT_MARKUP_SVG,
'eccLevel' => QRCode::ECC_L,
'eccLevel' => QRCode::ECC_L,
// 'imageTransparent' => true,
]);
$qr = new QRCode($options);
return view('client.invoice', compact('area', 'title', 'subtitle','invoice','qr'));
return view('client.invoice', compact('area', 'title', 'subtitle', 'invoice', 'qr'));
}

@ -27,6 +27,11 @@ class CustomerSaveRequest extends FormRequest
'email' => ['required', 'string', 'email', 'max:255', 'unique:customers,email,'.$this->id],
'password' => ['nullable', 'string', 'min:6', 'confirmed'],
'mobile'=> ['required', 'string', 'min:10'],
'height' => ['nullable', 'numeric'],
'weight' => ['nullable', 'numeric'],
'sex' => ['required', 'in:MALE,FEMALE'],
'dob' => ['nullable', 'date'],
'avatar' => ['nullable', 'image', 'mimes:jpeg','max:2048'],
];
}
}

@ -69,4 +69,14 @@ class Customer extends Authenticatable
}
public function avatar(){
if ($this->avatar == null || trim($this->avatar) == ''){
return asset('assets/default/unknown.svg');
}
return \Storage::url('customers/' . $this->avatar);
}
}

@ -25,6 +25,10 @@ return new class extends Migration
$table->boolean('colleague')->default(false);
$table->text('description')->default(null)->nullable();
$table->bigInteger('credit')->default(0);
$table->enum('sex',['MALE','FEMALE'])->nullable()->default(null);
$table->integer('height')->nullable()->default(null);
$table->decimal('weight')->nullable()->default(null);
$table->string('avatar')->nullable()->default(null);
$table->json('card')->default(null)->nullable();
$table->rememberToken();
$table->timestamps();

@ -32,6 +32,10 @@ import RateInput from "../client-vue/RateInput.vue";
app.component('rate-input', RateInput);
import vdp from "../client-vue/vueDateTimePickerClient.vue";
app.component('vue-datetime-picker-input', vdp);
app.use(ToastPlugin);
app.use(store);
app.mount('#app');

File diff suppressed because it is too large Load Diff

@ -166,6 +166,10 @@ a.btn,a.action-btn,a.circle-btn{
}
}
#avatar-input{
display: none;
}
.ol-sortable {
padding-right: 1rem;
@ -330,3 +334,4 @@ a.btn,a.action-btn,a.circle-btn{
transform: rotate(360deg);
}
}

@ -24,6 +24,14 @@
</ul>
</div>
@if(isset($item))
<div class="item-list mb-3">
<h3 class="p-3">
<i class="ri-user-3-line"></i>
{{__("Avatar")}}
</h3>
<img src="{{$item->avatar()}}" class="img-fluid mb-3" alt="" data-open-file="#avatar-input">
<input type="file" name="avatar" id="avatar-input" accept="image/jpeg">
</div>
<div class="item-list mb-3">
<h3 class="p-3">
<i class="ri-user-location-line"></i>
@ -89,6 +97,44 @@
</currency-input>
</div>
</div>
<div class="col-md-3 mt-3">
<div class="form-group">
<label for="dp">
{{__('Date of born')}}
</label>
<vue-datetime-picker-input
:xmax="{{strtotime('yesterday')}}"
xid="dp" xname="dob" xshow="pdate" xtitle="{{__("Date of born")}}" def-tab="0"
@if(isset($item)) :xvalue="{{strtotime($item->dob)}}" @endif
:timepicker="false"
></vue-datetime-picker-input>
</div>
</div>
<div class="col-md-3 mt-3">
<label for="height">
{{__('Height')}}
</label>
<input name="height" type="text" class="form-control @error('height') is-invalid @enderror"
placeholder="{{__('Height')}}" value="{{old('height',$item->height??null)}}"
minlength="2"/>
</div>
<div class="col-md-3 mt-3">
<label for="weight">
{{__('Weight')}}
</label>
<input name="weight" type="text" class="form-control @error('weight') is-invalid @enderror"
placeholder="{{__('Weight')}}" value="{{old('weight',$item->weight??null)}}"
minlength="2"/>
</div>
<div class="col-md-3 mt-3">
<label for="sex">
{{__('Sex')}}
</label>
<select name="sex" id="sex" class="form-control">
<option value="MALE"> {{__("Male")}} </option>
<option value="FEMALE" @if(isset($item) && $item->sex == 'FEMALE') selected @endif> {{__("Female")}} </option>
</select>
</div>
<div class="col-md-4 mt-3">
<div class="form-group">
<label for="mobile">
@ -96,7 +142,7 @@
</label>
<input name="mobile" type="text" class="form-control @error('mobile') is-invalid @enderror"
placeholder="{{__('Mobile')}}" value="{{old('mobile',$item->mobile??null)}}"
min-length="10"/>
minlength="10"/>
</div>
</div>
<div class="col-md-3 mt-3">
@ -128,7 +174,7 @@
type="checkbox" id="colleague" name="colleague"
@if (isset($item) && $item->colleague)
checked
@endif>
@endif>
<label class="form-check-label" for="colleague">{{__("Colleague")}}</label>
</div>
</div>

@ -2,7 +2,7 @@
<div class="{{gfx()['container']}}">
<div class="row">
<div class="col-lg-3">
<img src="{{asset('assets/default/unknown.svg')}}" alt="[avatar]" class="avisa-avatar">
<img src="{{auth('customer')->user()->avatar()}}" alt="[avatar]" class="avisa-avatar" onclick="document.querySelector('#avatar').click();">
<div class="text-center ">
{{__("Welcome back")}}
<br>
@ -227,7 +227,8 @@
<i class="ri-eye-line"></i>
</a>
@if( in_array($inv->status, ['PENDING', 'CANCELED', 'FAILED'] ) && $inv->created_at->timestamp > (time() - 3600) )
<a href="{{route('client.pay',$inv->hash)}}" class="btn btn-outline-primary btn-sm ms-2">
<a href="{{route('client.pay',$inv->hash)}}"
class="btn btn-outline-primary btn-sm ms-2">
<i class="ri-secure-payment-line"></i>
{{__("Pay now")}}
</a>
@ -242,7 +243,7 @@
<div class="alert alert-info">
{{__("If you want to change the password, choose both the same. Otherwise, leave the password field blank.")}}
</div>
<form action="{{route('client.profile.save')}}" method="post">
<form action="{{route('client.profile.save')}}" method="post" enctype="multipart/form-data">
@csrf
<div class="row">
<div class="col-md-4 mt-3">
@ -279,7 +280,50 @@
min-length="10"/>
</div>
</div>
<div class="col-md-6 mt-3">
<div class="col-md-3 mt-3">
<div class="form-group">
<label for="dp">
{{__('Date of born')}}
</label>
<vue-datetime-picker-input
:xmax="{{strtotime('yesterday')}}"
xid="dp" xname="dob" xshow="pdate" xtitle="{{__("Date of born")}}" def-tab="0"
:xvalue="{{strtotime(auth('customer')->user()->dob)}}"
:timepicker="false"
></vue-datetime-picker-input>
</div>
</div>
<div class="col-md-3 mt-3">
<label for="height">
{{__('Height')}}
</label>
<input name="height" type="text"
class="form-control @error('height') is-invalid @enderror"
placeholder="{{__('Height')}}"
value="{{old('height',auth('customer')->user()->height??null)}}"
minlength="2"/>
</div>
<div class="col-md-3 mt-3">
<label for="weight">
{{__('Weight')}}
</label>
<input name="weight" type="text"
class="form-control @error('weight') is-invalid @enderror"
placeholder="{{__('Weight')}}"
value="{{old('weight',auth('customer')->user()->weight??null)}}"
minlength="2"/>
</div>
<div class="col-md-3 mt-3">
<label for="sex">
{{__('Sex')}}
</label>
<select name="sex" id="sex" class="form-control">
<option value="MALE"> {{__("Male")}} </option>
<option value="FEMALE"
@if(auth('customer')->user()->sex == 'FEMALE') selected @endif> {{__("Female")}} </option>
</select>
</div>
<div class="col-md-4 mt-3">
<div class="form-group">
<label for="password">
{{__('Password')}}
@ -289,7 +333,7 @@
placeholder="{{__('Password')}}" value="{{old('password',''??null)}}"/>
</div>
</div>
<div class="col-md-6 mt-3">
<div class="col-md-4 mt-3">
<div class="form-group">
<label for="password_confirmation">
{{__('password repeat')}}
@ -300,6 +344,14 @@
value="{{old('password_confirmation',$item->password_confirmation??null)}}"/>
</div>
</div>
<div class="col-md-4 mt-3">
<div class="form-group">
<label>
{{__("Avatar")}}
</label>
<input type="file" name="avatar" class="form-control" id="avatar" accept="image/jpeg">
</div>
</div>
<div class="col-md-12">
<label> &nbsp;</label>
<input name="" type="submit" class="btn btn-primary mt-3 w-100 "

@ -8,6 +8,8 @@
border-radius: 50%;
object-fit: cover;
margin: auto;
cursor: pointer;
margin-bottom: 1rem;
}
#avisa-tabs {

Loading…
Cancel
Save