bit fix sale customer, verified partial, and replan for paylater and coin

dev
Aji Kamaludin 1 year ago
parent b5e55ca95c
commit 4d56b27731
No known key found for this signature in database
GPG Key ID: 19058F67F0083AD3

@ -13,13 +13,20 @@
- [x] Setting Level Customer (view levels, edit name of level,minimal saldo, max amount saldo, max hutang)
- [x] Deposit Menu (view daftar histori deposit)
- [x] Manual Approve Deposit
- [ ] Setting Bonus Coin (memasukan amount bonus coin yang didapat dengan level dan harga voucher) - coin rewards
- [ ] View Customer Coin History
- [ ] List Customer Verification
- [ ] Manual Approve Verification
- [ ] Manual Approve Verification -> mendapatkan limit hutang
- [ ] Setting Bonus Coin (memasukan amount bonus coin yang didapat dengan level dan harga voucher) - bonus coin
- [ ] Voucher Sales
- [ ] Dashboard (gafik hasil penjualan : disorting tanggal, lokasi dan customer)
- [ ] Notification (manual deposit, stock voucher)
- [ ] View Customer Coin History
- [ ] Voucher - harga per level
- [ ] Voucher - harga coin
### Adds
- hutang (paylater) adalah limit tiap customer jika deposit kurang dalam pembayaran voucher , setiap limit yang digunakan akan di potong / di lunasi ketika melakukan topup deposit
- tukar coin adalah dengan menambahkan harga coin di voucher dan menambahkan 1 fitur di customer untuk explorer voucher yang memiliki harga coin, disimpan menjadi sale biasa dengan cara 1 kali penukaran adalah 1 voucher
### Customer
@ -36,4 +43,6 @@
- [x] Register Refferal
- [x] Customer View Coin History
- [ ] Verified Akun
- [ ] Paylater
- [ ] Coin Explorer
- [ ] Notification (purchase success, deposit success)

@ -96,25 +96,20 @@ class CartController extends Controller
DB::beginTransaction();
$carts = collect(session('carts'));
if ($carts->count() == 0) {
return redirect()->route('home.index')
->with('message', ['type' => 'error', 'message' => 'transaksi gagal, keranjang anda kosong']);
}
// validate voucher is available
$vouchers = Voucher::whereIn('id', $carts->pluck('id')->toArray())->get();
$carts = $carts->map(function ($item) use ($vouchers) {
$voucher = $vouchers->firstWhere('id', $item['id']);
if ($voucher->is_sold == Voucher::SOLD) {
$voucher = $voucher->shuffle_unsold();
// rare happen
if ($voucher == null) {
session()->remove('carts');
return redirect()->route('home.index')
->with('message', ['type' => 'error', 'message' => 'transaksi gagal, voucher sedang tidak tersedia']);
}
foreach ($carts as $item) {
$batchCount = $item['voucher']->count_unsold();
if ($batchCount < $item['quantity']) {
session()->remove('carts');
return redirect()->route('home.index')
->with('message', ['type' => 'error', 'message' => 'transaksi gagal, voucher sedang tidak tersedia']);
}
return [
...$item,
'voucher' => $voucher
];
});
};
$total = $carts->sum(function ($item) {
return $item['quantity'] * $item['voucher']->price;
@ -129,15 +124,18 @@ class CartController extends Controller
]);
foreach ($carts as $item) {
$sale->items()->create([
'entity_type' => $item['voucher']::class,
'entity_id' => $item['voucher']->id,
'price' => $item['voucher']->price,
'quantity' => $item['quantity'],
'additional_info_json' => json_encode($item),
]);
$item['voucher']->update(['is_sold' => Voucher::SOLD]);
foreach (range(1, $item['quantity']) as $q) {
$voucher = $item['voucher']->shuffle_unsold();
$sale->items()->create([
'entity_type' => $voucher::class,
'entity_id' => $voucher->id,
'price' => $voucher->price,
'quantity' => 1,
'additional_info_json' => json_encode($item),
]);
$voucher->update(['is_sold' => Voucher::SOLD]);
}
}
$deposit = $customer->deposites()->create([

@ -0,0 +1,32 @@
<?php
namespace App\Http\Controllers\Customer;
use App\Http\Controllers\Controller;
use App\Models\Customer;
use Illuminate\Http\Request;
class VerificationController extends Controller
{
public function index()
{
return inertia('Verification/Index');
}
public function update(Request $request)
{
$request->validate(['image' => 'required|image']);
$customer = Customer::where('id', auth()->id())->first();
$file = $request->file('image');
$file->store('uploads/KTP', 'public');
$customer->update([
'identity_image' => $file->hashName('uploads/KTP'),
'identity_verified' => Customer::IN_VERICATION,
]);
return redirect()->route('customer.verification')
->with('message', ['type' => 'success', 'message' => 'verification is in progress']);
}
}

@ -0,0 +1,42 @@
<?php
namespace App\Http\Controllers;
use App\Models\Customer;
use App\Models\CustomerLevel;
use Illuminate\Http\Request;
class VerificationController extends Controller
{
public function index()
{
$query = Customer::with(['level'])
->where('identity_verified', Customer::IN_VERICATION)
->orderBy('updated_at', 'desc');
return inertia('Verification/Index', [
'query' => $query->paginate()
]);
}
public function edit(Customer $customer)
{
$levels = [
CustomerLevel::where('key', CustomerLevel::GOLD)->first(),
CustomerLevel::where('key', CustomerLevel::PLATINUM)->first(),
];
return inertia('Verification/Form', [
'customer' => $customer->load(['level']),
'levels' => $levels
]);
}
public function update(Request $request, Customer $customer)
{
// TODO: here
$request->validate([]);
//
$customer->update([]);
}
}

@ -40,7 +40,7 @@ class HandleInertiaCustomerRequests extends Middleware
return array_merge(parent::share($request), [
'app_name' => env('APP_NAME', 'App Name'),
'auth' => [
'user' => auth('customer')->user()?->load(['level']),
'user' => auth('customer')->user()?->load(['level', 'paylater']),
],
'flash' => [
'message' => fn () => $request->session()->get('message') ?? ['type' => null, 'message' => null],

@ -41,10 +41,10 @@ class CoinHistory extends Model
{
return Attribute::make(get: function () {
if ($this->credit == 0) {
return 'Rp' . number_format($this->debit, 0, ',', '.');
return number_format($this->debit, 0, ',', '.');
}
return '-Rp' . number_format($this->credit, 0, ',', '.');
return number_format($this->credit, 0, ',', '.');
});
}

@ -33,7 +33,6 @@ class Customer extends Authenticatable
'google_id',
'deposit_balance',
'coin_balance',
'paylater_balance',
'identity_verified',
'identity_image',
'customer_level_id',
@ -47,9 +46,11 @@ class Customer extends Authenticatable
protected $appends = [
'image_url',
'identity_image_url',
'display_deposit',
'display_coin',
'display_phone',
'paylater_limit',
];
protected static function booted(): void
@ -103,6 +104,19 @@ class Customer extends Authenticatable
);
}
public function identityImageUrl(): Attribute
{
return Attribute::make(
get: function () {
if ($this->identity_image != null) {
return asset($this->identity_image);
}
return asset('sample/ktp_placeholder.png');
}
);
}
public function displayPhone(): Attribute
{
return Attribute::make(get: function () {
@ -128,6 +142,13 @@ class Customer extends Authenticatable
});
}
public function paylaterLimit(): Attribute
{
return Attribute::make(get: function () {
return $this->paylater?->limit ?? '';
});
}
public function level()
{
return $this->belongsTo(CustomerLevel::class, 'customer_level_id');
@ -148,6 +169,16 @@ class Customer extends Authenticatable
return $this->hasMany(CoinHistory::class);
}
public function paylater()
{
return $this->hasOne(PaylaterCustomer::class);
}
public function paylaterHistories()
{
return $this->hasMany(PaylaterHistory::class);
}
public function customerRefferals()
{
return $this->hasMany(CustomerRefferal::class);

@ -0,0 +1,13 @@
<?php
namespace App\Models;
class PaylaterCustomer extends Model
{
protected $fillable = [
'limit',
'usage',
'description',
'customer_id',
];
}

@ -17,6 +17,7 @@ class Voucher extends Model
'location_id',
'username',
'password',
'price_coin', // harga voucher untuk ditukarkan dengan coin
'price', // harga jual
'discount',
'display_price', //yang di input user
@ -87,4 +88,14 @@ class Voucher extends Model
return $voucher;
}
public function count_unsold()
{
$voucher = Voucher::where([
['is_sold', '=', self::UNSOLD],
['batch_id', '=', $this->batch_id]
])->count();
return $voucher;
}
}

@ -19,6 +19,7 @@ return new class extends Migration
$table->ulid('location_id')->nullable();
$table->string('username')->nullable();
$table->string('password')->nullable();
$table->decimal('price_coin', 20, 2)->default(0);
$table->decimal('price', 20, 2)->default(0);
$table->decimal('discount', 20, 0)->default(0);
$table->decimal('display_price', 20, 2)->default(0);

@ -26,8 +26,7 @@ return new class extends Migration
$table->string('google_id')->nullable();
$table->decimal('deposit_balance', 20, 2)->default(0);
$table->decimal('coin_balance', 20, 2)->default(0);
$table->decimal('paylater_balance', 20, 2)->default(0);
$table->smallInteger('identity_verified')->nullable();
$table->smallInteger('identity_verified')->default(0);
$table->string('identity_image')->nullable();
$table->ulid('customer_level_id')->nullable();
$table->text('google_oauth_response')->nullable();

@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('paylater_customers', function (Blueprint $table) {
$table->ulid('id')->primary();
$table->text('description')->nullable();
$table->ulid('customer_id')->nullable();
$table->decimal('limit', 20, 2)->default(0);
$table->decimal('usage', 20, 2)->default(0);
$table->timestamps();
$table->softDeletes();
$table->ulid('created_by')->nullable();
$table->ulid('updated_by')->nullable();
$table->ulid('deleted_by')->nullable();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('paylater_customers');
}
};

@ -54,10 +54,7 @@ class PermissionSeeder extends Seeder
['id' => Str::ulid(), 'label' => 'Update Customer Level', 'name' => 'update-customer-level'],
['id' => Str::ulid(), 'label' => 'View Customer Level', 'name' => 'view-customer-level'],
['id' => Str::ulid(), 'label' => 'Create Customer Verification', 'name' => 'create-customer-verification'],
['id' => Str::ulid(), 'label' => 'Update Customer Verification', 'name' => 'update-customer-verification'],
['id' => Str::ulid(), 'label' => 'View Customer Verification', 'name' => 'view-customer-verification'],
['id' => Str::ulid(), 'label' => 'Delete Customer Verification', 'name' => 'delete-customer-verification'],
['id' => Str::ulid(), 'label' => 'View Setting', 'name' => 'view-setting'],

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.4 KiB

@ -30,7 +30,7 @@ export default function Index({ auth: { user }, carts, total }) {
return (
<CustomerLayout>
<Head title="Index" />
<Head title="Cart" />
<div className="flex flex-col min-h-[calc(95dvh)]">
<div className="py-5 text-2xl px-5 font-bold">Keranjang</div>

@ -36,7 +36,7 @@ export default function Index({
Coin
</div>
<div className="font-bold text-3xl">
Rp {user.display_coin}
{user.display_coin}
</div>
</div>
</div>

@ -25,7 +25,7 @@ export default function BalanceBanner({ user }) {
</div>
<div className="font-bold">{user.level.name} Member</div>
<div className="text-xs flex flex-row items-center space-x-1 text-gray-400">
<div>Limit 100.000</div>
<div>{user.paylater_limit}</div>
</div>
</div>
</div>

@ -6,7 +6,7 @@ import { HiChevronLeft } from 'react-icons/hi2'
export default function Banner({ banner }) {
return (
<CustomerLayout>
<Head title="Login" />
<Head title="Banner" />
<div className="flex flex-col min-h-[calc(95dvh)] p-4">
<div
className="w-full pb-4"

@ -149,7 +149,7 @@ export default function Index({ auth: { user }, flash }) {
<img
src={`${data.image_url}`}
className="w-20 h-20 mb-1 rounded-full"
alt="site logo"
alt="profile image"
/>
}
/>

@ -84,7 +84,17 @@ export default function Index({ auth: { user } }) {
</div>
</div>
<div className="p-4 flex flex-col">
{/* menu hanya muncul untuk member gold atau platinum */}
<div className="flex flex-row justify-between items-center px-2 py-4 w-full border-b border-gray-400 hover:bg-gray-100">
<div>Paylater</div>
<HiChevronRight className="h-5 w-5" />
</div>
<div
className="flex flex-row justify-between items-center px-2 py-4 w-full border-b border-gray-400 hover:bg-gray-100"
onClick={() =>
router.get(route('customer.verification'))
}
>
<div>Upgrade Member</div>
<HiChevronRight className="h-5 w-5" />
</div>
@ -101,7 +111,7 @@ export default function Index({ auth: { user } }) {
className="flex flex-row justify-between items-center px-2 py-4 w-full border-b border-gray-400 hover:bg-gray-100"
onClick={() => router.get(route('customer.coin.index'))}
>
<div>Coin</div>
<div>Riwayat Coin</div>
<HiChevronRight className="h-5 w-5" />
</div>
<div

@ -20,19 +20,19 @@ export default function Detail({ sale }) {
<div className="text-2xl px-5 font-bold">
Transaksi #{sale.code}
</div>
<div className="px-5 pb-4">{sale.format_created_at}</div>
<div className="px-5">{sale.format_created_at}</div>
<div className="px-5 pb-4 w-full">
<div className="text-xl font-bold text-right flex flex-row justify-between">
<div>TOTAL</div>
<div> {sale.display_amount}</div>
</div>
</div>
<div className="w-full px-5 flex flex-col space-y-2">
{sale.items.map((item) => (
<VoucherCard key={item.id} item={item} />
))}
</div>
<div className="fixed bottom-20 right-0 w-full">
<div className="max-w-sm mx-auto text-xl font-bold text-right flex flex-row justify-between">
<div>TOTAL</div>
<div> {sale.display_amount}</div>
</div>
</div>
</div>
</CustomerLayout>
)

@ -64,12 +64,6 @@ export default function VoucherCard(props) {
</div>
</div>
<div className="w-full border border-dashed"></div>
<div className="w-full flex flex-row justify-between items-center pt-1">
<div>{formatIDR(voucher.price)}</div>
<div>x</div>
<div>{quantity}</div>
<div>{formatIDR(+voucher.price * +quantity)}</div>
</div>
<div className="w-full flex flex-row justify-between items-center py-1">
<div className="w-full flex flex-col space-y-2 py-2 px-2 bg-blue-50 border border-blue-200 rounded text-blue-700">
<div className="flex flex-row space-x-2 items-center">

@ -0,0 +1,102 @@
import React, { useState } from 'react'
import { Head, useForm, router, usePage } from '@inertiajs/react'
import CustomerLayout from '@/Layouts/CustomerLayout'
import FormFile from '@/Components/FormFile'
import { HiCheckCircle, HiClock } from 'react-icons/hi2'
// 0 yuk verifikasi
const VerificationForm = () => {
const {
props: {
auth: { user },
},
} = usePage()
const [show, setShow] = useState(false)
const { setData, post, errors } = useForm({ image: null })
const handleSubmit = () => {
post(route('customer.verification'))
}
return (
<>
<div className="px-4 text-gray-400">
upgrade akun kamu untuk mendapatkan banefit lebih, cukup lakukan
verifikasi data dengan upload foto KTP kamu
</div>
{show === false ? (
<div
className="w-full px-4 mt-10"
onClick={() => setShow(true)}
>
<div className="py-3 px-4 rounded-full border bg-blue-600 text-white hover:bg-gray-100 hover:text-black">
Verifikasi
</div>
</div>
) : (
<div className="w-full flex flex-col px-5">
<FormFile
label="KTP"
onChange={(e) => setData('image', e.target.files[0])}
error={errors.image}
preview={
<img
src={`${user.identity_image_url}`}
className="w-full object-fill h-48 mb-1 "
alt="ktp image"
/>
}
/>
<div
className="py-3 px-4 rounded-full border bg-blue-600 text-white hover:bg-gray-100 hover:text-black"
onClick={() => handleSubmit()}
>
Upload
</div>
</div>
)}
</>
)
}
// 1 verified
const Verified = () => {
return (
<div className="flex flex-col w-full items-center my-auto">
<HiCheckCircle className="h-32 w-32 text-green-500" />
<div className="font-bold text-lg px-10 pt-5 text-center">
Akun anda berhasil terverifikasi
</div>
</div>
)
}
// 2 your data is in review
const VerificationInProgress = () => {
return (
<div className="flex flex-col w-full items-center my-auto">
<HiClock className="h-32 w-32 text-gray-400 border rounded-full border-gray-600" />
<div className="font-bold text-lg px-10 pt-5 text-center">
Data anda sedang kami proses untuk verifikasi
</div>
</div>
)
}
export default function Index({ auth: { user } }) {
return (
<CustomerLayout>
<Head title="Upgrade Member" />
<div className="flex flex-col min-h-[calc(95dvh)]">
<div className="px-4 pt-10 text-2xl font-bold">
Upgrade Member
</div>
{+user.identity_verified === 0 && <VerificationForm />}
{+user.identity_verified === 1 && <Verified />}
{+user.identity_verified === 2 && <VerificationInProgress />}
</div>
</CustomerLayout>
)
}

@ -6,6 +6,8 @@ import { HiOutlineHome, HiOutlineUserCircle } from 'react-icons/hi'
import {
HiArrowPathRoundedSquare,
HiBars3,
HiGift,
HiOutlineGift,
HiOutlineShoppingCart,
} from 'react-icons/hi2'
@ -51,7 +53,6 @@ export default function CustomerLayout({ children }) {
<HiOutlineHome className="h-6 w-6" />
<div className="text-xs font-light">Beranda</div>
</div>
<div
className={`pb-1 pt-2 px-5 hover:bg-blue-200 flex flex-col items-center ${isActive(
'cart.index'
@ -68,6 +69,17 @@ export default function CustomerLayout({ children }) {
</div>
<div className="text-xs font-light">Keranjang</div>
</div>
<div
className={`pb-1 pt-2 px-5 hover:bg-blue-200 flex flex-col items-center ${isActive(
'coin'
)}`}
// onClick={() => handleOnClick('cart.index')}
>
<div className="flex flex-row">
<HiOutlineGift className="h-6 w-6" />
</div>
<div className="text-xs font-light">Coin</div>
</div>
<div
className={`pb-1 pt-2 px-5 hover:bg-blue-200 flex flex-col items-center ${isActive(
'transactions.*'

@ -61,7 +61,7 @@ export default [
permission: 'view-deposit',
},
{
name: 'Coin Rewards', //TODO
name: 'Bonus Coin', //TODO
show: true,
icon: HiOutlineCurrencyDollar,
route: route('voucher.index'),
@ -98,12 +98,12 @@ export default [
icon: HiUser,
items: [
{
name: 'Verification', //TODO
name: 'Verifikasi',
show: true,
icon: HiCheckBadge,
route: route('customer.index'),
active: 'customer.*',
permission: 'view-customer',
route: route('customer-verification.index'),
active: 'customer-verification.*',
permission: 'view-customer-verification',
},
{
name: 'Customer',

@ -84,7 +84,7 @@ export default function FormModal(props) {
toggle={handleClose}
title={'Deposit'}
>
<table className="relative w-full overflow-x-auto border-collapse border p-2 rounded">
<table className="relative w-full overflow-x-auto p-2 rounded">
<tbody>
<tr>
<td className="font-bold">Customer</td>

@ -14,7 +14,7 @@ import SearchInput from '@/Components/SearchInput'
import { formatIDR, hasPermission } from '@/utils'
import { HiEye } from 'react-icons/hi2'
export default function Info(props) {
export default function Index(props) {
const {
query: { links, data },
auth,
@ -125,31 +125,20 @@ export default function Info(props) {
>
{deposit.status.text}
</td>
<td className="py-4 px-6 flex justify-end">
<Dropdown
label={'Opsi'}
floatingArrow={true}
arrowIcon={true}
dismissOnClick={true}
size={'sm'}
>
{canUpdate && (
<Dropdown.Item
onClick={() =>
toggleFormModal(
deposit
)
}
>
<div className="flex space-x-1 items-center">
<HiEye />
<div>
Lihat
</div>
</div>
</Dropdown.Item>
)}
</Dropdown>
<td className="py-4 px-6 flex justify-center">
{canUpdate && (
<div
className="flex space-x-1 items-center hover:underline"
onClick={() =>
toggleFormModal(
deposit
)
}
>
<HiEye />
<div>Lihat</div>
</div>
)}
</td>
</tr>
))}
@ -157,7 +146,7 @@ export default function Info(props) {
</table>
</div>
<div className="w-full flex items-center justify-center">
<Pagination links={links} />
<Pagination links={links} params={params} />
</div>
</div>
</div>

@ -0,0 +1,102 @@
import React, { useEffect, useState } from 'react'
import { useForm, Head, Link } from '@inertiajs/react'
import { isEmpty } from 'lodash'
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout'
import Button from '@/Components/Button'
export default function Form(props) {
const { customer, levels } = props
const { data, setData, post, processing, errors, reset, clearErrors } =
useForm({
level: '',
image_prove_url: '',
})
const handleOnChange = (event) => {
setData(
event.target.name,
event.target.type === 'checkbox'
? event.target.checked
? 1
: 0
: event.target.value
)
}
const handleSubmit = () => {
post(route('customer-verification.update', customer))
}
return (
<AuthenticatedLayout
auth={props.auth}
errors={props.errors}
flash={props.flash}
page={'Verifikasi Customer'}
action={'Form'}
>
<Head title="Verifikasi Customer" />
<div>
<div className="mx-auto sm:px-6 lg:px-8">
<div className="overflow-hidden p-4 shadow-sm sm:rounded-lg bg-white dark:bg-gray-800 flex flex-col ">
<div className="text-xl font-bold mb-4">
Verifikasi Customer
</div>
<table className="relative w-full overflow-x-auto border-collapse border p-2 rounded">
<tbody>
<tr>
<td className="font-bold">Customer</td>
<td>:</td>
<td className="hover:underline">
<Link
href={route(
'customer.edit',
customer
)}
>
{customer.name}
</Link>
</td>
</tr>
</tbody>
</table>
<div className="py-2">
<img
src={customer.identity_image_url}
className="w-full object-fill h-96"
/>
</div>
<div className="my-4">
<div className="mb-1 text-sm">Level Upgrade</div>
<select
className="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
onChange={handleOnChange}
value={data.level}
name="level"
>
<option value=""></option>
{levels.map((level) => (
<option value={level.key} key={level.key}>
{level.name}
</option>
))}
</select>
</div>
<div className="flex items-center">
<Button
onClick={handleSubmit}
processing={processing}
>
Simpan
</Button>
</div>
</div>
</div>
</div>
</AuthenticatedLayout>
)
}

@ -0,0 +1,163 @@
import React, { useEffect, useState } from 'react'
import { router } from '@inertiajs/react'
import { usePrevious } from 'react-use'
import { Head } from '@inertiajs/react'
import { Dropdown } from 'flowbite-react'
import { HiEye } from 'react-icons/hi2'
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout'
import Pagination from '@/Components/Pagination'
import SearchInput from '@/Components/SearchInput'
export default function Index(props) {
const {
query: { links, data },
auth,
} = props
const [search, setSearch] = useState('')
const preValue = usePrevious(search)
const params = { q: search }
useEffect(() => {
if (preValue) {
router.get(
route(route().current()),
{ q: search },
{
replace: true,
preserveState: true,
}
)
}
}, [search])
return (
<AuthenticatedLayout
auth={props.auth}
errors={props.errors}
flash={props.flash}
page={'Verifikasi Customer'}
action={''}
>
<Head title="Verifikasi Customer" />
<div>
<div className="mx-auto sm:px-6 lg:px-8 ">
<div className="p-6 overflow-hidden shadow-sm sm:rounded-lg bg-gray-200 dark:bg-gray-800 space-y-4">
<div className="flex justify-between">
<div className="flex items-center">
<SearchInput
onChange={(e) => setSearch(e.target.value)}
value={search}
/>
</div>
</div>
<div className="overflow-auto">
<div>
<table className="w-full text-sm text-left text-gray-500 dark:text-gray-400 mb-4">
<thead className="text-xs text-gray-700 uppercase bg-gray-50 dark:bg-gray-700 dark:text-gray-400">
<tr>
<th
scope="col"
className="py-3 px-6"
>
Nama
</th>
<th
scope="col"
className="py-3 px-6"
>
Level
</th>
<th
scope="col"
className="py-3 px-6"
>
Deposit
</th>
<th
scope="col"
className="py-3 px-6"
>
Coin
</th>
<th
scope="col"
className="py-3 px-6"
>
Referal Code
</th>
<th
scope="col"
className="py-3 px-6 w-1/8"
/>
</tr>
</thead>
<tbody>
{data.map((customer) => (
<tr
className="bg-white border-b dark:bg-gray-800 dark:border-gray-700"
key={customer.id}
>
<td
scope="row"
className="py-4 px-6 font-medium text-gray-900 whitespace-nowrap dark:text-white"
>
{customer.name}
</td>
<td
scope="row"
className="py-4 px-6"
>
{customer.level.name}
</td>
<td
scope="row"
className="py-4 px-6"
>
{customer.display_deposit}
</td>
<td
scope="row"
className="py-4 px-6"
>
{customer.display_coin}
</td>
<td
scope="row"
className="py-4 px-6"
>
{customer.referral_code}
</td>
<td className="py-4 px-6 flex justify-center">
<div
className="flex space-x-1 items-center hover:underline"
onClick={() => {
router.get(
route(
'customer-verification.edit',
customer
)
)
}}
>
<HiEye />
<div>Lihat</div>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
<div className="w-full flex items-center justify-center">
<Pagination links={links} params={params} />
</div>
</div>
</div>
</div>
</div>
</AuthenticatedLayout>
)
}

@ -5,6 +5,7 @@ use App\Http\Controllers\Auth\AuthenticatedSessionController;
use App\Http\Controllers\BannerController;
use App\Http\Controllers\CustomerController;
use App\Http\Controllers\CustomerLevelController;
use App\Http\Controllers\VerificationController;
use App\Http\Controllers\DepositController;
use App\Http\Controllers\GeneralController;
use App\Http\Controllers\InfoController;
@ -83,6 +84,11 @@ Route::middleware(['http_secure_aware', 'inertia.admin'])
Route::get('/customer-levels', [CustomerLevelController::class, 'index'])->name('customer-level.index');
Route::put('/customer-levels/{customerLevel}', [CustomerLevelController::class, 'update'])->name('customer-level.update');
// verification
Route::get('/customers-verifications', [VerificationController::class, 'index'])->name('customer-verification.index');
Route::get('/customers-verifications/{customer}', [VerificationController::class, 'edit'])->name('customer-verification.edit');
Route::post('/customers-verifications/{customer}', [VerificationController::class, 'update'])->name('customer-verification.update');
// customer
Route::get('/customers', [CustomerController::class, 'index'])->name('customer.index');
Route::get('/customers/create', [CustomerController::class, 'create'])->name('customer.create');

@ -7,6 +7,7 @@ use App\Http\Controllers\Customer\DepositController;
use App\Http\Controllers\Customer\HomeController;
use App\Http\Controllers\Customer\ProfileController;
use App\Http\Controllers\Customer\TransactionController;
use App\Http\Controllers\Customer\VerificationController;
use Illuminate\Support\Facades\Route;
/*
@ -30,6 +31,11 @@ Route::middleware(['http_secure_aware', 'guard_should_customer', 'inertia.custom
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']);
// logout
Route::post('logout', [AuthController::class, 'destroy'])->name('customer.logout');

Loading…
Cancel
Save