dev
Aji Kamaludin 1 year ago
parent aad6e10c80
commit 26483da322
No known key found for this signature in database
GPG Key ID: 19058F67F0083AD3

@ -33,7 +33,7 @@ class CustomerMitraController extends Controller
->count(),
'sum_paylater_limit' => PaylaterCustomer::sum('limit'),
'sum_paylater_usage' => PaylaterCustomer::sum('usage'),
'sum_paylater_remain' => PaylaterCustomer::selectRaw('(SUM("limit") - SUM(usage)) as remain')->value('remain'),
'sum_paylater_remain' => PaylaterCustomer::selectRaw('(SUM("limit") - SUM("usage")) as remain')->value('remain'),
];
$query = Customer::query()->with(['level', 'paylater', 'locationFavorites'])

@ -103,15 +103,15 @@ class GeneralController extends Controller
$date = $date->addDay();
}
$saleYearDepositCharts = Sale::selectRaw("SUM(amount) as sale_total, DATE_PART('month', date_time) as month")
$saleYearDepositCharts = Sale::selectRaw("SUM(amount) as sale_total, MONTH(date_time) as month")
->where('payed_with', Sale::PAYED_WITH_DEPOSIT)
->whereRaw("DATE_PART('year', sales.date_time) = " . Carbon::parse($year)->year)
->groupBy(DB::raw("DATE_PART('month', date_time)"));
->whereRaw("YEAR(sales.date_time) = " . Carbon::parse($year)->year)
->groupBy(DB::raw("MONTH(date_time)"));
$saleYearPaylaterCharts = Sale::selectRaw("SUM(amount) as sale_total, DATE_PART('month', date_time) as month")
$saleYearPaylaterCharts = Sale::selectRaw("SUM(amount) as sale_total, MONTH(date_time) as month")
->where('payed_with', Sale::PAYED_WITH_PAYLATER)
->whereRaw("DATE_PART('year', sales.date_time) = " . Carbon::parse($year)->year)
->groupBy(DB::raw("DATE_PART('month', date_time)"));
->whereRaw("YEAR(sales.date_time) = " . Carbon::parse($year)->year)
->groupBy(DB::raw("MONTH(date_time)"));
// filter lokasi
if ($request->year_location_id != '') {

@ -54,9 +54,11 @@ class VoucherController extends Controller
->where('location_profile_id', $profile->id);
if ($request->q != '') {
$query->where(function ($query) use ($request){
$query->where('username', 'ilike', "%$request->q%")
->orWhere('comment', 'ilike', "%$request->q%")
->orWhere('profile', 'ilike', "%$request->q%");
});
}
if ($request->sortBy != '' && $request->sortRule != '') {

@ -107,7 +107,7 @@ class AuthController extends Controller
DB::beginTransaction();
$customer = Customer::create([
'fullname' => $user->name,
'name' => $user->nickname,
'name' => $user->name,
'email' => $user->email,
'username' => Str::slug($user->name . '_' . Str::random(5), '_'),
'google_id' => $user->id,
@ -153,7 +153,7 @@ class AuthController extends Controller
$request->validate([
'fullname' => 'required|string',
'email' => 'required|email|unique:users,email',
'name' => 'required|string',
'name' => 'nullable|string',
'address' => 'required|string',
'phone' => 'required|regex:/^([0-9\s\-\+\(\)]*)$/|min:9|max:16',
'username' => 'required|string|min:5|alpha_dash|unique:customers,username',
@ -164,7 +164,7 @@ class AuthController extends Controller
DB::beginTransaction();
$customer = Customer::create([
'fullname' => $request->fullname,
'name' => $request->name,
'name' => $request->fullname,
'address' => $request->address,
'phone' => $request->phone,
'username' => $request->username,

@ -109,7 +109,7 @@ class CartController extends Controller
// validate carts not empty
if ($carts->count() == 0) {
return redirect()->route('home.index')
return redirect()->route('home.index', ['direct' => 1])
->with('message', ['type' => 'error', 'message' => 'transaksi gagal, keranjang anda kosong']);
}
@ -119,7 +119,7 @@ class CartController extends Controller
if ($batchCount < $item->quantity) {
$customer->carts()->delete();
return redirect()->route('home.index')
return redirect()->route('home.index', ['direct' => 1])
->with('message', ['type' => 'error', 'message' => 'transaksi gagal, voucher sedang tidak tersedia']);
}
}

@ -29,7 +29,7 @@ class ProfileController extends Controller
$request->validate([
'fullname' => 'string|required',
'name' => 'string|required',
'name' => 'string|nullable',
'address' => 'string|required',
'phone' => 'string|required|numeric',
'username' => 'string|required|min:5|alpha_dash|unique:customers,username,' . $customer->id,
@ -49,7 +49,7 @@ class ProfileController extends Controller
$customer->update([
'fullname' => $request->fullname,
'name' => $request->name,
'name' => $request->fullname,
'address' => $request->address,
'phone' => $request->phone,
'username' => $request->username,

@ -70,5 +70,6 @@ class Kernel extends HttpKernel
'inertia.customer' => \App\Http\Middleware\HandleInertiaCustomerRequests::class,
'guard_should_customer' => \App\Http\Middleware\GuardCustomer::class,
'http_secure_aware' => \App\Http\Middleware\HttpSecureAware::class,
'customer.is_complate_profile' => \App\Http\Middleware\CustomerComplateProfile::class,
];
}

@ -0,0 +1,26 @@
<?php
namespace App\Http\Middleware;
use App\Models\Customer;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;
use Symfony\Component\HttpFoundation\Response;
class CustomerApi
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
if ($request->header('user') != '') {
$customer = Customer::find($request->header('user'));
Auth::guard('customer')->setUser($customer);
}
return $next($request);
}
}

@ -0,0 +1,27 @@
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
class CustomerComplateProfile
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
$customer = $request->user('customer');
if (!$customer->is_profile_complate) {
return redirect()->route('customer.profile.show')
->with('message', ['type' => 'error', 'message' => 'silahkan lengkapi profile sebelum dapat ber-transaksi']);
}
return $next($request);
}
}

@ -245,6 +245,34 @@ class Customer extends Authenticatable
});
}
public function isProfileComplate(): Attribute
{
return Attribute::make(get: function () {
if (in_array(null, [
$this->username,
$this->email,
$this->name,
$this->fullname,
$this->address,
$this->phone,
])) {
return false;
}
if (in_array('', [
$this->username,
$this->email,
$this->name,
$this->fullname,
$this->address,
$this->phone,
])) {
return false;
}
return true;
});
}
public function level()
{
return $this->belongsTo(CustomerLevel::class, 'customer_level_id');

@ -37,7 +37,10 @@ class SaleItem extends Model
public function shareWord(): Attribute
{
return Attribute::make(get: function () {
return Setting::getByKey('SHARE_TEXT');
$shareText = Setting::getByKey('SHARE_TEXT').'
Kode Voucher : ' . $this->voucher->username;
return $shareText;
});
}
}

@ -68,7 +68,7 @@ export default function Index({ referral_code, flash }) {
onKeyDownCapture={(e) => handleKeyDown(e)}
/>
</div>
<div className="w-full">
{/* <div className="w-full">
<FormInput
placeholder="nama panggilan"
name="name"
@ -77,7 +77,7 @@ export default function Index({ referral_code, flash }) {
error={errors.name}
onKeyDownCapture={(e) => handleKeyDown(e)}
/>
</div>
</div> */}
<div className="w-full">
<FormInput
placeholder="email"

@ -1,4 +1,4 @@
import React from 'react'
import React, { useState } from 'react'
import { Head, router } from '@inertiajs/react'
import { formatIDR } from '@/utils'
@ -8,9 +8,29 @@ import EmptyHere from './IndexPartials/EmptyHere'
import { useModalState } from '@/hooks'
import Payment from './IndexPartials/Payment'
export default function Index({ carts, total, allow_process }) {
export default function Index({ carts: items, total, allow_process }) {
const [carts, setCarts] = useState(items)
const paymentModal = useModalState()
const removeCart = (cart) => {
setCarts(carts.filter((c) => c.id !== cart.id))
}
console.log(carts)
const changeQty = (cart, qty) => {
setCarts(
carts.map((c) => {
if (c.id === cart.id) {
return {
...c,
quantity: qty,
}
}
return c
})
)
}
const handlePayment = () => {
paymentModal.toggle()
}
@ -28,7 +48,12 @@ export default function Index({ carts, total, allow_process }) {
<>
<div className="w-full px-2 flex flex-col space-y-2 pb-28">
{carts.map((item) => (
<VoucherCard key={item.id} item={item} />
<VoucherCard
key={item.id}
item={item}
onRemove={removeCart}
onChangeQty={changeQty}
/>
))}
</div>
<div className="fixed bottom-12 w-full bg-white py-5 px-2 shadow-lg border-t max-w-md mx-auto">

@ -1,23 +1,72 @@
import { formatIDR } from '@/utils'
import { router } from '@inertiajs/react'
import { router, usePage } from '@inertiajs/react'
import { HiMinusCircle, HiPlusCircle, HiTrash } from 'react-icons/hi2'
export default function VoucherCard({ item: { location_profile, quantity } }) {
export default function VoucherCard({ item, onRemove, onChangeQty }) {
const {
props: {
auth: { user },
},
} = usePage()
const { location_profile, quantity } = item
const handleDelete = () => {
router.post(
route('cart.store', { profile: location_profile, param: 'delete' })
onRemove(item)
fetch(
route('api.cart.store', {
profile: location_profile,
param: 'delete',
}),
{
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
user: user.id,
},
}
)
}
const handleAdd = () => {
router.post(
route('cart.store', { profile: location_profile, param: 'add' })
const qty = +quantity + 1
onChangeQty(item, qty)
fetch(
route('api.cart.store', {
profile: location_profile,
param: 'add',
}),
{
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
user: user.id,
},
}
)
}
const handleSub = () => {
router.post(
route('cart.store', { profile: location_profile, param: 'sub' })
const qty = +quantity - 1
if (qty <= 0) {
return
}
onChangeQty(item, qty)
fetch(
route('api.cart.store', {
profile: location_profile,
param: 'sub',
}),
{
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
user: user.id,
},
}
)
}

@ -88,7 +88,7 @@ export default function Detail({ deposit, back }) {
</div>
<div>
<div
className={`text-xs px-2 py-1 rounded-full border ${deposit.status.color} text-white`}
className={`text-xs ${deposit.status.text_color} `}
>
{deposit.status.text}
</div>

@ -110,7 +110,7 @@ export default function Index(props) {
</div>
{+history.is_valid !== 0 && (
<div
className={`text-xs px-2 py-1 rounded-full border text-white ${history.status.color}`}
className={`text-xs ${history.status.text_color}`}
>
{history.status.text}
</div>

@ -12,6 +12,17 @@ export default function UserBanner({ user }) {
<div>
{/* user */}
<div className="flex flex-row justify-between items-center px-5 py-6 text-lg bg-primary-900">
<div className="flex flex-row items-center space-x-2">
{user.image_url !== null ? (
<img
src={user.image_url}
alt="profile image"
className="rounded-full object-cover h-14 w-14"
loading="lazy"
/>
) : (
<HiOutlineUserCircle className="text-white h-14 w-14" />
)}
<div className="flex flex-col text-white">
<div className="font-bold">{user.name}</div>
<div className="flex flex-row items-center space-x-1 -mt-1">
@ -21,6 +32,7 @@ export default function UserBanner({ user }) {
</div>
</div>
</div>
</div>
<div
className="flex flex-row"
onClick={() => {

@ -97,9 +97,9 @@ export default function Index({
</div>
{history.status !== '' && (
<div
className={`text-xs px-2 py-1 rounded-full border text-white bg-red-600`}
className={`text-xs px-2 py-1 text-red-600`}
>
{history.status}
{history.status_text.text}
</div>
)}
</div>

@ -70,7 +70,7 @@ export default function Index({ auth: { user }, flash }) {
label="nama lengkap"
/>
</div>
<div className="w-full">
{/* <div className="w-full">
<FormInput
placeholder="nama panggilan"
name="name"
@ -80,7 +80,7 @@ export default function Index({ auth: { user }, flash }) {
onKeyDownCapture={(e) => handleKeyDown(e)}
label="nama panggilan"
/>
</div>
</div> */}
<FormInputWith
type="number"
leftItem={<div className="text-sm">+62</div>}

@ -157,7 +157,7 @@ export default function Form(props) {
>
<img
src={deposit.image_prove_url}
className="w-full object-fill h-96"
className="w-full object-contain h-96"
loading="lazy"
/>
</a>

@ -186,7 +186,7 @@ export default function Form(props) {
>
<img
src={deposit.image_prove_url}
className="w-full object-fill h-96"
className="w-full object-contain h-96"
loading="lazy"
/>
</a>

@ -2,7 +2,7 @@
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
<meta name="mobile-web-app-capable" content="yes">
<meta name="description" content="web shop online aplikasi jual voucher wifi online">

@ -1,5 +1,5 @@
<x-mail::message>
# Hai, {{ $customer->name }}
# Hai, {{ $customer->fullname }}
## Welcome to {{ config('app.name', 'Voucher WBB') }}
Untuk mulai menggunakan layanan kami, harap aktifkan akun Anda dengan mengklik tombol aktivasi ini di bawah.

@ -7,7 +7,9 @@ use App\Http\Controllers\Api\LocationController;
use App\Http\Controllers\Api\LocationProfileController;
use App\Http\Controllers\Api\NotificationController;
use App\Http\Controllers\Api\RoleController;
use App\Http\Controllers\Customer\CartController;
use App\Http\Controllers\Customer\DepositController;
use App\Http\Middleware\CustomerApi;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
@ -37,3 +39,8 @@ Route::get('/notifications/{notif?}', [NotificationController::class, 'update'])
// midtrans
Route::post('mindtrans/notification', [DepositController::class, 'mindtrans_notification'])->name('api.midtrans.notification');
Route::post('mindtrans/{deposit}/payment', [DepositController::class, 'midtrans_payment'])->name('api.midtrans.payment');
// cart customer
Route::middleware([CustomerApi::class])->group(function () {
Route::post('cart/{profile}', [CartController::class, 'store'])->name('api.cart.store');
});

@ -30,16 +30,11 @@ Route::middleware(['http_secure_aware', 'guard_should_customer', 'inertia.custom
Route::get('/banner/{banner}', [HomeController::class, 'banner'])->name('home.banner');
Route::middleware('auth:customer')->group(function () {
Route::middleware(['auth:customer', 'customer.is_complate_profile'])->group(function () {
// location to favorite
Route::post('/locations/{location}/add-favorite', [HomeController::class, 'addFavorite'])->name('customer.location.favorite');
Route::get('/favorites', [HomeController::class, 'favorite'])->name('home.favorite');
// profile
Route::get('profile', [ProfileController::class, 'index'])->name('customer.profile.index');
Route::get('profile/update', [ProfileController::class, 'show'])->name('customer.profile.show');
Route::post('profile/update', [ProfileController::class, 'update']);
// verification
Route::get('profile/verification', [VerificationController::class, 'index'])->name('customer.verification');
Route::post('profile/verification', [VerificationController::class, 'update']);
@ -87,6 +82,13 @@ Route::middleware(['http_secure_aware', 'guard_should_customer', 'inertia.custom
Route::get('cash-deposit-locations', [DepositLocationController::class, 'index'])->name('customer.deposit-location.index');
});
Route::middleware('auth:customer')->group(function () {
// profile
Route::get('profile', [ProfileController::class, 'index'])->name('customer.profile.index');
Route::get('profile/update', [ProfileController::class, 'show'])->name('customer.profile.show');
Route::post('profile/update', [ProfileController::class, 'update']);
});
Route::middleware('guest:customer')->group(function () {
// login
Route::get('/login', [AuthController::class, 'login'])->name('customer.login');

Loading…
Cancel
Save