address
This commit is contained in:
parent
b0eda5e389
commit
a2caec5b74
|
|
@ -0,0 +1,56 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Http\Controllers\Auth;
|
||||||
|
|
||||||
|
use App\Http\Controllers\Controller;
|
||||||
|
use App\Models\Province;
|
||||||
|
use App\Models\District;
|
||||||
|
use App\Models\Subdistrict;
|
||||||
|
use App\Models\City;
|
||||||
|
use Illuminate\Http\Request;
|
||||||
|
|
||||||
|
class AddressController extends Controller
|
||||||
|
{
|
||||||
|
public function index(Request $request)
|
||||||
|
{
|
||||||
|
$addresses = auth()->user()->addresses;
|
||||||
|
return view('account.addresses', compact('addresses'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function provinces()
|
||||||
|
{
|
||||||
|
$provinces = Province::orderBy('name')->get();
|
||||||
|
|
||||||
|
|
||||||
|
return [
|
||||||
|
'data' => $provinces,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function cities($provinceId)
|
||||||
|
{
|
||||||
|
$cities = City::where('province_id', $provinceId)->orderBy('name')->get();
|
||||||
|
|
||||||
|
return [
|
||||||
|
'data' => $cities,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function districts($city_id)
|
||||||
|
{
|
||||||
|
$districts = District::where('city_id', $city_id)->orderBy('name')->get();
|
||||||
|
|
||||||
|
return [
|
||||||
|
'data' => $districts,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
public function villages($districtId)
|
||||||
|
{
|
||||||
|
$villages = Subdistrict::where('district_id', $districtId)->orderBy('name')->get();
|
||||||
|
|
||||||
|
return [
|
||||||
|
'data' => $villages,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -31,7 +31,7 @@ class SetLocale
|
||||||
|
|
||||||
// Check if locale is in session
|
// Check if locale is in session
|
||||||
elseif (Session::has('locale')) {
|
elseif (Session::has('locale')) {
|
||||||
$locale = Session::get('locale');
|
$locale = Session::get('locale') ?? 'id';
|
||||||
|
|
||||||
if (in_array($locale, ['en', 'id'])) {
|
if (in_array($locale, ['en', 'id'])) {
|
||||||
App::setLocale($locale);
|
App::setLocale($locale);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
<?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 Address extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
use SoftDeletes;
|
||||||
|
use LogsActivity;
|
||||||
|
|
||||||
|
public function getActivitylogOptions(): LogOptions
|
||||||
|
{
|
||||||
|
return LogOptions::defaults();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected $table = 'address';
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'label',
|
||||||
|
'name',
|
||||||
|
'address',
|
||||||
|
'province_id',
|
||||||
|
'city_id',
|
||||||
|
'district_id',
|
||||||
|
'subdistrict_id',
|
||||||
|
'province_name',
|
||||||
|
'city_name',
|
||||||
|
'district_name',
|
||||||
|
'subdistrict_name',
|
||||||
|
'postal_code',
|
||||||
|
'phone',
|
||||||
|
'longitude',
|
||||||
|
'latitude',
|
||||||
|
'user_id',
|
||||||
|
'is_primary'
|
||||||
|
];
|
||||||
|
|
||||||
|
public function user()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(User::class, 'user_id', 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function province()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Province::class, 'province_id', 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function city()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(City::class, 'city_id', 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function district()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(District::class, 'district_id', 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function subdistrict()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Subdistrict::class, 'subdistrict_id', 'id');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function getLocationAttribute()
|
||||||
|
{
|
||||||
|
$province = $this->province?->name;
|
||||||
|
$city = $this->city?->name;
|
||||||
|
$district = $this->district?->name;
|
||||||
|
$subdistrict = $this->subdistrict?->name;
|
||||||
|
$postalCode = $this->postal_code;
|
||||||
|
|
||||||
|
return "{$province}, {$city}, {$district}, {$subdistrict}, {$postalCode}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class City extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $fillable = ['province_id', 'name'];
|
||||||
|
|
||||||
|
public function province()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(Province::class, 'province_id', 'id');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class District extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $fillable = ['city_id', 'name'];
|
||||||
|
|
||||||
|
public function city()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(City::class, 'city_id', 'id');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class PosCode extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $fillable = [
|
||||||
|
'code',
|
||||||
|
'village',
|
||||||
|
'district',
|
||||||
|
'regency',
|
||||||
|
'province',
|
||||||
|
'latitude',
|
||||||
|
'longitude',
|
||||||
|
'elevation',
|
||||||
|
'timezone',
|
||||||
|
];
|
||||||
|
|
||||||
|
public function provinceRef(){
|
||||||
|
return $this->belongsTo(Province::class,"provice_id","id");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function cityRef(){
|
||||||
|
return $this->belongsTo(City::class,"city_id","id");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function districtRef(){
|
||||||
|
return $this->belongsTo(City::class,"district_id","id");
|
||||||
|
}
|
||||||
|
|
||||||
|
public function subdistrictRef(){
|
||||||
|
return $this->belongsTo(City::class,"subdistrict_id","id");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Province extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $fillable = ['name'];
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Models;
|
||||||
|
|
||||||
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
||||||
|
class Subdistrict extends Model
|
||||||
|
{
|
||||||
|
use HasFactory;
|
||||||
|
|
||||||
|
protected $fillable = ['district_id', 'name'];
|
||||||
|
|
||||||
|
public function district()
|
||||||
|
{
|
||||||
|
return $this->belongsTo(District::class, 'district_id', 'id');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -56,4 +56,9 @@ class User extends Authenticatable
|
||||||
{
|
{
|
||||||
return $this->hasOne(Customer::class);
|
return $this->hasOne(Customer::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function addresses()
|
||||||
|
{
|
||||||
|
return $this->hasMany(Address::class);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,295 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace App\Repositories\Member\Address;
|
||||||
|
|
||||||
|
use App\Models\Address;
|
||||||
|
use App\Models\City;
|
||||||
|
use App\Models\District;
|
||||||
|
use App\Models\Province;
|
||||||
|
use App\Models\Subdistrict;
|
||||||
|
use App\Models\PosCode;
|
||||||
|
|
||||||
|
use Illuminate\Support\Facades\DB;
|
||||||
|
use Illuminate\Support\Facades\Http;
|
||||||
|
use Illuminate\Database\Eloquent\ModelNotFoundException;
|
||||||
|
use Illuminate\Support\Facades\Cache;
|
||||||
|
|
||||||
|
class MemberAddressRepository
|
||||||
|
{
|
||||||
|
public function getList($request)
|
||||||
|
{
|
||||||
|
$model = Address::where('user_id', auth()->user()->id)->orderBy('created_at','desc')->paginate($request->limit);
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function geocode($params){
|
||||||
|
|
||||||
|
$lat = @$params["latitude"];
|
||||||
|
$lon = @$params["longitude"];
|
||||||
|
$res = Cache::remember("geocode_$lat\_$lon", 60 * 60 * 24, function () use ($lat, $lon){
|
||||||
|
return Http::get("https://nominatim.openstreetmap.org/reverse",[
|
||||||
|
"email" => "husnusetiawan@gmail.com",
|
||||||
|
"lat" => $lat,
|
||||||
|
"lon" => $lon,
|
||||||
|
"format" => "json"
|
||||||
|
])->json();
|
||||||
|
});
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
try {
|
||||||
|
$address = @$res["address"];
|
||||||
|
|
||||||
|
$posCode = PosCode::where("code", $address['postcode'])->firstOrFail();
|
||||||
|
|
||||||
|
$province_id = $posCode->province_id ?? null;
|
||||||
|
$city_id = $posCode->city_id ?? null;
|
||||||
|
$district_id = $posCode->district_id ?? null;
|
||||||
|
$subdistrict_id = $posCode->subdistrict_id ?? null;
|
||||||
|
if ($address != null) {
|
||||||
|
$addr_province = $address["state"] ?? $address["city"] ?? $posCode->province;
|
||||||
|
$addr_city = $address["city"] ?? $address["county"] ?? $address["city_district"] ?? $posCode->city;
|
||||||
|
$addr_district = $address["suburb"] ?? $address["district"] ?? $posCode->district;
|
||||||
|
$addr_subdistrict = $address["neighbourhood"] ?? $address["village"] ?? $posCode->subdistrict;
|
||||||
|
|
||||||
|
if ($addr_province != null && $province_id == null) {
|
||||||
|
// search by nominatim
|
||||||
|
$province = Province::whereRaw('name ILIKE ?', ['%' . trim($addr_province) . '%'])->first();
|
||||||
|
|
||||||
|
// search by poscode
|
||||||
|
if ($province == null) {
|
||||||
|
$province = Province::whereRaw('name ILIKE ?', ['%' . trim($posCode->province) . '%'])->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
$province_id = $posCode->province_id ?? $province->id ?? null;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($addr_city != null && $city_id == null) {
|
||||||
|
// search by nominatim
|
||||||
|
$city = City::whereRaw('name ILIKE ?', ['%' . trim($addr_city) . '%'])
|
||||||
|
->where("province_id", $province_id)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
// search by poscode
|
||||||
|
if ($city == null) {
|
||||||
|
$city = City::whereRaw('name ILIKE ?', ['%' . trim($posCode->city) . '%'])
|
||||||
|
->where("province_id", $province_id)
|
||||||
|
->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
$city_id = $posCode->city_id ?? $city->id ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if ($addr_district != null && $district_id == null) {
|
||||||
|
// search by nominatim
|
||||||
|
$district = District::whereRaw('name ILIKE ?', ['%' . trim($addr_district) . '%'])
|
||||||
|
->where("city_id", $city_id)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// search by poscode
|
||||||
|
if ($district == null) {
|
||||||
|
$district = District::whereRaw('name ILIKE ?', ['%' . trim($posCode->district) . '%'])
|
||||||
|
->where("city_id", $city_id)
|
||||||
|
->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
$district_id = $posCode->district_id ?? $district->id ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($addr_subdistrict != null && $subdistrict_id == null) {
|
||||||
|
// search by nominatim
|
||||||
|
$subdistrict = Subdistrict::whereRaw('name ILIKE ?', ['%' . trim($addr_subdistrict) . '%'])
|
||||||
|
->where("district_id", $district_id)
|
||||||
|
->first();
|
||||||
|
|
||||||
|
// search by poscode
|
||||||
|
if ($subdistrict == null) {
|
||||||
|
$subdistrict = Subdistrict::whereRaw('name ILIKE ?', ['%' . trim($posCode->subdistrict) . '%'])
|
||||||
|
->where("district_id", $district_id)
|
||||||
|
->first();
|
||||||
|
}
|
||||||
|
|
||||||
|
$subdistrict_id = $posCode->subdistrict_id ?? $subdistrict->id ?? null;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
$address = new Address([
|
||||||
|
'label' => "",
|
||||||
|
'name' => "",
|
||||||
|
'address' => $address["road"] ?? $res["display_name"],
|
||||||
|
'province_id' => $province_id,
|
||||||
|
'city_id' => $city_id,
|
||||||
|
'district_id' => $district_id,
|
||||||
|
'subdistrict_id' => $subdistrict_id,
|
||||||
|
|
||||||
|
'postal_code' => $address['postcode'],
|
||||||
|
'phone' => "",
|
||||||
|
'latitude' => $res['lat'],
|
||||||
|
'longitude' => $res['lon'],
|
||||||
|
'user_id' => auth()->user()->id,
|
||||||
|
'is_primary' => false
|
||||||
|
]);
|
||||||
|
} catch (ModelNotFoundException $e) {
|
||||||
|
|
||||||
|
abort(404, 'lokasi tidak didukung');
|
||||||
|
}
|
||||||
|
|
||||||
|
return $address;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function create($data)
|
||||||
|
{
|
||||||
|
$model = DB::transaction(function () use ($data) {
|
||||||
|
|
||||||
|
$model = Address::create([
|
||||||
|
'label' => $data['label'],
|
||||||
|
'name' => $data['name'],
|
||||||
|
'address' => $data['address'],
|
||||||
|
'province_id' => $data['province_id'],
|
||||||
|
'city_id' => $data['city_id'],
|
||||||
|
'district_id' => $data['district_id'],
|
||||||
|
'subdistrict_id' => $data['subdistrict_id'],
|
||||||
|
'postal_code' => $data['postal_code'],
|
||||||
|
'phone' => $data['phone'],
|
||||||
|
'latitude' => $data['latitude'],
|
||||||
|
'longitude' => $data['longitude'],
|
||||||
|
'user_id' => auth()->user()->id,
|
||||||
|
'is_primary' => $data['is_primary']
|
||||||
|
]);
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
});
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function update($id ,$data)
|
||||||
|
{
|
||||||
|
$model = DB::transaction(function () use ($id, $data) {
|
||||||
|
|
||||||
|
$model = Address::findOrFail($id);
|
||||||
|
$model->label = $data['label'] ?? $model->label;
|
||||||
|
$model->name = $data['name'] ?? $model->name;
|
||||||
|
$model->address = $data['address'] ?? $model->address;
|
||||||
|
$model->province_id = $data['province_id'] ?? $model->province_id;
|
||||||
|
$model->city_id = $data['city_id'] ?? $model->city_id;
|
||||||
|
$model->district_id = $data['district_id'] ?? $model->district_id;
|
||||||
|
$model->subdistrict_id = $data['subdistrict_id'] ?? $model->subdistrict_id;
|
||||||
|
$model->postal_code = $data['postal_code'] ?? $model->postal_code;
|
||||||
|
$model->phone = $data['phone'] ?? $model->phone;
|
||||||
|
$model->latitude = $data['latitude'] ?? $model->latitude;
|
||||||
|
$model->longitude = $data['longitude'] ?? $model->longitude;
|
||||||
|
$model->is_primary = $data['is_primary'] ?? $model->is_primary;
|
||||||
|
$model->save();
|
||||||
|
return $model;
|
||||||
|
});
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setPrimary($id)
|
||||||
|
{
|
||||||
|
$model = DB::transaction(function () use ($id) {
|
||||||
|
|
||||||
|
$model = Address::findOrFail($id);
|
||||||
|
|
||||||
|
Address::where("user_id", $model->user_id)->update([
|
||||||
|
"is_primary" => 0
|
||||||
|
]);
|
||||||
|
|
||||||
|
|
||||||
|
$model->is_primary = 1;
|
||||||
|
$model->save();
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
});
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function delete($model)
|
||||||
|
{
|
||||||
|
$model = DB::transaction(function () use ($model) {
|
||||||
|
$model->delete();
|
||||||
|
return $model;
|
||||||
|
});
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getProvince($request)
|
||||||
|
{
|
||||||
|
$model = Province::orderBy('name','desc')->where("is_new",true)->paginate($request->limit);
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCity($request)
|
||||||
|
{
|
||||||
|
$all = $request->all();
|
||||||
|
|
||||||
|
$model = City::orderBy('name','desc')->where("is_new",true)
|
||||||
|
->where(function($query) use ($all){
|
||||||
|
if (@$all["province_id"])
|
||||||
|
$query->where("province_id", $all["province_id"]);
|
||||||
|
})->paginate($request->limit);
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDistrict($request)
|
||||||
|
{
|
||||||
|
$all = $request->all();
|
||||||
|
|
||||||
|
$model = District::orderBy('name','desc')->where("is_new",true)
|
||||||
|
->where(function($query) use ($all){
|
||||||
|
if (@$all["city_id"])
|
||||||
|
$query->where("city_id", $all["city_id"]);
|
||||||
|
})->paginate($request->limit);
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getSubdistrict($request)
|
||||||
|
{
|
||||||
|
$all = $request->all();
|
||||||
|
$model = Subdistrict::orderBy('name','desc')->where("is_new",true)
|
||||||
|
->where(function($query) use ($all){
|
||||||
|
if (@$all["district_id"])
|
||||||
|
$query->where("district_id", $all["district_id"]);
|
||||||
|
})
|
||||||
|
->paginate($request->limit);
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getPoscode($request)
|
||||||
|
{
|
||||||
|
|
||||||
|
$all = $request->all();
|
||||||
|
$model = PosCode::orderBy('province','desc')
|
||||||
|
->where(function($query) use ($all){
|
||||||
|
if (@$all["village"])
|
||||||
|
$query->where("village", $all["village"]);
|
||||||
|
|
||||||
|
if (@$all["district"])
|
||||||
|
$query->where("district", $all["district"]);
|
||||||
|
|
||||||
|
if (@$all["regency"])
|
||||||
|
$query->where("regency", $all["regency"]);
|
||||||
|
})
|
||||||
|
->paginate($request->limit);
|
||||||
|
|
||||||
|
return $model;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'page_title' => 'Addresses',
|
||||||
|
'shipping_address' => 'Shipping address',
|
||||||
|
'primary' => 'Primary',
|
||||||
|
'edit' => 'Edit',
|
||||||
|
'country' => 'Country',
|
||||||
|
'select_country' => 'Select country...',
|
||||||
|
'province' => 'Province',
|
||||||
|
'select_province' => 'Select province...',
|
||||||
|
'city' => 'City',
|
||||||
|
'select_city' => 'Select city...',
|
||||||
|
'district' => 'District',
|
||||||
|
'select_district' => 'Select district...',
|
||||||
|
'village' => 'Village',
|
||||||
|
'select_village' => 'Select village...',
|
||||||
|
'zip_code' => 'ZIP code',
|
||||||
|
'address' => 'Address',
|
||||||
|
'set_as_primary_address' => 'Set as primary address',
|
||||||
|
'save_changes' => 'Save changes',
|
||||||
|
'close' => 'Close',
|
||||||
|
'alternative_shipping_address' => 'Alternative shipping address',
|
||||||
|
'add_address' => 'Add address',
|
||||||
|
'please_select_country' => 'Please select your country!',
|
||||||
|
'please_select_province' => 'Please select your province!',
|
||||||
|
'please_select_city' => 'Please select your city!',
|
||||||
|
'please_select_district' => 'Please select your district!',
|
||||||
|
'please_select_village' => 'Please select your village!',
|
||||||
|
'please_enter_zip_code' => 'Please enter your ZIP code!',
|
||||||
|
'please_enter_address' => 'Please enter your address!',
|
||||||
|
'regions' => [
|
||||||
|
'africa' => 'Africa',
|
||||||
|
'asia' => 'Asia',
|
||||||
|
'europe' => 'Europe',
|
||||||
|
'north_america' => 'North America',
|
||||||
|
'south_america' => 'South America',
|
||||||
|
'oceania' => 'Oceania'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
@ -0,0 +1,40 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
return [
|
||||||
|
'page_title' => 'Alamat',
|
||||||
|
'shipping_address' => 'Alamat Pengiriman',
|
||||||
|
'primary' => 'Utama',
|
||||||
|
'edit' => 'Edit',
|
||||||
|
'country' => 'Negara',
|
||||||
|
'select_country' => 'Pilih negara...',
|
||||||
|
'province' => 'Provinsi',
|
||||||
|
'select_province' => 'Pilih provinsi...',
|
||||||
|
'city' => 'Kota',
|
||||||
|
'select_city' => 'Pilih kota...',
|
||||||
|
'district' => 'Kecamatan',
|
||||||
|
'select_district' => 'Pilih kecamatan...',
|
||||||
|
'village' => 'Kelurahan',
|
||||||
|
'select_village' => 'Pilih kelurahan...',
|
||||||
|
'zip_code' => 'Kode Pos',
|
||||||
|
'address' => 'Alamat',
|
||||||
|
'set_as_primary_address' => 'Jadikan alamat utama',
|
||||||
|
'save_changes' => 'Simpan perubahan',
|
||||||
|
'close' => 'Tutup',
|
||||||
|
'alternative_shipping_address' => 'Alamat Pengiriman Alternatif',
|
||||||
|
'add_address' => 'Tambah alamat',
|
||||||
|
'please_select_country' => 'Silakan pilih negara Anda!',
|
||||||
|
'please_select_province' => 'Silakan pilih provinsi Anda!',
|
||||||
|
'please_select_city' => 'Silakan pilih kota Anda!',
|
||||||
|
'please_select_district' => 'Silakan pilih kecamatan Anda!',
|
||||||
|
'please_select_village' => 'Silakan pilih kelurahan Anda!',
|
||||||
|
'please_enter_zip_code' => 'Silakan masukkan kode pos Anda!',
|
||||||
|
'please_enter_address' => 'Silakan masukkan alamat Anda!',
|
||||||
|
'regions' => [
|
||||||
|
'africa' => 'Afrika',
|
||||||
|
'asia' => 'Asia',
|
||||||
|
'europe' => 'Eropa',
|
||||||
|
'north_america' => 'Amerika Utara',
|
||||||
|
'south_america' => 'Amerika Selatan',
|
||||||
|
'oceania' => 'Oseania'
|
||||||
|
]
|
||||||
|
];
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
@extends('layouts.account', ['title' => 'Account - Addresses'])
|
@extends('layouts.account', ['title' => __('addresses.page_title')])
|
||||||
|
|
||||||
@section('content')
|
@section('content')
|
||||||
<!-- Addresses content -->
|
<!-- Addresses content -->
|
||||||
|
|
@ -6,198 +6,177 @@
|
||||||
<div class="ps-lg-3 ps-xl-0">
|
<div class="ps-lg-3 ps-xl-0">
|
||||||
|
|
||||||
<!-- Page title -->
|
<!-- Page title -->
|
||||||
<h1 class="h2 mb-1 mb-sm-2">Addresses</h1>
|
<h1 class="h2 mb-1 mb-sm-2">{{ __('addresses.page_title') }}</h1>
|
||||||
|
|
||||||
<!-- Primary shipping address -->
|
@foreach ($addresses as $address)
|
||||||
<div class="border-bottom py-4">
|
<div class="border-bottom py-4">
|
||||||
<div class="nav flex-nowrap align-items-center justify-content-between pb-1 mb-3">
|
<div class="nav flex-nowrap align-items-center justify-content-between pb-1 mb-3">
|
||||||
<div class="d-flex align-items-center gap-3 me-4">
|
<div class="d-flex align-items-center gap-3 me-4">
|
||||||
<h2 class="h6 mb-0">Shipping address</h2>
|
<h2 class="h6 mb-0">{{ $address->label }}</h2>
|
||||||
<span class="badge text-bg-info rounded-pill">Primary</span>
|
@if ($address->is_primary)
|
||||||
|
<span class="badge text-bg-info rounded-pill">{{ __('addresses.primary') }}</span>
|
||||||
|
@endif
|
||||||
|
</div>
|
||||||
|
<a class="nav-link hiding-collapse-toggle text-decoration-underline p-0 collapsed primaryAddressEditButton"
|
||||||
|
data-address-id="{{ $address->id }}" href=".primary-address-{{ $address->id }}"
|
||||||
|
data-bs-toggle="collapse" aria-expanded="false"
|
||||||
|
aria-controls="primaryAddressPreview{{ $address->id }} primaryAddressEdit{{ $address->id }}">{{ __('addresses.edit') }}</a>
|
||||||
|
</div>
|
||||||
|
<div class="collapse primary-address-{{ $address->id }} show"
|
||||||
|
id="primaryAddressPreview{{ $address->id }}">
|
||||||
|
<ul class="list-unstyled fs-sm m-0">
|
||||||
|
<li>{{ $address->location }}</li>
|
||||||
|
<li>{{ $address->address }}</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
<div class="collapse primary-address-{{ $address->id }}" id="primaryAddressEdit{{ $address->id }}">
|
||||||
|
<form class="row g-3 g-sm-4 needs-validation" novalidate>
|
||||||
|
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="position-relative">
|
||||||
|
<label class="form-label">{{ __('addresses.province') }}</label>
|
||||||
|
<select class="form-select province-select" data-select='{"searchEnabled": true}'
|
||||||
|
aria-label="Select city" required data-address-id="{{ $address->id }}">
|
||||||
|
<option value="">{{ __('addresses.select_province') }}</option>
|
||||||
|
</select>
|
||||||
|
<div class="invalid-feedback">{{ __('addresses.please_select_province') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="position-relative">
|
||||||
|
<label class="form-label">{{ __('addresses.city') }}</label>
|
||||||
|
<select class="form-select city-select" data-select='{"searchEnabled": true}'
|
||||||
|
aria-label="Select city" required data-address-id="{{ $address->id }}">
|
||||||
|
<option value="">{{ __('addresses.select_city') }}</option>
|
||||||
|
</select>
|
||||||
|
<div class="invalid-feedback">{{ __('addresses.please_select_city') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="position-relative">
|
||||||
|
<label class="form-label">{{ __('addresses.district') }}</label>
|
||||||
|
<select class="form-select district-select" data-select='{"searchEnabled": true}'
|
||||||
|
aria-label="Select district" required data-address-id="{{ $address->id }}">
|
||||||
|
<option value="">{{ __('addresses.select_district') }}</option>
|
||||||
|
</select>
|
||||||
|
<div class="invalid-feedback">{{ __('addresses.please_select_district') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-6">
|
||||||
|
<div class="position-relative">
|
||||||
|
<label class="form-label">{{ __('addresses.village') }}</label>
|
||||||
|
<select class="form-select village-select" data-select='{"searchEnabled": true}'
|
||||||
|
aria-label="Select village" required data-address-id="{{ $address->id }}">
|
||||||
|
<option value="">{{ __('addresses.select_village') }}</option>
|
||||||
|
</select>
|
||||||
|
<div class="invalid-feedback">{{ __('addresses.please_select_village') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-4">
|
||||||
|
<div class="position-relative">
|
||||||
|
<label for="psa-zip-{{ $address->id }}"
|
||||||
|
class="form-label">{{ __('addresses.zip_code') }}</label>
|
||||||
|
<input type="text" class="form-control" id="psa-zip-{{ $address->id }}"
|
||||||
|
value="{{ $address->postal_code }}" required>
|
||||||
|
<div class="invalid-feedback">{{ __('addresses.please_enter_zip_code') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-sm-8">
|
||||||
|
<div class="position-relative">
|
||||||
|
<label for="psa-address-{{ $address->id }}"
|
||||||
|
class="form-label">{{ __('addresses.address') }}</label>
|
||||||
|
<input type="text" class="form-control" id="psa-address-{{ $address->id }}"
|
||||||
|
value="{{ $address->address }}" required>
|
||||||
|
<div class="invalid-feedback">{{ __('addresses.please_enter_address') }}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="form-check mb-0">
|
||||||
|
<input type="checkbox" class="form-check-input" id="set-primary-{{ $address->id }}"
|
||||||
|
{{ $address->is_primary ? 'checked' : '' }}>
|
||||||
|
<label for="set-primary-{{ $address->id }}"
|
||||||
|
class="form-check-label">{{ __('addresses.set_as_primary_address') }}</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="col-12">
|
||||||
|
<div class="d-flex gap-3 pt-2 pt-sm-0">
|
||||||
|
<button type="submit"
|
||||||
|
class="btn btn-primary">{{ __('addresses.save_changes') }}</button>
|
||||||
|
<button type="button" class="btn btn-secondary" data-bs-toggle="collapse"
|
||||||
|
data-bs-target=".primary-address-{{ $address->id }}" aria-expanded="true"
|
||||||
|
aria-controls="primaryAddressPreview{{ $address->id }} primaryAddressEdit{{ $address->id }}">{{ __('addresses.close') }}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<a class="nav-link hiding-collapse-toggle text-decoration-underline p-0 collapsed" href=".primary-address"
|
|
||||||
data-bs-toggle="collapse" aria-expanded="false"
|
|
||||||
aria-controls="primaryAddressPreview primaryAddressEdit">Edit</a>
|
|
||||||
</div>
|
|
||||||
<div class="collapse primary-address show" id="primaryAddressPreview">
|
|
||||||
<ul class="list-unstyled fs-sm m-0">
|
|
||||||
<li>New York 11741, USA</li>
|
|
||||||
<li>396 Lillian Bolavandy, Holbrook</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="collapse primary-address" id="primaryAddressEdit">
|
|
||||||
<form class="row g-3 g-sm-4 needs-validation" novalidate>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<div class="position-relative">
|
|
||||||
<label class="form-label">Country</label>
|
|
||||||
<select class="form-select" data-select='{"searchEnabled": true}'
|
|
||||||
aria-label="Select country" required>
|
|
||||||
<option value="">Select country...</option>
|
|
||||||
<optgroup label="Africa">
|
|
||||||
<option value="Nigeria">Nigeria</option>
|
|
||||||
<option value="South Africa">South Africa</option>
|
|
||||||
<option value="Kenya">Kenya</option>
|
|
||||||
<option value="Egypt">Egypt</option>
|
|
||||||
<option value="Ethiopia">Ethiopia</option>
|
|
||||||
</optgroup>
|
|
||||||
<optgroup label="Asia">
|
|
||||||
<option value="China">China</option>
|
|
||||||
<option value="India">India</option>
|
|
||||||
<option value="Japan">Japan</option>
|
|
||||||
<option value="South Korea">South Korea</option>
|
|
||||||
<option value="Saudi Arabia">Saudi Arabia</option>
|
|
||||||
</optgroup>
|
|
||||||
<optgroup label="Europe">
|
|
||||||
<option value="Germany">Germany</option>
|
|
||||||
<option value="France">France</option>
|
|
||||||
<option value="United Kingdom">United Kingdom</option>
|
|
||||||
<option value="Italy">Italy</option>
|
|
||||||
<option value="Spain">Spain</option>
|
|
||||||
</optgroup>
|
|
||||||
<optgroup label="North America">
|
|
||||||
<option value="United States" selected>United States</option>
|
|
||||||
<option value="Canada">Canada</option>
|
|
||||||
<option value="Mexico">Mexico</option>
|
|
||||||
<option value="Jamaica">Jamaica</option>
|
|
||||||
<option value="Costa Rica">Costa Rica</option>
|
|
||||||
</optgroup>
|
|
||||||
<optgroup label="South America">
|
|
||||||
<option value="Brazil">Brazil</option>
|
|
||||||
<option value="Argentina">Argentina</option>
|
|
||||||
<option value="Colombia">Colombia</option>
|
|
||||||
<option value="Chile">Chile</option>
|
|
||||||
<option value="Peru">Peru</option>
|
|
||||||
</optgroup>
|
|
||||||
<optgroup label="Oceania">
|
|
||||||
<option value="Australia">Australia</option>
|
|
||||||
<option value="New Zealand">New Zealand</option>
|
|
||||||
<option value="Papua New Guinea">Papua New Guinea</option>
|
|
||||||
<option value="Fiji">Fiji</option>
|
|
||||||
<option value="Solomon Islands">Solomon Islands</option>
|
|
||||||
</optgroup>
|
|
||||||
</select>
|
|
||||||
<div class="invalid-feedback">Please select your country!</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-6">
|
|
||||||
<div class="position-relative">
|
|
||||||
<label class="form-label">City</label>
|
|
||||||
<select class="form-select" data-select='{"searchEnabled": true}' aria-label="Select city"
|
|
||||||
required>
|
|
||||||
<option value="">Select city...</option>
|
|
||||||
<option value="Austin">Austin</option>
|
|
||||||
<option value="Charlotte">Charlotte</option>
|
|
||||||
<option value="Chicago">Chicago</option>
|
|
||||||
<option value="Columbus">Columbus</option>
|
|
||||||
<option value="Dallas">Dallas</option>
|
|
||||||
<option value="Houston">Houston</option>
|
|
||||||
<option value="Jacksonville">Jacksonville</option>
|
|
||||||
<option value="Los Angeles">Los Angeles</option>
|
|
||||||
<option value="New York" selected>New York</option>
|
|
||||||
<option value="Orlando">Orlando</option>
|
|
||||||
<option value="Philadelphia">Philadelphia</option>
|
|
||||||
<option value="Phoenix">Phoenix</option>
|
|
||||||
<option value="San Antonio">San Antonio</option>
|
|
||||||
<option value="San Diego">San Diego</option>
|
|
||||||
<option value="San Jose">San Jose</option>
|
|
||||||
</select>
|
|
||||||
<div class="invalid-feedback">Please select your city!</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-4">
|
|
||||||
<div class="position-relative">
|
|
||||||
<label for="psa-zip" class="form-label">ZIP code</label>
|
|
||||||
<input type="text" class="form-control" id="psa-zip" value="11741" required>
|
|
||||||
<div class="invalid-feedback">Please enter your ZIP code!</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-sm-8">
|
|
||||||
<div class="position-relative">
|
|
||||||
<label for="psa-address" class="form-label">Address</label>
|
|
||||||
<input type="text" class="form-control" id="psa-address"
|
|
||||||
value="396 Lillian Bolavandy, Holbrook" required>
|
|
||||||
<div class="invalid-feedback">Please enter your address!</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-12">
|
|
||||||
<div class="form-check mb-0">
|
|
||||||
<input type="checkbox" class="form-check-input" id="set-primary-1" checked>
|
|
||||||
<label for="set-primary-1" class="form-check-label">Set as primary
|
|
||||||
address</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-12">
|
|
||||||
<div class="d-flex gap-3 pt-2 pt-sm-0">
|
|
||||||
<button type="submit" class="btn btn-primary">Save changes</button>
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-toggle="collapse"
|
|
||||||
data-bs-target=".primary-address" aria-expanded="true"
|
|
||||||
aria-controls="primaryAddressPreview primaryAddressEdit">Close</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
</div>
|
||||||
|
@endforeach
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- Add address button -->
|
||||||
|
<div class="nav pt-4">
|
||||||
|
<a class="nav-link animate-underline fs-base px-0" href="#newAddressModal" data-bs-toggle="modal">
|
||||||
|
<i class="ci-plus fs-lg ms-n1 me-2"></i>
|
||||||
|
<span class="animate-target">{{ __('addresses.add_address') }}</span>
|
||||||
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Alternative shipping address -->
|
<!-- New Address Modal -->
|
||||||
<div class="border-bottom py-4">
|
<div class="modal fade" id="newAddressModal" tabindex="-1" aria-labelledby="newAddressModalLabel" aria-hidden="true">
|
||||||
<div class="nav flex-nowrap align-items-center justify-content-between pb-1 mb-3">
|
<div class="modal-dialog modal-lg">
|
||||||
<div class="d-flex align-items-center gap-3 me-4">
|
<div class="modal-content">
|
||||||
<h2 class="h6 mb-0">Alternative shipping address</h2>
|
<div class="modal-header">
|
||||||
</div>
|
<h5 class="modal-title" id="newAddressModalLabel">{{ __('addresses.add_address') }}</h5>
|
||||||
<a class="nav-link hiding-collapse-toggle text-decoration-underline p-0 collapsed"
|
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
|
||||||
href=".alternative-address" data-bs-toggle="collapse" aria-expanded="false"
|
|
||||||
aria-controls="alternativeAddressPreview alternativeAddressEdit">Edit</a>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="collapse alternative-address show" id="alternativeAddressPreview">
|
<div class="modal-body">
|
||||||
<ul class="list-unstyled fs-sm m-0">
|
|
||||||
<li>Florida 32806, USA</li>
|
|
||||||
<li>514 S. Magnolia St., Orlando</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div class="collapse alternative-address" id="alternativeAddressEdit">
|
|
||||||
<form class="row g-3 g-sm-4 needs-validation" novalidate>
|
<form class="row g-3 g-sm-4 needs-validation" novalidate>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<div class="position-relative">
|
<div class="position-relative">
|
||||||
<label class="form-label">Country</label>
|
<label class="form-label">{{ __('addresses.country') }}</label>
|
||||||
<select class="form-select" data-select='{"searchEnabled": true}'
|
<select class="form-select" data-select='{"searchEnabled": true}'
|
||||||
aria-label="Select country" required>
|
aria-label="Select country" required>
|
||||||
<option value="">Select country...</option>
|
<option value="">{{ __('addresses.select_country') }}</option>
|
||||||
<optgroup label="Africa">
|
<optgroup label="{{ __('addresses.regions.africa') }}">
|
||||||
<option value="Nigeria">Nigeria</option>
|
<option value="Nigeria">Nigeria</option>
|
||||||
<option value="South Africa">South Africa</option>
|
<option value="South Africa">South Africa</option>
|
||||||
<option value="Kenya">Kenya</option>
|
<option value="Kenya">Kenya</option>
|
||||||
<option value="Egypt">Egypt</option>
|
<option value="Egypt">Egypt</option>
|
||||||
<option value="Ethiopia">Ethiopia</option>
|
<option value="Ethiopia">Ethiopia</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
<optgroup label="Asia">
|
<optgroup label="{{ __('addresses.regions.asia') }}">
|
||||||
<option value="China">China</option>
|
<option value="China">China</option>
|
||||||
<option value="India">India</option>
|
<option value="India">India</option>
|
||||||
<option value="Japan">Japan</option>
|
<option value="Japan">Japan</option>
|
||||||
<option value="South Korea">South Korea</option>
|
<option value="South Korea">South Korea</option>
|
||||||
<option value="Saudi Arabia">Saudi Arabia</option>
|
<option value="Saudi Arabia">Saudi Arabia</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
<optgroup label="Europe">
|
<optgroup label="{{ __('addresses.regions.europe') }}">
|
||||||
<option value="Germany">Germany</option>
|
<option value="Germany">Germany</option>
|
||||||
<option value="France">France</option>
|
<option value="France">France</option>
|
||||||
<option value="United Kingdom">United Kingdom</option>
|
<option value="United Kingdom">United Kingdom</option>
|
||||||
<option value="Italy">Italy</option>
|
<option value="Italy">Italy</option>
|
||||||
<option value="Spain">Spain</option>
|
<option value="Spain">Spain</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
<optgroup label="North America">
|
<optgroup label="{{ __('addresses.regions.north_america') }}">
|
||||||
<option value="United States" selected>United States</option>
|
<option value="United States">United States</option>
|
||||||
<option value="Canada">Canada</option>
|
<option value="Canada">Canada</option>
|
||||||
<option value="Mexico">Mexico</option>
|
<option value="Mexico">Mexico</option>
|
||||||
<option value="Jamaica">Jamaica</option>
|
<option value="Jamaica">Jamaica</option>
|
||||||
<option value="Costa Rica">Costa Rica</option>
|
<option value="Costa Rica">Costa Rica</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
<optgroup label="South America">
|
<optgroup label="{{ __('addresses.regions.south_america') }}">
|
||||||
<option value="Brazil">Brazil</option>
|
<option value="Brazil">Brazil</option>
|
||||||
<option value="Argentina">Argentina</option>
|
<option value="Argentina">Argentina</option>
|
||||||
<option value="Colombia">Colombia</option>
|
<option value="Colombia">Colombia</option>
|
||||||
<option value="Chile">Chile</option>
|
<option value="Chile">Chile</option>
|
||||||
<option value="Peru">Peru</option>
|
<option value="Peru">Peru</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
<optgroup label="Oceania">
|
<optgroup label="{{ __('addresses.regions.oceania') }}">
|
||||||
<option value="Australia">Australia</option>
|
<option value="Australia">Australia</option>
|
||||||
<option value="New Zealand">New Zealand</option>
|
<option value="New Zealand">New Zealand</option>
|
||||||
<option value="Papua New Guinea">Papua New Guinea</option>
|
<option value="Papua New Guinea">Papua New Guinea</option>
|
||||||
|
|
@ -205,15 +184,15 @@
|
||||||
<option value="Solomon Islands">Solomon Islands</option>
|
<option value="Solomon Islands">Solomon Islands</option>
|
||||||
</optgroup>
|
</optgroup>
|
||||||
</select>
|
</select>
|
||||||
<div class="invalid-feedback">Please select your country!</div>
|
<div class="invalid-feedback">{{ __('addresses.please_select_country') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-6">
|
<div class="col-sm-6">
|
||||||
<div class="position-relative">
|
<div class="position-relative">
|
||||||
<label class="form-label">City</label>
|
<label class="form-label">{{ __('addresses.city') }}</label>
|
||||||
<select class="form-select" data-select='{"searchEnabled": true}'
|
<select class="form-select" data-select='{"searchEnabled": true}'
|
||||||
aria-label="Select city" required>
|
aria-label="Select city" required>
|
||||||
<option value="">Select city...</option>
|
<option value="">{{ __('addresses.select_city') }}</option>
|
||||||
<option value="Austin">Austin</option>
|
<option value="Austin">Austin</option>
|
||||||
<option value="Charlotte">Charlotte</option>
|
<option value="Charlotte">Charlotte</option>
|
||||||
<option value="Chicago">Chicago</option>
|
<option value="Chicago">Chicago</option>
|
||||||
|
|
@ -223,61 +202,353 @@
|
||||||
<option value="Jacksonville">Jacksonville</option>
|
<option value="Jacksonville">Jacksonville</option>
|
||||||
<option value="Los Angeles">Los Angeles</option>
|
<option value="Los Angeles">Los Angeles</option>
|
||||||
<option value="New York">New York</option>
|
<option value="New York">New York</option>
|
||||||
<option value="Orlando" selected>Orlando</option>
|
<option value="Orlando">Orlando</option>
|
||||||
<option value="Philadelphia">Philadelphia</option>
|
<option value="Philadelphia">Philadelphia</option>
|
||||||
<option value="Phoenix">Phoenix</option>
|
<option value="Phoenix">Phoenix</option>
|
||||||
<option value="San Antonio">San Antonio</option>
|
<option value="San Antonio">San Antonio</option>
|
||||||
<option value="San Diego">San Diego</option>
|
<option value="San Diego">San Diego</option>
|
||||||
<option value="San Jose">San Jose</option>
|
<option value="San Jose">San Jose</option>
|
||||||
</select>
|
</select>
|
||||||
<div class="invalid-feedback">Please select your city!</div>
|
<div class="invalid-feedback">{{ __('addresses.please_select_city') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-4">
|
<div class="col-sm-4">
|
||||||
<div class="position-relative">
|
<div class="position-relative">
|
||||||
<label for="asa-zip" class="form-label">ZIP code</label>
|
<label for="new-zip" class="form-label">{{ __('addresses.zip_code') }}</label>
|
||||||
<input type="text" class="form-control" id="asa-zip" value="32806" required>
|
<input type="text" class="form-control" id="new-zip" required>
|
||||||
<div class="invalid-feedback">Please enter your ZIP code!</div>
|
<div class="invalid-feedback">{{ __('addresses.please_enter_zip_code') }}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-sm-8">
|
<div class="col-sm-8">
|
||||||
<div class="position-relative">
|
<div class="position-relative">
|
||||||
<label for="asa-address" class="form-label">Address</label>
|
<label for="new-address" class="form-label">{{ __('addresses.address') }}</label>
|
||||||
<input type="text" class="form-control" id="asa-address" value="514 S. Magnolia St."
|
<input type="text" class="form-control" id="new-address" required>
|
||||||
required>
|
<div class="invalid-feedback">{{ __('addresses.please_enter_address') }}</div>
|
||||||
<div class="invalid-feedback">Please enter your address!</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<div class="form-check mb-0">
|
<div class="form-check mb-0">
|
||||||
<input type="checkbox" class="form-check-input" id="set-primary-2">
|
<input type="checkbox" class="form-check-input" id="set-primary-new">
|
||||||
<label for="set-primary-2" class="form-check-label">Set as primary
|
<label for="set-primary-new"
|
||||||
address</label>
|
class="form-check-label">{{ __('addresses.set_as_primary_address') }}</label>
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="col-12">
|
|
||||||
<div class="d-flex gap-3 pt-2 pt-sm-0">
|
|
||||||
<button type="submit" class="btn btn-primary">Save changes</button>
|
|
||||||
<button type="button" class="btn btn-secondary" data-bs-toggle="collapse"
|
|
||||||
data-bs-target=".alternative-address" aria-expanded="true"
|
|
||||||
aria-controls="alternativeAddressPreview alternativeAddressEdit">Close</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-secondary"
|
||||||
<!-- Add address button -->
|
data-bs-dismiss="modal">{{ __('addresses.close') }}</button>
|
||||||
<div class="nav pt-4">
|
<button type="submit" class="btn btn-primary">{{ __('addresses.save_changes') }}</button>
|
||||||
<a class="nav-link animate-underline fs-base px-0" href="#newAddressModal" data-bs-toggle="modal">
|
</div>
|
||||||
<i class="ci-plus fs-lg ms-n1 me-2"></i>
|
|
||||||
<span class="animate-target">Add address</span>
|
|
||||||
</a>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@endsection
|
@endsection
|
||||||
|
|
||||||
@section('scripts')
|
@section('scripts')
|
||||||
|
<script>
|
||||||
|
document.addEventListener('DOMContentLoaded', function() {
|
||||||
|
// Add click event listener to edit buttons
|
||||||
|
document.addEventListener('click', function(e) {
|
||||||
|
// Check if clicked element is an edit button
|
||||||
|
if (e.target.closest('.primaryAddressEditButton')) {
|
||||||
|
// Find the button element to get its data attribute
|
||||||
|
const button = e.target.closest('.primaryAddressEditButton');
|
||||||
|
console.log('Button clicked:', button);
|
||||||
|
|
||||||
|
// Get address ID from data attribute
|
||||||
|
const addressId = button.getAttribute('data-address-id');
|
||||||
|
console.log('Address ID:', addressId);
|
||||||
|
|
||||||
|
if (addressId) {
|
||||||
|
loadProvincesForAddress(addressId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function loadProvincesForAddress(addressId) {
|
||||||
|
console.log('Loading provinces for address ID:', addressId);
|
||||||
|
const provinceSelect = document.querySelector(`.province-select[data-address-id="${addressId}"]`);
|
||||||
|
if (!provinceSelect) {
|
||||||
|
console.log('Province select not found for address ID:', addressId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const currentProvinceId = '{{ $address->province_id }}';
|
||||||
|
const currentCityId = '{{ $address->city_id }}';
|
||||||
|
const currentDistrictId = '{{ $address->district_id }}';
|
||||||
|
const currentVillageId = '{{ $address->subdistrict_id }}';
|
||||||
|
|
||||||
|
// Load provinces via AJAX
|
||||||
|
fetch('/addresses/provinces')
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
if (window.Choices) {
|
||||||
|
// Destroy existing instance if any
|
||||||
|
if (provinceSelect.choices) {
|
||||||
|
provinceSelect.choices.destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Clear and set options
|
||||||
|
provinceSelect.innerHTML =
|
||||||
|
'<option value="">{{ __('addresses.select_province') }}</option>';
|
||||||
|
|
||||||
|
data.data.forEach(province => {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = province.id;
|
||||||
|
option.textContent = province.name;
|
||||||
|
|
||||||
|
// Select current province if it matches
|
||||||
|
if (province.id == currentProvinceId) {
|
||||||
|
option.selected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
provinceSelect.appendChild(option);
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log(provinceSelect);
|
||||||
|
|
||||||
|
// Initialize Choices.js
|
||||||
|
if (window.Choices) {
|
||||||
|
// Destroy existing instance if any
|
||||||
|
if (provinceSelect.choices) {
|
||||||
|
provinceSelect.choices.destroy();
|
||||||
|
}
|
||||||
|
// Initialize new Choices instance
|
||||||
|
provinceSelect.choices = new window.Choices(provinceSelect, {
|
||||||
|
searchEnabled: true,
|
||||||
|
itemSelectText: 'Select an option',
|
||||||
|
noResultsText: 'No results found',
|
||||||
|
shouldSort: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load cities if province is selected
|
||||||
|
if (currentProvinceId) {
|
||||||
|
loadCitiesForAddress(addressId, currentProvinceId, currentCityId, currentDistrictId,
|
||||||
|
currentVillageId);
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => console.log('Error loading provinces:', error));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add change event listener to province selects
|
||||||
|
document.addEventListener('change', function(e) {
|
||||||
|
if (e.target.classList.contains('province-select')) {
|
||||||
|
const addressId = e.target.dataset.addressId;
|
||||||
|
const provinceId = e.target.value;
|
||||||
|
|
||||||
|
// Clear district and village selects
|
||||||
|
const citySelect = document.querySelector(
|
||||||
|
`.city-select[data-address-id="${addressId}"]`);
|
||||||
|
const districtSelect = document.querySelector(
|
||||||
|
`.district-select[data-address-id="${addressId}"]`);
|
||||||
|
const villageSelect = document.querySelector(
|
||||||
|
`.village-select[data-address-id="${addressId}"]`);
|
||||||
|
|
||||||
|
if (citySelect) {
|
||||||
|
citySelect.innerHTML =
|
||||||
|
'<option value="">{{ __('addresses.select_city') }}</option>';
|
||||||
|
}
|
||||||
|
if (districtSelect) {
|
||||||
|
districtSelect.innerHTML =
|
||||||
|
'<option value="">{{ __('addresses.select_district') }}</option>';
|
||||||
|
}
|
||||||
|
if (villageSelect) {
|
||||||
|
villageSelect.innerHTML =
|
||||||
|
'<option value="">{{ __('addresses.select_village') }}</option>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load cities if province is selected
|
||||||
|
if (provinceId) {
|
||||||
|
loadCitiesForAddress(addressId, provinceId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e.target.classList.contains('city-select')) {
|
||||||
|
const addressId = e.target.dataset.addressId;
|
||||||
|
const cityId = e.target.value;
|
||||||
|
|
||||||
|
// Clear district and village selects
|
||||||
|
const districtSelect = document.querySelector(
|
||||||
|
`.district-select[data-address-id="${addressId}"]`);
|
||||||
|
const villageSelect = document.querySelector(
|
||||||
|
`.village-select[data-address-id="${addressId}"]`);
|
||||||
|
|
||||||
|
if (districtSelect) {
|
||||||
|
districtSelect.innerHTML =
|
||||||
|
'<option value="">{{ __('addresses.select_district') }}</option>';
|
||||||
|
}
|
||||||
|
if (villageSelect) {
|
||||||
|
villageSelect.innerHTML =
|
||||||
|
'<option value="">{{ __('addresses.select_village') }}</option>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load districts if city is selected
|
||||||
|
if (cityId) {
|
||||||
|
loadDistrictsForAddress(addressId, cityId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Add change event listener to district selects
|
||||||
|
document.addEventListener('change', function(e) {
|
||||||
|
if (e.target.classList.contains('district-select')) {
|
||||||
|
const addressId = e.target.dataset.addressId;
|
||||||
|
const districtId = e.target.value;
|
||||||
|
|
||||||
|
// Clear village select
|
||||||
|
const villageSelect = document.querySelector(
|
||||||
|
`.village-select[data-address-id="${addressId}"]`);
|
||||||
|
if (villageSelect) {
|
||||||
|
villageSelect.innerHTML =
|
||||||
|
'<option value="">{{ __('addresses.select_village') }}</option>';
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load villages if district is selected
|
||||||
|
if (districtId) {
|
||||||
|
loadVillages(addressId, districtId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function loadCitiesForAddress(addressId, provinceId, currentCityId = null, currentDistrictId = null,
|
||||||
|
currentVillageId = null) {
|
||||||
|
fetch(`/addresses/cities/${provinceId}`)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
const citySelect = document.querySelector(
|
||||||
|
`.city-select[data-address-id="${addressId}"]`);
|
||||||
|
if (citySelect) {
|
||||||
|
// Clear and set options
|
||||||
|
citySelect.innerHTML =
|
||||||
|
'<option value="">{{ __('addresses.select_city') }}</option>';
|
||||||
|
|
||||||
|
data.data.forEach(city => {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = city.id;
|
||||||
|
option.textContent = city.name;
|
||||||
|
|
||||||
|
if (currentCityId && city.id == currentCityId) {
|
||||||
|
option.selected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
citySelect.appendChild(option);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initialize Choices.js
|
||||||
|
if (window.Choices) {
|
||||||
|
// Destroy existing instance if any
|
||||||
|
if (citySelect.choices) {
|
||||||
|
citySelect.choices.destroy();
|
||||||
|
}
|
||||||
|
// Initialize new Choices instance
|
||||||
|
citySelect.choices = new window.Choices(citySelect, {
|
||||||
|
searchEnabled: true,
|
||||||
|
itemSelectText: 'Select an option',
|
||||||
|
noResultsText: 'No results found',
|
||||||
|
shouldSort: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load districts if city is selected
|
||||||
|
if (currentCityId) {
|
||||||
|
loadDistrictsForAddress(addressId, currentCityId, currentDistrictId,
|
||||||
|
currentVillageId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => console.log('Error loading cities:', error));
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadDistrictsForAddress(addressId, cityId, currentDistrictId = null, currentVillageId = null) {
|
||||||
|
fetch(`/addresses/districts/${cityId}`)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
const districtSelect = document.querySelector(
|
||||||
|
`.district-select[data-address-id="${addressId}"]`);
|
||||||
|
if (districtSelect) {
|
||||||
|
// Clear and set options
|
||||||
|
districtSelect.innerHTML =
|
||||||
|
'<option value="">{{ __('addresses.select_district') }}</option>';
|
||||||
|
|
||||||
|
data.data.forEach(district => {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = district.id;
|
||||||
|
option.textContent = district.name;
|
||||||
|
|
||||||
|
if (currentDistrictId && district.id == currentDistrictId) {
|
||||||
|
option.selected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
districtSelect.appendChild(option);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initialize Choices.js
|
||||||
|
if (window.Choices) {
|
||||||
|
// Destroy existing instance if any
|
||||||
|
if (districtSelect.choices) {
|
||||||
|
districtSelect.choices.destroy();
|
||||||
|
}
|
||||||
|
// Initialize new Choices instance
|
||||||
|
districtSelect.choices = new window.Choices(districtSelect, {
|
||||||
|
searchEnabled: true,
|
||||||
|
itemSelectText: 'Select an option',
|
||||||
|
noResultsText: 'No results found',
|
||||||
|
shouldSort: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Load villages if district is selected
|
||||||
|
if (currentDistrictId) {
|
||||||
|
loadVillages(addressId, currentDistrictId, currentVillageId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => console.log('Error loading districts:', error));
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadVillages(addressId, districtId, currentVillageId = null) {
|
||||||
|
fetch(`/addresses/villages/${districtId}`)
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
const villageSelect = document.querySelector(
|
||||||
|
`.village-select[data-address-id="${addressId}"]`);
|
||||||
|
if (villageSelect) {
|
||||||
|
// Clear and set options
|
||||||
|
villageSelect.innerHTML =
|
||||||
|
'<option value="">{{ __('addresses.select_village') }}</option>';
|
||||||
|
|
||||||
|
data.data.forEach(village => {
|
||||||
|
const option = document.createElement('option');
|
||||||
|
option.value = village.id;
|
||||||
|
option.textContent = village.name;
|
||||||
|
|
||||||
|
if (currentVillageId && village.id == currentVillageId) {
|
||||||
|
option.selected = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
villageSelect.appendChild(option);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Initialize Choices.js
|
||||||
|
if (window.Choices) {
|
||||||
|
// Destroy existing instance if any
|
||||||
|
if (villageSelect.choices) {
|
||||||
|
villageSelect.choices.destroy();
|
||||||
|
}
|
||||||
|
// Initialize new Choices instance
|
||||||
|
villageSelect.choices = new window.Choices(villageSelect, {
|
||||||
|
searchEnabled: true,
|
||||||
|
itemSelectText: 'Select an option',
|
||||||
|
noResultsText: 'No results found',
|
||||||
|
shouldSort: false
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.catch(error => console.log('Error loading villages:', error));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@endsection
|
@endsection
|
||||||
|
|
|
||||||
|
|
@ -68,12 +68,12 @@
|
||||||
<h6 class="pt-4 ps-2 ms-1">{{ __('account_sidebar.manage_account') }}</h6>
|
<h6 class="pt-4 ps-2 ms-1">{{ __('account_sidebar.manage_account') }}</h6>
|
||||||
<nav class="list-group list-group-borderless">
|
<nav class="list-group list-group-borderless">
|
||||||
<a class="list-group-item list-group-item-action d-flex align-items-center"
|
<a class="list-group-item list-group-item-action d-flex align-items-center"
|
||||||
href="{{ route('second', ['account', 'info']) }}">
|
href="{{ route('profile') }}">
|
||||||
<i class="ci-user fs-base opacity-75 me-2"></i>
|
<i class="ci-user fs-base opacity-75 me-2"></i>
|
||||||
{{ __('account_sidebar.personal_info') }}
|
{{ __('account_sidebar.personal_info') }}
|
||||||
</a>
|
</a>
|
||||||
<a class="list-group-item list-group-item-action d-flex align-items-center"
|
<a class="list-group-item list-group-item-action d-flex align-items-center"
|
||||||
href="{{ route('second', ['account', 'addresses']) }}">
|
href="{{ route('addresses') }}">
|
||||||
<i class="ci-map-pin fs-base opacity-75 me-2"></i>
|
<i class="ci-map-pin fs-base opacity-75 me-2"></i>
|
||||||
{{ __('account_sidebar.addresses') }}
|
{{ __('account_sidebar.addresses') }}
|
||||||
</a>
|
</a>
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
|
|
||||||
|
use App\Http\Controllers\Auth\AddressController;
|
||||||
use App\Http\Controllers\Auth\LoginEmailController;
|
use App\Http\Controllers\Auth\LoginEmailController;
|
||||||
use App\Http\Controllers\Auth\LoginWaController;
|
use App\Http\Controllers\Auth\LoginWaController;
|
||||||
use App\Http\Controllers\Auth\RegisterController;
|
use App\Http\Controllers\Auth\RegisterController;
|
||||||
|
|
@ -71,3 +72,10 @@ Route::group(['prefix' => '/login/google'], function () {
|
||||||
Route::get('/profile', [ProfileController::class, 'index'])->name('profile');
|
Route::get('/profile', [ProfileController::class, 'index'])->name('profile');
|
||||||
Route::post('/profile', [ProfileController::class, 'update'])->name('profile.update');
|
Route::post('/profile', [ProfileController::class, 'update'])->name('profile.update');
|
||||||
Route::put('/profile/password', [ProfileController::class, 'updatePassword'])->name('profile.password.update');
|
Route::put('/profile/password', [ProfileController::class, 'updatePassword'])->name('profile.password.update');
|
||||||
|
|
||||||
|
|
||||||
|
Route::get('/addresses', [AddressController::class, 'index'])->name('addresses');
|
||||||
|
Route::get('/addresses/provinces', [AddressController::class, 'provinces'])->name('addresses.provinces');
|
||||||
|
Route::get('/addresses/cities/{provinceId}', [AddressController::class, 'cities'])->name('addresses.cities');
|
||||||
|
Route::get('/addresses/districts/{provinceId}', [AddressController::class, 'districts'])->name('addresses.districts');
|
||||||
|
Route::get('/addresses/villages/{districtId}', [AddressController::class, 'villages'])->name('addresses.villages');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue