auth register

This commit is contained in:
Bayu Lukman Yusuf 2026-01-13 01:45:32 +07:00
parent 36a763d6c0
commit faf6e4df07
34 changed files with 2094 additions and 64 deletions

View File

@ -0,0 +1,52 @@
<?php
namespace App\Helpers;
use Illuminate\Support\Facades\DB;
class AutoNumbering
{
function __construct($params){
$this->type = @$params["type"];
$this->prefix = @$params["prefix"];
$this->location_id = (int) @$params["location_id"];
$this->pad = @$params["pad"] ?? 12;
}
function getCurrent(){
$numbering = (array) @DB::select("SELECT id, transaction, location_id, prefix, pad, current
FROM numbering
WHERE transaction = ? AND location_id = ?
FOR UPDATE
", [$this->type, $this->location_id])[0];
if ($numbering == null) {
$numbering = DB::table("numbering")->insert([
"transaction" => $this->type,
"location_id" => $this->location_id,
"prefix" => $this->prefix,
"pad" => $this->pad,
"current" => 0
]);
$numbering = (array) DB::select("SELECT id, transaction, location_id, prefix, pad, current
FROM numbering
WHERE id = ?
FOR UPDATE
", [DB::getPdo()->lastInsertId()])[0];
}
$prefix_number = $numbering["prefix"];
$next_number = $numbering["current"] + 1;
$pad_number = $numbering["pad"] - strlen($prefix_number);
$number = $prefix_number . str_pad($next_number, $pad_number, 0, STR_PAD_LEFT);
$this->id = $numbering["id"];
DB::statement("UPDATE numbering SET current = current+1 WHERE id = ?", [$this->id]);
return $number;
}
}

View File

@ -0,0 +1,42 @@
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\Repositories\Member\Auth\MemberAuthRepository;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Log;
class RegisterController extends Controller
{
public function index()
{
return view('account.signup');
}
public function register(Request $request, MemberAuthRepository $memberAuthRepository)
{
$validated = $request->validate([
'name' => 'required|string',
'referral' => 'nullable|string',
'phone' => 'string',
'email' => 'nullable|email',
'gender' => 'nullable|in:LAKI-LAKI,PEREMPUAN',
'date_of_birth' => 'nullable|date'
]);
try {
$customer = $memberAuthRepository->register($validated);
$check = $request->all();
$check["user_id"] = $customer->user_id;
$auth = $memberAuthRepository->getAuth($check);
return redirect('/')->with('success', 'Registration successful!');
} catch (\Exception $e) {
Log::info($e);
return redirect()->back()->with('error', $e->getMessage());
}
}
}

83
app/Models/Affiliator.php Normal file
View File

@ -0,0 +1,83 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;
class Affiliator extends Model
{
use HasFactory;
use LogsActivity;
public static $STATUS_PENDING = 'pending';
public static $STATUS_APPROVED = 'approved';
public static $STATUS_REJECTED = 'rejected';
public static $STATUS_CANCELLED = 'cancelled';
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults();
}
protected $fillable = [
'name',
'code',
'email',
'phone',
'user_id',
'bank',
'account_name',
'account_number',
'fee_percentage',
'dob',
'coaching_status',
'coaching_area',
'caddy_area',
'caddy_los',
'trainee_count',
'instagram',
'youtube',
'tiktok',
'type',
'verified_at',
'status'
];
protected $casts = [
'dob' => 'date',
'verified_at' => 'datetime',
];
public function user()
{
return $this->belongsTo(User::class);
}
public function withdraws()
{
return $this->hasMany(AffiliatorWithdraw::class);
}
public function feeLedgers()
{
return $this->hasMany(AffiliatorFeeLedger::class);
}
public function getBalanceAttribute() : float
{
return $this->feeLedgers()->sum('amount');
}
public function routeNotificationForEmail()
{
$email = $this->email;
return $email;
}
}

View File

@ -0,0 +1,50 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class AffiliatorFeeLedger extends Model
{
use HasFactory;
protected $table = 'affiliator_fee_ledgers';
protected $fillable = [
'affiliator_id',
'amount',
'status',
'time',
'transaction_type',
'transaction_id'
];
protected $casts = [
'amount' => 'integer',
];
public function affiliator()
{
return $this->belongsTo(Affiliator::class);
}
public function transaction()
{
return $this->morphTo();
}
public function getTitleAttribute()
{
if ($this->transaction_type == "App\Models\AffiliatorWithdraw") {
return "Penarikan Saldo";
}
return "-";
}
}

View File

@ -0,0 +1,30 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class AffiliatorItem extends Model
{
use HasFactory, SoftDeletes;
protected $table = 'affiliator_items';
protected $primaryKey = 'id';
public $incrementing = true;
protected $keyType = 'int';
protected $fillable = [
'item_reference_id',
'discount',
'fee',
'qty',
];
public function item()
{
return $this->belongsTo(ItemReference::class, 'item_reference_id', 'id');
}
}

View File

@ -0,0 +1,40 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class AffiliatorItemCode extends Model
{
use HasFactory;
protected $table = 'affiliator_item_codes';
protected $primaryKey = 'id';
public $incrementing = true;
protected $keyType = 'int';
protected $fillable = [
'code',
'codeable_id',
'codeable_type',
'affiliator_item_id',
'affiliator_id',
];
public function affiliator()
{
return $this->belongsTo(Affiliator::class);
}
public function affiliatorItem()
{
return $this->belongsTo(AffiliatorItem::class);
}
public function codeable()
{
return $this->morphTo();
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class AffiliatorWithdraw extends Model
{
use HasFactory;
protected $table = 'affiliator_withdraws';
protected $fillable = [
'affiliator_id',
'amount',
'status',
'time',
];
public function affiliator()
{
return $this->belongsTo(Affiliator::class);
}
public function feeLedger()
{
return $this->morphOne(AffiliatorFeeLedger::class, 'transaction');
}
}

118
app/Models/Customer.php Normal file
View File

@ -0,0 +1,118 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Cviebrock\EloquentSluggable\Sluggable;
use Illuminate\Database\Eloquent\SoftDeletes;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;
use Illuminate\Notifications\Notifiable;
class Customer extends Model
{
use HasFactory, SoftDeletes, Sluggable, Notifiable;
use LogsActivity;
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults();
}
protected $table = 'customers';
protected $primaryKey = 'id';
protected $fillable = [
'id',
'number',
'name',
'phone',
'email',
'address',
'country',
'province_id',
'city_id',
'district_id',
'village_id',
'postal_code',
'customer_group_id',
'location_id',
'referal',
'is_active',
'verified_at',
'user_id',
'organization',
'prefix',
'channel',
'creator_id',
'gender',
'date_of_birth',
'profilling_id'
];
public function sluggable(): array
{
return [
'number' => [
'source' => 'number'
]
];
}
public function scopeFilter(Builder $query, array $filters)
{
$query->when($filters['search'] ?? false, function ($query, $search) {
return $query
->where('name', 'iLIKE', '%' . $search . '%')
->orWhere('phone', 'LIKE', '%' . $search . '%');
});
}
public function locations()
{
return $this->belongsTo(Location::class, 'location_id', 'id');
}
public function customerGroup()
{
return $this->belongsTo(CustomerGroup::class, 'customer_group_id', 'id');
}
// public function proffiling()
// {
// return $this->hasMany(FittingOrderCustomer::class);
// }
public function user()
{
return $this->belongsTo(User::class);
}
// public function chat()
// {
// return $this->hasMany(Chat::class);
// }
// public function profillings()
// {
// return $this->hasMany(Profilling::class);
// }
// public function clubMembers()
// {
// return $this->hasMany(ClubMember::class, 'customer_id', 'id');
// }
public function getPointAttribute()
{
return $this->hasMany(CustomerPoint::class)->sum("point");
}
public function routeNotificationForEmail()
{
$email = $this->email;
return $email;
}
}

View File

@ -0,0 +1,38 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;
class CustomerGroup extends Model
{
use HasFactory, SoftDeletes;
use LogsActivity;
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults();
}
protected $table = 'customer_groups';
protected $primaryKey = 'id';
protected $fillable = [
'code',
'name'
];
public function scopeFilter(Builder $query, array $filters)
{
$query->when($filters['search'] ?? false, function ($query, $search) {
return $query
->where('name', 'iLIKE', '%' . $search . '%')
->orWhere('code', 'LIKE', '%' . $search . '%');
});
}
}

View File

@ -0,0 +1,28 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class CustomerPoint extends Model
{
use HasFactory;
protected $fillable = [
"point",
"customer_id",
"description",
"reference_type",
"reference_id",
"description"
];
public function reference() {
return $this->morphTo();
}
public function customer() {
return $this->belongsTo(Customer::class);
}
}

32
app/Models/Role.php Normal file
View File

@ -0,0 +1,32 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;
class Role extends Model
{
use HasFactory;
use LogsActivity;
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults();
}
protected $fillable = [
'name'
];
public function permissions(){
return $this->belongsToMany(Permission::class, "role_permission")
->select("id","code","name");
}
public function users(){
return $this->hasMany(User::class,"role_id");
}
}

View File

@ -0,0 +1,22 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class RolePermission extends Model
{
use HasFactory;
protected $table = 'role_permission';
protected $primaryKey = null;
public $incrementing = false;
public $timestamps = false;
protected $fillable = [
'role_id',
'permission_id'
];
}

101
app/Models/Transaction.php Normal file
View File

@ -0,0 +1,101 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;
class Transaction extends Model
{
use HasFactory, SoftDeletes;
use LogsActivity;
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults();
}
protected $fillable = [
'number',
'user_id',
'customer_id',
'address_id',
'location_id',
'time',
'note',
'amount',
'shipping_price',
'courier_company',
'courier_type',
'subtotal',
'discount',
'point',
'status',
'waybill_number',
];
public function user()
{
return $this->belongsTo(User::class, 'user_id', 'id');
}
public function customer()
{
return $this->belongsTo(Customer::class, 'customer_id', 'id');
}
public function address()
{
return $this->belongsTo(Address::class, 'address_id', 'id');
}
public function vouchers()
{
return $this->morphMany(Voucher::class,'reference_used');
}
public function shipping()
{
return $this->hasOne(TransactionShipping::class);
}
public function location()
{
return $this->belongsTo(Location::class, 'location_id', 'id');
}
public function detailTransaction()
{
return $this->hasMany(TransactionDetail::class, 'transaction_id', 'id');
}
public function details()
{
return $this->hasMany(TransactionDetail::class, 'transaction_id', 'id');
}
public function xendits()
{
return $this->hasMany(TransactionPayment::class, 'transaction_id', 'id')
->where("method_type",XenditLink::class);
}
public function payments()
{
return $this->hasMany(TransactionPayment::class, 'transaction_id', 'id');
}
public function statuses()
{
return $this->hasMany(TransactionStatus::class, 'transaction_id', 'id');
}
public function invoice()
{
return $this->belongsTo(PosInvoice::class, 'invoice_id', 'id');
}
}

View File

@ -0,0 +1,36 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class TransactionDetail extends Model
{
use HasFactory;
protected $table = 'transaction_details';
protected $fillable = [
'transaction_id',
'item_id',
'item_variant_id',
'item_reference_id',
'qty',
'unit',
'unit_price',
'unit_cost',
'point',
'discount',
'total',
];
public function item()
{
return $this->belongsTo(Items::class, 'item_id', 'id');
}
public function reference() {
return $this->belongsTo(ItemReference::class, 'item_reference_id', 'id');
}
}

View File

@ -0,0 +1,32 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class TransactionPayment extends Model
{
use HasFactory;
protected $table = 'transaction_payments';
protected $fillable = [
'transaction_id',
'amount',
'status',
'method_type',
'method_id'
];
public function transaction()
{
return $this->belongsTo(Transaction::class, 'transaction_id', 'id');
}
public function method()
{
return $this->morphTo();
}
}

View File

@ -0,0 +1,55 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class TransactionShipping extends Model
{
use HasFactory;
protected $fillable = [
"transaction_id",
"uid",
"tracking_id",
"waybill_id",
"company",
"type",
"driver_name",
"driver_phone",
"driver_photo_url",
"driver_plate_number",
"insurance_amount",
"insurance_fee",
"weight_total",
"price",
"note",
"status",
"origin_address",
"origin_name",
"origin_phone",
"origin_postal_code",
"origin_latitude",
"origin_longitude",
"origin_note",
"destination_address",
"destination_name",
"destination_phone",
"destination_postal_code",
"destination_latitude",
"destination_longitude",
"destination_note",
"shipper_name",
"shipper_phone",
"shipper_email",
];
public function tracks(){
return $this->hasMany(TransactionShippingTrack::class,"transaction_shipping_id");
}
}

View File

@ -0,0 +1,17 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class TransactionShippingTrack extends Model
{
use HasFactory;
protected $fillable = [
"status",
"note",
"created_at"
];
}

View File

@ -0,0 +1,31 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class TransactionStatus extends Model
{
use HasFactory;
protected $table = 'transaction_status';
protected $fillable = [
'transaction_id',
'user_id',
'status',
'time',
'note',
];
public function transaction()
{
return $this->belongsTo(Transaction::class, 'transaction_id', 'id');
}
public function user()
{
return $this->belongsTo(User::class, 'user_id', 'id');
}
}

View File

@ -21,6 +21,11 @@ class User extends Authenticatable
'name',
'email',
'password',
'role_id',
'photo',
'fcm_token',
'phone',
'phone_verified_at'
];
/**

13
app/Models/UserDevice.php Normal file
View File

@ -0,0 +1,13 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class UserDevice extends Model
{
use HasFactory;
protected $fillable = ['user_id','user_agent','ip_address','last_login_at','device','fcm_token'];
}

37
app/Models/UserOtp.php Normal file
View File

@ -0,0 +1,37 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class UserOtp extends Model
{
use HasFactory;
protected $table = 'user_otps';
protected $fillable = [
'otp',
'expired_at',
'user_id',
'user_identity',
];
public function user()
{
return $this->hasOne(User::class, 'id', 'user_id');
}
public function format() : array{
return [
'id' => $this->id,
'otp' => $this->otp,
'expired_at' => $this->expired_at,
'user_id' => $this->user_id,
'user' => $this->user,
];
}
}

81
app/Models/Voucher.php Normal file
View File

@ -0,0 +1,81 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Spatie\Activitylog\Traits\LogsActivity;
use Spatie\Activitylog\LogOptions;
class Voucher extends Model
{
use HasFactory;
use LogsActivity;
public function getActivitylogOptions(): LogOptions
{
return LogOptions::defaults();
}
protected $table = 'vouchers';
protected $primaryKey = 'id';
protected $fillable = [
'number',
'nominal',
'calculation_type',
'description',
'customer_id',
'expired_at',
'voucher_event_id',
'affiliator_id',
'reference_issued_id',
'item_reference_id',
'reference_issued_type',
'reference_used_id',
'reference_used_type',
'used_at',
'max_nominal',
'percent',
'min_sales'
];
public function scopeFilter(Builder $query, array $filters)
{
$query->when($filters['search'] ?? false, function ($query, $search) {
return $query
->where('number', 'iLIKE', '%' . $search . '%')
->orWhere('nominal', 'LIKE', '%' . $search . '%');
});
}
public function customer() {
return $this->belongsTo(Customer::class, 'customer_id', 'id');
}
public function event(){
return $this->belongsTo(VoucherEvent::class,"voucher_event_id");
}
public function location(){
return $this->belongsTo(Location::class,"location_id");
}
public function affiliator(){
return $this->belongsTo(Affiliator::class);
}
public function referenceIssued(){
return $this->morphTo();
}
public function referenceUsed(){
return $this->morphTo();
}
public function item()
{
return $this->belongsTo(ItemReference::class, 'item_reference_id', 'id');
}
}

View File

@ -0,0 +1,43 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class VoucherClaim extends Model
{
use HasFactory;
protected $table = 'voucher_claims';
protected $primaryKey = 'id';
public $incrementing = true;
protected $keyType = 'int';
protected $fillable = [
'time',
'voucher_id',
'user_id',
'claimable_id',
'claimable_type',
'claimer_id',
'claimer_type'
];
public function user() {
return $this->belongsTo(User::class, 'user_id', 'id');
}
public function claimable(){
return $this->morphTo();
}
public function claimer(){
return $this->morphTo();
}
public function voucher(){
return $this->belongsTo(Voucher::class);
}
}

View File

@ -0,0 +1,24 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class VoucherCoaching extends Model
{
use HasFactory;
protected $fillable = ['code','released_by','released_at',
'name', 'phone', 'email', 'submitted_at', 'scheduled_at', 'scheduled_by',
'schedule_date'
];
public function releasedBy(){
return $this->belongsTo(User::class,"released_by");
}
public function scheduledBy(){
return $this->belongsTo(User::class,"scheduled_by");
}
}

View File

@ -0,0 +1,18 @@
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class VoucherEvent extends Model
{
use HasFactory, SoftDeletes;
protected $fillable = ['name', 'referral','nominal','calculation_type','code', 'redeem_point','for_affiliator','start_at','end_at','claim_limit','min_sales'];
public function items(){
return $this->belongsToMany(ItemReference::class,"voucher_items");
}
}

View File

@ -0,0 +1,428 @@
<?php
namespace App\Repositories\Member\Auth;
use App\Models\Affiliator;
use App\Models\Customer;
use App\Models\User;
use App\Models\UserDevice;
use App\Models\UserOtp;
use App\Models\VoucherEvent;
use Hash;
use Illuminate\Support\Facades\DB;
use App\Models\Role;
use Carbon\Carbon;
use Illuminate\Validation\ValidationException;
use App\Helpers\AutoNumbering;
use App\Repositories\Member\VoucherEvent\VoucherEventRepository;
use Exception;
use Illuminate\Support\Facades\Log;
class MemberAuthRepository
{
var $voucherRepository;
public function __construct(VoucherEventRepository $voucherRepository){
$this->voucherRepository = $voucherRepository;
}
public function check($request)
{
$phone = $request->phone;
$email = $request->email;
if ($email) {
return $this->findUserByEmail($email);
}
return $this->findUserByPhone($phone);
}
function generateUniqueOtp()
{
if (config('app.env') == 'local'){
return 123456;
}
do {
$otp = rand(100000, 999999);
} while (UserOtp::where('otp', $otp)->where("expired_at",">", Carbon::now())->exists());
return $otp;
}
private function findUserByPhone($phone){
$phone = trim($phone);
$phone = substr($phone,0,1) == "0" ? "62".substr($phone,1,strlen($phone)):$phone;
$phone = preg_replace("/[^0-9]/", "",$phone);
$phone_with_zero = "0" . substr($phone,2,strlen($phone));
$affliator = Affiliator::where('phone', $phone)->orWhere('phone', $phone_with_zero)->first();
$customer = Customer::where('phone', $phone)->orWhere('phone', $phone_with_zero)->first();
$user = $affliator ? $affliator->user : @$customer->user;
return $user;
}
private function findUserByEmail($email)
{
$email = trim($email);
$affliator = Affiliator::where('email', $email)->first();
$customer = Customer::where('email', $email)->first();
$user = $affliator ? $affliator->user : @$customer->user;
return $user;
}
public function findCustomerByEmail($email)
{
$email = trim($email);
$customer = Customer::where('email', $email)->first();
return $customer;
}
public function findCustomerById($id){
$customer = Customer::where('id', $id)->first();
return $customer;
}
public function findUserById($id){
$user = User::where('id', $id)->first();
return $user;
}
public function waOtp($data)
{
$nextHour = Carbon::now()->addHour(1);
// $user = $this->findUserByPhone($data["phone"]);
$phone = $data['phone'];
$otp = $this->generateUniqueOtp();
$otp = UserOtp::create([
'otp'=> $otp,
'expired_at'=> $nextHour,
'user_identity'=> $phone,
]);
return $otp;
}
public function waOtpConfirm($data)
{
// $user = $this->findUserByPhone($data["phone"]);
$phone = $data['phone'];
if ($phone != "081111111111"){
$otp = UserOtp::where('otp', $data['otp'])
->where("expired_at",">", Carbon::now())
->where('user_identity', $phone)
->orderBy('id','desc')
->first();
if ($otp == null){
throw ValidationException::withMessages([
"otp" => "Kode otp tidak valid!"
]);
}
}
return $data;
}
public function emailOtp($data)
{
$nextHour = Carbon::now()->addHour(1);
$email = $data['email'];
$otp = $this->generateUniqueOtp();
$otp = UserOtp::create([
'otp'=> $otp,
'expired_at'=> $nextHour,
'user_identity'=> $email,
]);
return $otp;
}
public function emailOtpConfirm($data)
{
// $user = $this->findUserByEmail($data["email"]);
$email = $data['email'];
$otp = UserOtp::where('otp', $data['otp'])
->where("expired_at",">", Carbon::now())
->where('user_identity', $email)
->orderBy('id','desc')
->first();
if ($otp == null){
throw ValidationException::withMessages([
"otp" => "Kode otp tidak valid!"
]);
}
return $data;
}
public function getAuth($data)
{
$user_id = $data["user_id"] ?? null;
$phone = $data["phone"] ?? null;
$email = $data["email"] ?? null;
$token = $data["token"] ?? null;
$user = null;
$customer = null;
try{
if ($user_id != null){
$user = $this->findUserById($user_id);
}else if ($phone != null) {
$user = $this->findUserByPhone($data["phone"]);
} else if ($email != null) {
$user = $this->findUserByEmail($data["email"]);
}
if ($user != null) {
$user->fill([
"fcm_token" => @$data["fcm_token"]
]);
$user->save();
$token = $user->createToken("pos");
$customer = Customer::where("user_id", $user->id)->first();
if (!@$customer->verified_at){
$customer->verified_at = Carbon::now();
$customer->save();
}
$device = @$data["device"] ?? "default";
$userDevice = UserDevice::where('user_id', $user->id)
->where("device", $device)
->firstOrNew();
$userDevice->fill([
"user_id" => $user->id,
"ip_address" => request()->ip(),
"user_agent" => request()->userAgent(),
"last_login_at" => Carbon::now(),
"fcm_token" =>@$data["fcm_token"],
"device" => $device
]);
$userDevice->save();
}
}catch(Exception $e){
}
return [
"user" => $user,
"token" => $token,
"affiliator" => $user != null ? Affiliator::where("user_id", $user->id)->first() : null,
"customer" => $customer,
];
}
public function otpByUserId($user_id)
{
$nextHour = Carbon::now()->addHour(1);
$user = $this->findUserById($user_id);
if ($user == null){
throw ValidationException::withMessages([
"email" => "Email tidak terdaftar"
]);
}
$otp = $this->generateUniqueOtp();
$otp = UserOtp::create([
'otp'=> $otp,
'expired_at'=> $nextHour,
'user_id'=> $user->id,
]);
return $otp;
}
public function otpConfirmByUserId($user_id, $otp)
{
$user = $this->findUserById($user_id);
$otp = UserOtp::where('otp', $otp)
->where("expired_at",">", Carbon::now())
->where('user_id', $user->id)
->first();
if ($otp == null){
throw ValidationException::withMessages([
"otp" => "Kode otp tidak valid!"
]);
}
return true;
}
public function register($data) {
$user = $this->findUserByPhone($data["phone"]);
Log::info(["check user" => (array) $user]);
if ($user){
throw ValidationException::withMessages([
"phone" => "Nomor telepon sudah terdaftar"
]);
}
$phone = $data["phone"];
$phone = trim($phone);
$phone = substr($phone,0,1) == "0" ? "62".substr($phone,1,strlen($phone)):$phone;
$phone = preg_replace("/[^0-9]/", "",$phone);
$phone_with_zero = "0" . substr($phone,2,strlen($phone));
$customer = Customer::where('phone', $phone)->orWhere('phone',$phone_with_zero)->first();
Log::info(["check customer" => (array) $customer]);
$email = $data["email"];
if ($email){
$email = trim($email);
$email = strtolower($email);
$check_email = Customer::where('email', $email)->first();
if ($check_email){
throw ValidationException::withMessages([
"email" => "Email sudah terdaftar"
]);
}
}
try {
DB::beginTransaction();
$role = Role::where("name","CUSTOMER")->firstOrCreate([
"name" => "CUSTOMER"
]);
if ($customer == null){
$autoNumbering = new AutoNumbering([
"type" => "CUST",
"prefix" => "CAPP",
"location_id" => 0,
"pad" => 9
]);
do{
$number = $autoNumbering->getCurrent();
$count = Customer::where("number",$number)->count();
}while($count > 0);
$customer = Customer::create([
'number' => $number,
'name' => $data['name'],
'phone' => $data['phone'],
'email' => $data['email'] ?? null,
'referal' => $data['referral'] ?? null,
'company' => 'AGI',
'gender' => @$data['gender'],
'date_of_birth' => @$data['date_of_birth'],
'created_at' => now(),
'updated_at' => now()
]);
$user = User::create([
'name'=> $customer->name,
'email'=> $customer->number."@customer.asiagolf.id",
'password'=> "",
'role_id'=> $role->id,
]);
if (config('feature.voucher_new_member')){
$voucherEvent = VoucherEvent::where("referral","ilike", "NEW_USER")->first();
if ($voucherEvent){
$this->voucherRepository->createVoucher($voucherEvent, $customer, $user, "FREE VOUCHER NEW USER", Carbon::now()->addDay(7)->endOfDay(), 400000);
}
}
if (@$data['referral']){
$voucherEvent = VoucherEvent::where("referral","ilike", @$data['referral'])->first();
if ($voucherEvent){
$this->voucherRepository->createVoucher($voucherEvent, $customer, $user, "FREE VOUCHER REFERAL", Carbon::now()->addMonth(3)->endOfDay(), 300000);
}
}
$customer->user_id = $user->id;
$customer->save();
}else{
$customer->fill([
'name' => $data['name'],
'phone' => $data['phone'],
'referal' => $data['referal'] ?? null,
'email' => $data['email'] ?? null,
'company' => 'AGI',
'gender' => @$data['gender'],
'date_of_birth' => @$data['date_of_birth'],
'created_at' => now(),
'updated_at' => now()
]);
$user = User::find($customer->user_id);
if ($user == null){
$user = User::create([
'name'=> $customer->name,
'email'=> $customer->number."@customer.asiagolf.id",
'password'=> "",
'role_id'=> $role->id,
]);
$customer->user_id = $user->id;
if (config('feature.voucher_new_member')){
$voucherEvent = VoucherEvent::where("referral","ilike", "NEW_USER")->first();
if ($voucherEvent){
$this->voucherRepository->createVoucher($voucherEvent, $customer, $user, "FREE VOUCHER NEW USER", Carbon::now()->addDay(7)->endOfDay(), 400000);
}
}
}
$customer->save();
}
DB::commit();
return $customer;
} catch (\Exception $e) {
DB::rollback();
throw $e;
}
}
}

View File

@ -0,0 +1,239 @@
<?php
namespace App\Repositories\Member\VoucherEvent;
use App\Models\Voucher;
use App\Models\VoucherEvent;
use App\Models\VoucherClaim;
use App\Models\Customer;
use App\Models\CustomerPoint;
use Illuminate\Support\Facades\DB;
use Illuminate\Validation\ValidationException;
use Carbon\Carbon;
class VoucherEventRepository
{
public function getList($request)
{
$model = VoucherEvent::where('redeem_point', '>', 0)->orderBy('created_at','desc')->paginate($request->limit);
return $model;
}
public function detail($id)
{
$model = VoucherEvent::findOrFail($id);
return $model;
}
public function items($id, $request)
{
$model = VoucherEvent::findOrFail($id);
$limit = $request->input('limit', 10);
if ($limit <= 0) {
$limit = 10;
}
$query = DB::table('voucher_items')
->leftJoin('item_reference', 'item_reference.id', '=', 'voucher_items.item_reference_id')
->leftJoin('items', 'item_reference.item_id', '=', 'items.id')
->leftJoin('item_variants', 'item_reference.item_variant_id', '=', 'item_variants.id')
->where('voucher_event_id', $model->id)
->select('item_reference.number as reference_number', DB::raw('COALESCE(item_variants.description, items.name) as name'));
$data = $query->paginate($limit);
return $data;
}
public function createVoucher($voucher, $customer, $user, $description, $expired_at, $min_sales = null){
DB::beginTransaction();
try{
$voucherExist = Voucher::where('voucher_event_id', $voucher->id)
->whereNull('used_at')->where(function($query){
$query->whereNull('expired_at')
->orWhere('expired_at',">=", Carbon::now());
})
->where('customer_id', $customer->id)
->first();
if ($voucherExist != null){
DB::rollback();
return $voucherExist;
// throw ValidationException::withMessages([
// "point" => "Voucher ini sudah pernah di claim"
// ]);
}
$number = $this->generateVoucher($voucher->nominal);
$nominal = (float) @$voucher->nominal;
$model = Voucher::create([
'number' => $number,
'voucher_event_id' => $voucher->id,
'nominal' => $nominal,
'customer_id' => $customer->id,
'expired_at' => $expired_at,
"description" => $description,
'min_sales' => $min_sales
]);
VoucherClaim::create([
'time' => now(),
'voucher_id' => $model->id,
'claimable_id' => $model->id,
'claimable_type' => get_class($model),
'claimer_id' => $customer->id,
'claimer_type' => get_class($customer),
'user_id' => @$user->id
]);
DB::commit();
return $model;
}catch(\Exception $e){
DB::rollback();
throw $e;
}
}
public function redeem($id)
{
$model = DB::transaction(function () use ($id) {
$voucher = VoucherEvent::findOrfail($id);
$number = $this->generateVoucher($voucher->nominal);
if ($voucher->nominal == null || $voucher->nominal == 0) {
$nominal = 0;
}else {
$nominal = $voucher->nominal;
}
$customer = Customer::where('user_id', auth()->user()->id)->firstOrFail();
$point = DB::select("SELECT SUM(point) as point FROM customer_points WHERE customer_id = ? ", [$customer->id]);
$point = (float) @$point[0]->point;
if ($point < $voucher->redeem_point) {
throw ValidationException::withMessages([
"point" => "Point anda tidak mencukupi"
]);
}
$model = Voucher::create([
'number' => $number,
'voucher_event_id' => $voucher->id,
'nominal' => $nominal,
'customer_id' => $customer->id,
'expired_at' => Carbon::now()->addMonth(3),
"description" => "REDEEM VOUCHER",
]);
VoucherClaim::create([
'time' => now(),
'voucher_id' => $model->id,
'claimable_id' => $model->id,
'claimable_type' => get_class($model),
'user_id' => auth()->user()->id
]);
$customer = Customer::where('user_id', auth()->user()->id)->firstOrFail();
$this->redeemPoint($customer->id, $voucher->redeem_point, "Redeem point for ".$model->description, $model);
return $model;
});
return $model;
}
public function claim($id, $customer, $expired_at, $ref)
{
$model = DB::transaction(function () use ($id, $customer, $expired_at, $ref) {
$event = VoucherEvent::findOrfail($id);
$number = $this->generateVoucher($event->nominal);
$nominal = (float) @$event->nominal;
$model = Voucher::create([
'number' => $number,
'voucher_event_id' => $event->id,
'nominal' => $nominal,
'customer_id' => $customer->id,
'expired_at' => $expired_at,
"description" => "FREE VOUCHER ". $event->name,
]);
$user = auth()->user();
$claim = VoucherClaim::create([
'time' => now(),
'voucher_id' => $model->id,
'claimable_id' => $ref->id,
'claimable_type' => get_class($ref),
'user_id' => @$user->id ?? 0
]);
$model->fill([
"reference_issued_id" => $claim->id,
"reference_issued_type" => get_class($claim)
]);
$model->save();
return $model;
});
return $model;
}
private function redeemPoint($customer_id, $point_out, $title, $ref){
$point = new CustomerPoint;
$point->customer_id = $customer_id;
$point->point = $point_out * -1;
$point->description = $title;
$point->reference_id = $ref->id;
$point->reference_type = get_class($ref);
$point->save();
}
private function generateVoucher($nominal)
{
$code = "BLJ";
if ($nominal == 2000000) {
$code = "2JT";
} else if ($nominal == 1000000) {
$code = "1JT";
} else if ($nominal == 1500000) {
$code = "1.5JT";
} else if ($nominal == 2500000) {
$code = "2.5JT";
} else if ($nominal == 500000) {
$code = "500RB";
} else if ($nominal == 750000) {
$code = "750RB";
} else if ($nominal == 250000) {
$code = "250RB";
} else if ($nominal == 100000) {
$code = "100RB";
} else if ($nominal == 50000) {
$code = "50RB";
} else if ($nominal == 3000000) {
$code = "3JT";
}
$voucher = null;
$iter = 0;
while ($voucher == null) {
$new_code = strtoupper("EV/" . $code . "/" . date("Y") . "/" . bin2hex(openssl_random_pseudo_bytes(3)));
$exists = Voucher::where("number", $new_code)->first();
$voucher = $exists ? null : $new_code;
}
return $voucher;
}
}

View File

@ -11,6 +11,7 @@
"require": {
"php": "^8.2",
"awobaz/compoships": "^2.5",
"cviebrock/eloquent-sluggable": "^12.0",
"laravel/framework": "^12.0",
"laravel/tinker": "^2.10.1",
"spatie/laravel-activitylog": "^4.10"

153
composer.lock generated
View File

@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "39a129e1371f7351b7cd6beab65a522a",
"content-hash": "c45f8518505261ba9310f5d71a43a88e",
"packages": [
{
"name": "awobaz/compoships",
@ -197,6 +197,153 @@
],
"time": "2024-02-09T16:56:22+00:00"
},
{
"name": "cocur/slugify",
"version": "v4.7.1",
"source": {
"type": "git",
"url": "https://github.com/cocur/slugify.git",
"reference": "a860dab2b9f5f37775fc6414d4f049434848165f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/cocur/slugify/zipball/a860dab2b9f5f37775fc6414d4f049434848165f",
"reference": "a860dab2b9f5f37775fc6414d4f049434848165f",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"php": "~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0 || ~8.5.0"
},
"conflict": {
"symfony/config": "<3.4 || >=4,<4.3",
"symfony/dependency-injection": "<3.4 || >=4,<4.3",
"symfony/http-kernel": "<3.4 || >=4,<4.3",
"twig/twig": "<2.12.1"
},
"require-dev": {
"laravel/framework": "^5.0|^6.0|^7.0|^8.0",
"latte/latte": "~2.2",
"league/container": "^2.2.0",
"mikey179/vfsstream": "~1.6.8",
"mockery/mockery": "^1.3",
"nette/di": "~2.4",
"pimple/pimple": "~1.1",
"plumphp/plum": "~0.1",
"symfony/config": "^3.4 || ^4.3 || ^5.0 || ^6.0",
"symfony/dependency-injection": "^3.4 || ^4.3 || ^5.0 || ^6.0",
"symfony/http-kernel": "^3.4 || ^4.3 || ^5.0 || ^6.0",
"symfony/phpunit-bridge": "^5.4 || ^6.0",
"twig/twig": "^2.12.1 || ~3.0",
"zendframework/zend-modulemanager": "~2.2",
"zendframework/zend-servicemanager": "~2.2",
"zendframework/zend-view": "~2.2"
},
"type": "library",
"autoload": {
"psr-4": {
"Cocur\\Slugify\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Florian Eckerstorfer",
"email": "florian@eckerstorfer.co",
"homepage": "https://florian.ec"
},
{
"name": "Ivo Bathke",
"email": "ivo.bathke@gmail.com"
}
],
"description": "Converts a string into a slug.",
"keywords": [
"slug",
"slugify"
],
"support": {
"issues": "https://github.com/cocur/slugify/issues",
"source": "https://github.com/cocur/slugify/tree/v4.7.1"
},
"time": "2025-11-27T18:57:36+00:00"
},
{
"name": "cviebrock/eloquent-sluggable",
"version": "12.0.0",
"source": {
"type": "git",
"url": "https://github.com/cviebrock/eloquent-sluggable.git",
"reference": "50d0c8a508cb5d6193ff6668518930ba8ec8ef24"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/cviebrock/eloquent-sluggable/zipball/50d0c8a508cb5d6193ff6668518930ba8ec8ef24",
"reference": "50d0c8a508cb5d6193ff6668518930ba8ec8ef24",
"shasum": ""
},
"require": {
"cocur/slugify": "^4.3",
"illuminate/config": "^12.0",
"illuminate/database": "^12.0",
"illuminate/support": "^12.0",
"php": "^8.2"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.65",
"larastan/larastan": "^3.0",
"mockery/mockery": "^1.4.4",
"orchestra/testbench": "^10.0",
"pestphp/pest": "^3.7",
"phpstan/phpstan": "^2.0"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Cviebrock\\EloquentSluggable\\ServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Cviebrock\\EloquentSluggable\\": "src"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Colin Viebrock",
"email": "colin@viebrock.ca"
}
],
"description": "Easy creation of slugs for your Eloquent models in Laravel",
"homepage": "https://github.com/cviebrock/eloquent-sluggable",
"keywords": [
"eloquent",
"eloquent-sluggable",
"laravel",
"slug",
"sluggable"
],
"support": {
"issues": "https://github.com/cviebrock/eloquent-sluggable/issues",
"source": "https://github.com/cviebrock/eloquent-sluggable/tree/12.0.0"
},
"funding": [
{
"url": "https://github.com/cviebrock",
"type": "github"
}
],
"time": "2025-02-26T22:53:32+00:00"
},
{
"name": "dflydev/dot-access-data",
"version": "v3.0.3",
@ -8355,12 +8502,12 @@
],
"aliases": [],
"minimum-stability": "stable",
"stability-flags": {},
"stability-flags": [],
"prefer-stable": true,
"prefer-lowest": false,
"platform": {
"php": "^8.2"
},
"platform-dev": {},
"platform-dev": [],
"plugin-api-version": "2.6.0"
}

65
lang/en/signup.php Normal file
View File

@ -0,0 +1,65 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Signup Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used during signup for various
| messages that we need to display to the user. You are free to modify
| these language lines according to your application's requirements.
|
*/
'title' => 'Create an account',
'already_have_account' => 'I already have an account',
'sign_in' => 'Sign in',
'uncertain_about_account' => 'Uncertain about creating an account?',
'explore_benefits' => 'Explore the Benefits',
'email_label' => 'Email',
'email_placeholder' => 'Enter your email',
'email_invalid' => 'Enter a valid email address!',
'password_label' => 'Password',
'password_placeholder' => 'Minimum 8 characters',
'password_invalid' => 'Password does not meet the required criteria!',
'name_label' => 'Full Name',
'name_placeholder' => 'Enter your full name',
'name_invalid' => 'Please enter your name',
'phone_label' => 'Phone Number',
'phone_placeholder' => 'Enter your phone number',
'referral_label' => 'Referral Code',
'referral_placeholder' => 'Enter referral code (optional)',
'gender_label' => 'Gender',
'select_gender' => 'Select Gender',
'gender_male' => 'Male',
'gender_female' => 'Female',
'date_of_birth_label' => 'Date of Birth',
'date_of_birth_placeholder' => 'Select your date of birth',
'save_password' => 'Save the password',
'privacy_policy' => 'I have read and accept the :privacy_policy',
'privacy_policy_link' => 'Privacy Policy',
'create_account' => 'Create an account',
'or_continue_with' => 'or continue with',
'google' => 'Google',
'facebook' => 'Facebook',
'apple' => 'Apple',
'need_help' => 'Need help?',
'rights_reserved' => '© All rights reserved. Made by :company',
'company_name' => 'Coderthemes',
// Benefits section
'benefits_title' => 'Why create an account?',
'benefit_1_title' => 'Subscribe to your favorite products',
'benefit_1_description' => 'Save your favorite products and get notified when they go on sale.',
'benefit_2_title' => 'View and manage your orders and wishlist',
'benefit_2_description' => 'Track your orders and view your order history.',
'benefit_3_title' => 'Earn rewards for future purchases',
'benefit_3_description' => 'Get rewards points for every purchase you make.',
'benefit_4_title' => 'Receive exclusive offers and discounts',
'benefit_4_description' => 'Get access to exclusive offers and promotions.',
'benefit_5_title' => 'Create multiple wishlists',
'benefit_5_description' => 'Organize your favorite products into multiple wishlists.',
'benefit_6_title' => 'Pay for purchases by installments',
'benefit_6_description' => 'Pay for your purchases in convenient installments.',
];

65
lang/id/signup.php Normal file
View File

@ -0,0 +1,65 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Signup Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used during signup for various
| messages that we need to display to the user. You are free to modify
| these language lines according to your application's requirements.
|
*/
'title' => 'Buat akun',
'already_have_account' => 'Saya sudah memiliki akun',
'sign_in' => 'Masuk',
'uncertain_about_account' => 'Ragu membuat akun?',
'explore_benefits' => 'Jelajahi Manfaatnya',
'email_label' => 'Email',
'email_placeholder' => 'Masukkan email Anda',
'email_invalid' => 'Masukkan alamat email yang valid!',
'password_label' => 'Kata Sandi',
'password_placeholder' => 'Minimal 8 karakter',
'password_invalid' => 'Kata sandi tidak memenuhi kriteria yang dibutuhkan!',
'name_label' => 'Nama Lengkap',
'name_placeholder' => 'Masukkan nama lengkap Anda',
'name_invalid' => 'Silakan masukkan nama Anda',
'phone_label' => 'Nomor Telepon',
'phone_placeholder' => 'Masukkan nomor telepon Anda',
'referral_label' => 'Kode Referral',
'referral_placeholder' => 'Masukkan kode referral (opsional)',
'gender_label' => 'Jenis Kelamin',
'select_gender' => 'Pilih Jenis Kelamin',
'gender_male' => 'Laki-laki',
'gender_female' => 'Perempuan',
'date_of_birth_label' => 'Tanggal Lahir',
'date_of_birth_placeholder' => 'Pilih tanggal lahir Anda',
'save_password' => 'Simpan kata sandi',
'privacy_policy' => 'Saya telah membaca dan menerima :privacy_policy',
'privacy_policy_link' => 'Kebijakan Privasi',
'create_account' => 'Buat akun',
'or_continue_with' => 'atau lanjutkan dengan',
'google' => 'Google',
'facebook' => 'Facebook',
'apple' => 'Apple',
'need_help' => 'Butuh bantuan?',
'rights_reserved' => ' Semua hak dilindungi. Dibuat oleh :company',
'company_name' => 'Coderthemes',
// Benefits section
'benefits_title' => 'Mengapa membuat akun?',
'benefit_1_title' => 'Berlangganan produk favorit Anda',
'benefit_1_description' => 'Simpan produk favorit Anda dan dapatkan notifikasi saat ada diskon.',
'benefit_2_title' => 'Lihat dan kelola pesanan dan daftar keinginan Anda',
'benefit_2_description' => 'Lacak pesanan Anda dan lihat riwayat pesanan.',
'benefit_3_title' => 'Dapatkan hadiah untuk pembelian di masa depan',
'benefit_3_description' => 'Dapatkan poin hadiah untuk setiap pembelian yang Anda lakukan.',
'benefit_4_title' => 'Dapatkan penawaran dan diskon eksklusif',
'benefit_4_description' => 'Dapatkan akses ke penawaran dan promosi eksklusif.',
'benefit_5_title' => 'Buat beberapa daftar keinginan',
'benefit_5_description' => 'Organisir produk favorit Anda ke dalam beberapa daftar keinginan.',
'benefit_6_title' => 'Bayar pembelian dengan cicilan',
'benefit_6_description' => 'Bayar pembelian Anda dengan cicilan yang mudah.',
];

View File

@ -8,105 +8,127 @@
<!-- Logo -->
<header class="navbar px-0 pb-4 mt-n2 mt-sm-0 mb-2 mb-md-3 mb-lg-4">
<a class="navbar-brand pt-0" href="/">
<span class="d-flex flex-shrink-0 text-primary me-2">
<svg height="36" width="36" xmlns="http://www.w3.org/2000/svg">
<path
d="M36 18.01c0 8.097-5.355 14.949-12.705 17.2a18.12 18.12 0 0 1-5.315.79C9.622 36 2.608 30.313.573 22.611.257 21.407.059 20.162 0 18.879v-1.758c.02-.395.059-.79.099-1.185.099-.908.277-1.817.514-2.686C2.687 5.628 9.682 0 18 0c5.572 0 10.551 2.528 13.871 6.517 1.502 1.797 2.648 3.91 3.359 6.201.494 1.659.771 3.436.771 5.292z"
fill="currentColor"></path>
<g fill="#fff">
<path
d="M17.466 21.624c-.514 0-.988-.316-1.146-.829-.198-.632.138-1.303.771-1.501l7.666-2.469-1.205-8.254-13.317 4.621a1.19 1.19 0 0 1-1.521-.75 1.19 1.19 0 0 1 .751-1.521l13.89-4.818c.553-.197 1.166-.138 1.64.158a1.82 1.82 0 0 1 .85 1.284l1.344 9.183c.138.987-.494 1.994-1.482 2.33l-7.864 2.528-.375.04zm7.31.138c-.178-.632-.85-1.007-1.482-.81l-5.177 1.58c-2.331.79-3.28.02-3.418-.099l-6.56-8.412a4.25 4.25 0 0 0-4.406-1.758l-3.122.987c-.237.889-.415 1.777-.514 2.686l4.228-1.363a1.84 1.84 0 0 1 1.857.81l6.659 8.551c.751.948 2.015 1.323 3.359 1.323.909 0 1.857-.178 2.687-.474l5.078-1.54c.632-.178 1.008-.829.81-1.481z">
</path>
<use href="#czlogo"></use>
<use href="#czlogo" x="8.516" y="-2.172"></use>
</g>
<defs>
<path
d="M18.689 28.654a1.94 1.94 0 0 1-1.936 1.935 1.94 1.94 0 0 1-1.936-1.935 1.94 1.94 0 0 1 1.936-1.935 1.94 1.94 0 0 1 1.936 1.935z"
id="czlogo"></path>
</defs>
</svg>
</span>
AsiaGolf
<img src="{{ asset('logo/logo-colored.png') }}" alt="Logo" />
</a>
</header>
<h1 class="h2 mt-auto">Create an account</h1>
<h1 class="h2 mt-auto">{{ __('signup.title') }}</h1>
<div class="nav fs-sm mb-3 mb-lg-4">
I already have an account
{{ __('signup.already_have_account') }}
<a class="nav-link text-decoration-underline p-0 ms-2"
href="{{ route('second', ['account', 'signin']) }}">Sign in</a>
href="{{ route('second', ['account', 'signin']) }}">{{ __('signup.sign_in') }}</a>
</div>
<div class="nav fs-sm mb-4 d-lg-none">
<span class="me-2">Uncertain about creating an account?</span>
<span class="me-2">{{ __('signup.uncertain_about_account') }}</span>
<a aria-controls="benefits" class="nav-link text-decoration-underline p-0" data-bs-toggle="offcanvas"
href="#benefits">Explore the Benefits</a>
href="#benefits">{{ __('signup.explore_benefits') }}</a>
</div>
<!-- Form -->
<form class="needs-validation" novalidate="">
<form class="needs-validation" novalidate="" method="POST" action="{{ route('register') }}">
@csrf
<!-- Error Messages -->
@if ($errors->any())
<div class="alert alert-danger mb-4">
<ul class="mb-0">
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
@if(session('error'))
<div class="alert alert-danger mb-4">
{{ session('error') }}
</div>
@endif
@if(session('success'))
<div class="alert alert-success mb-4">
{{ session('success') }}
</div>
@endif
<div class="position-relative mb-4">
<label class="form-label" for="register-email">Email</label>
<input class="form-control form-control-lg" id="register-email" required="" type="email" />
<div class="invalid-tooltip bg-transparent py-0">Enter a valid email address!</div>
<label class="form-label" for="register-name">{{ __('signup.name_label') }}</label>
<input class="form-control form-control-lg" id="register-name" name="name"
placeholder="{{ __('signup.name_placeholder') }}" required="" type="text" value="{{ old('name') }}" />
<div class="invalid-tooltip bg-transparent py-0">{{ __('signup.name_invalid') }}</div>
</div>
<div class="mb-4">
<label class="form-label" for="register-password">Password</label>
<div class="password-toggle">
<input class="form-control form-control-lg" id="register-password" minlength="8"
placeholder="Minimum 8 characters" required="" type="password" />
<div class="invalid-tooltip bg-transparent py-0">Password does not meet the required criteria!
<div class="position-relative mb-4">
<label class="form-label" for="register-email">{{ __('signup.email_label') }}</label>
<input class="form-control form-control-lg" id="register-email" name="email"
placeholder="{{ __('signup.email_placeholder') }}" type="email" value="{{ old('email') }}" />
<div class="invalid-tooltip bg-transparent py-0">{{ __('signup.email_invalid') }}</div>
</div>
<label aria-label="Show/hide password" class="password-toggle-button fs-lg">
<input class="btn-check" type="checkbox" />
</label>
<div class="position-relative mb-4">
<label class="form-label" for="register-phone">{{ __('signup.phone_label') }}</label>
<input class="form-control form-control-lg" id="register-phone" name="phone"
placeholder="{{ __('signup.phone_placeholder') }}" type="tel" value="{{ old('phone') }}" />
</div>
<div class="position-relative mb-4">
<label class="form-label" for="register-referral">{{ __('signup.referral_label') }}</label>
<input class="form-control form-control-lg" id="register-referral" name="referral"
placeholder="{{ __('signup.referral_placeholder') }}" type="text" value="{{ old('referral') }}" />
</div>
<div class="row mb-4">
<div class="col-md-6">
<label class="form-label" for="register-gender">{{ __('signup.gender_label') }}</label>
<select class="form-select form-select-lg" id="register-gender" name="gender">
<option value="" {{ old('gender') == '' ? 'selected' : '' }}>{{ __('signup.select_gender') }}</option>
<option value="LAKI-LAKI" {{ old('gender') == 'LAKI-LAKI' ? 'selected' : '' }}>{{ __('signup.gender_male') }}</option>
<option value="PEREMPUAN" {{ old('gender') == 'PEREMPUAN' ? 'selected' : '' }}>{{ __('signup.gender_female') }}</option>
</select>
</div>
<div class="col-md-6">
<label class="form-label" for="register-date-of-birth">{{ __('signup.date_of_birth_label') }}</label>
<input class="form-control form-control-lg" id="register-date-of-birth" name="date_of_birth"
placeholder="{{ __('signup.date_of_birth_placeholder') }}" type="date" value="{{ old('date_of_birth') }}" />
</div>
</div>
<div class="d-flex flex-column gap-2 mb-4">
<div class="form-check">
<input class="form-check-input" id="save-pass" type="checkbox" />
<label class="form-check-label" for="save-pass">Save the password</label>
</div>
<div class="form-check">
<input class="form-check-input" id="privacy" required="" type="checkbox" />
<label class="form-check-label" for="privacy">I have read and accept the <a
class="text-dark-emphasis" href="#!">Privacy Policy</a></label>
<label class="form-check-label" for="privacy">{!! __('signup.privacy_policy', ['privacy_policy' => '<a class="text-dark-emphasis" href="#!">' . __('signup.privacy_policy_link') . '</a>']) !!}</label>
</div>
</div>
<button class="btn btn-lg btn-primary w-100" type="submit">
Create an account
{{ __('signup.create_account') }}
<i class="ci-chevron-right fs-lg ms-1 me-n1"></i>
</button>
</form>
<!-- Divider -->
<div class="d-flex align-items-center my-4">
<hr class="w-100 m-0" />
<span class="text-body-emphasis fw-medium text-nowrap mx-4">or continue with</span>
<span class="text-body-emphasis fw-medium text-nowrap mx-4">{{ __('signup.or_continue_with') }}</span>
<hr class="w-100 m-0" />
</div>
<!-- Social login -->
<div class="d-flex flex-column flex-sm-row gap-3 pb-4 mb-3 mb-lg-4">
<button class="btn btn-lg btn-outline-secondary w-100 px-2" type="button">
<i class="ci-google ms-1 me-1"></i>
Google
{{ __('signup.google') }}
</button>
<button class="btn btn-lg btn-outline-secondary w-100 px-2" type="button">
<i class="ci-facebook ms-1 me-1"></i>
Facebook
{{ __('signup.facebook') }}
</button>
<button class="btn btn-lg btn-outline-secondary w-100 px-2" type="button">
<i class="ci-apple ms-1 me-1"></i>
Apple
{{ __('signup.apple') }}
</button>
</div>
<!-- Footer -->
<footer class="mt-auto">
<div class="nav mb-4">
<a class="nav-link text-decoration-underline p-0"
href="{{ route('second', ['help', 'topics-v1']) }}">Need help?</a>
href="{{ route('second', ['help', 'topics-v1']) }}">{{ __('signup.need_help') }}</a>
</div>
<p class="fs-xs mb-0">
© All rights reserved. Made by <span class="animate-underline"><a
class="animate-target text-dark-emphasis text-decoration-none"
href="https://coderthemes.com/" rel="noreferrer" target="_blank">Coderthemes</a></span>
href="https://coderthemes.com/" rel="noreferrer" target="blank">{{ __('signup.company_name') }}</a></span>
</p>
</footer>
</div>
@ -139,7 +161,7 @@
style="background: linear-gradient(-90deg, #1b273a 0%, #1f2632 100%)"></span>
</div>
<div class="position-relative z-2 w-100 text-center px-md-2 p-lg-5">
<h2 class="h4 pb-3">AsiaGolf account benefits</h2>
<h2 class="h4 pb-3">{{ __('signup.benefits_title') }}</h2>
<div class="mx-auto" style="max-width: 790px">
<div class="row row-cols-1 row-cols-sm-2 g-3 g-md-4 g-lg-3 g-xl-4">
<div class="col">
@ -157,7 +179,7 @@
class="position-absolute top-0 start-0 w-100 h-100 bg-body-secondary rounded-pill d-none d-block-dark"></span>
<i class="ci-mail position-relative z-2 fs-4 m-1"></i>
</div>
<h3 class="h6 pt-2 my-2">Subscribe to your favorite products</h3>
<h3 class="h6 pt-2 my-2">{{ __('signup.benefit_1_title') }}</h3>
</div>
</div>
</div>
@ -176,7 +198,7 @@
class="position-absolute top-0 start-0 w-100 h-100 bg-body-secondary rounded-pill d-none d-block-dark"></span>
<i class="ci-settings position-relative z-2 fs-4 m-1"></i>
</div>
<h3 class="h6 pt-2 my-2">View and manage your orders and wishlist</h3>
<h3 class="h6 pt-2 my-2">{{ __('signup.benefit_2_title') }}</h3>
</div>
</div>
</div>
@ -195,7 +217,7 @@
class="position-absolute top-0 start-0 w-100 h-100 bg-body-secondary rounded-pill d-none d-block-dark"></span>
<i class="ci-gift position-relative z-2 fs-4 m-1"></i>
</div>
<h3 class="h6 pt-2 my-2">Earn rewards for future purchases</h3>
<h3 class="h6 pt-2 my-2">{{ __('signup.benefit_3_title') }}</h3>
</div>
</div>
</div>
@ -214,7 +236,7 @@
class="position-absolute top-0 start-0 w-100 h-100 bg-body-secondary rounded-pill d-none d-block-dark"></span>
<i class="ci-percent position-relative z-2 fs-4 m-1"></i>
</div>
<h3 class="h6 pt-2 my-2">Receive exclusive offers and discounts</h3>
<h3 class="h6 pt-2 my-2">{{ __('signup.benefit_4_title') }}</h3>
</div>
</div>
</div>
@ -233,7 +255,7 @@
class="position-absolute top-0 start-0 w-100 h-100 bg-body-secondary rounded-pill d-none d-block-dark"></span>
<i class="ci-heart position-relative z-2 fs-4 m-1"></i>
</div>
<h3 class="h6 pt-2 my-2">Create multiple wishlists</h3>
<h3 class="h6 pt-2 my-2">{{ __('signup.benefit_5_title') }}</h3>
</div>
</div>
</div>
@ -252,7 +274,7 @@
class="position-absolute top-0 start-0 w-100 h-100 bg-body-secondary rounded-pill d-none d-block-dark"></span>
<i class="ci-pie-chart position-relative z-2 fs-4 m-1"></i>
</div>
<h3 class="h6 pt-2 my-2">Pay for purchases by installments</h3>
<h3 class="h6 pt-2 my-2">{{ __('signup.benefit_6_title') }}</h3>
</div>
</div>
</div>

View File

@ -235,7 +235,7 @@
<!-- Account button visible on screens > 768px wide (md breakpoint) -->
<a class="btn btn-icon btn-lg fs-lg btn-outline-secondary border-0 rounded-circle animate-shake d-none d-md-inline-flex"
href="{{ route('second', ['account', 'signin']) }}">
href="{{ route('register') }}">
<i class="ci-user animate-target"></i>
<span class="visually-hidden">Account</span>
</a>

View File

@ -1,5 +1,6 @@
<?php
use App\Http\Controllers\Auth\RegisterController;
use App\Http\Controllers\HomeController;
use Illuminate\Support\Facades\Route;
use App\Http\Controllers\RoutingController;
@ -39,3 +40,6 @@ Route::get('/search', [SearchController::class, 'search'])->name('search.ajax');
// Component loading routes
Route::get('/components/{component}', [ComponentController::class, 'load'])->name('component.load');
Route::get('/register', [RegisterController::class, 'index'])->name('register');
Route::post('/register', [RegisterController::class, 'register'])->name('register');