inital commit
This commit is contained in:
parent
64e0e65c71
commit
17c9d487b2
74
app/Http/Controllers/Admin/IndexController.php
Normal file
74
app/Http/Controllers/Admin/IndexController.php
Normal file
@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\User;
|
||||
use Auth;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class IndexController extends Controller
|
||||
{
|
||||
|
||||
public function index()
|
||||
{
|
||||
return view('admin.dashboard.index');
|
||||
}
|
||||
|
||||
public function profile()
|
||||
{
|
||||
$user = Auth::user();
|
||||
// 從環境變數獲取預設密碼
|
||||
$defaultPassword = env('DEFAULT_PASSWORD');
|
||||
|
||||
// 判斷用戶密碼是否為預設密碼
|
||||
$isDefaultPassword = Hash::check($defaultPassword, $user->password);
|
||||
|
||||
// 傳送資料到前端
|
||||
$data = $user->toArray();
|
||||
|
||||
if ($isDefaultPassword) {
|
||||
$data['password'] = $defaultPassword;
|
||||
} else {
|
||||
$data['password'] = null;
|
||||
}
|
||||
|
||||
return view('admin.dashboard.profile', ['data' => (Object) $data]);
|
||||
}
|
||||
public function profileUpdate(Request $request)
|
||||
{
|
||||
|
||||
$user = Auth::user();
|
||||
|
||||
$user->email = $request->email;
|
||||
if ($request->password != null) {
|
||||
$user->password = Hash::make($request->password);
|
||||
}
|
||||
$user->phone = $request->phone;
|
||||
$user->save();
|
||||
|
||||
return response()->json(['status' => 'success', 'message' => '更新成功', 'data' => $user]);
|
||||
|
||||
}
|
||||
|
||||
public function pageProfile()
|
||||
{
|
||||
$user = Auth::user();
|
||||
// 從環境變數獲取預設密碼
|
||||
$defaultPassword = env('DEFAULT_PASSWORD');
|
||||
|
||||
// 判斷用戶密碼是否為預設密碼
|
||||
$isDefaultPassword = Hash::check($defaultPassword, $user->password);
|
||||
|
||||
// 傳送資料到前端
|
||||
$data = $user->toArray();
|
||||
|
||||
if ($isDefaultPassword) {
|
||||
$data['password'] = $defaultPassword;
|
||||
} else {
|
||||
$data['password'] = null;
|
||||
}
|
||||
return view('admin.profile.index', ['data' => (Object) $data]);
|
||||
}
|
||||
}
|
||||
@ -1,11 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
//
|
||||
}
|
||||
17
app/Http/Controllers/Admin/MemberController.php
Normal file
17
app/Http/Controllers/Admin/MemberController.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Member;
|
||||
|
||||
class MemberController extends Controller
|
||||
{
|
||||
|
||||
public function index()
|
||||
{
|
||||
$data = Member::paginate(20);
|
||||
|
||||
return view('admin.member.index', ['data' => $data]);
|
||||
}
|
||||
}
|
||||
63
app/Http/Controllers/Admin/RegisterController.php
Normal file
63
app/Http/Controllers/Admin/RegisterController.php
Normal file
@ -0,0 +1,63 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
|
||||
public function index()
|
||||
{
|
||||
return view('admin.dashboard.auth-register');
|
||||
}
|
||||
|
||||
public function register(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'name' => 'required',
|
||||
'email' => 'required|email|unique:users',
|
||||
'password' => 'required|min:6',
|
||||
'phone' => 'required',
|
||||
]);
|
||||
|
||||
$user = User::create([
|
||||
'name' => $request->name,
|
||||
'email' => $request->email,
|
||||
'password' => bcrypt($request->password),
|
||||
'phone' => $request->phone,
|
||||
]);
|
||||
|
||||
return view('admin.dashboard.auth-register');
|
||||
}
|
||||
|
||||
public function registerCreate(Request $request)
|
||||
{
|
||||
$request->validate([
|
||||
'name' => 'required',
|
||||
'email' => 'required|email|unique:users',
|
||||
'password' => 'required|min:6',
|
||||
'phone' => 'required',
|
||||
]);
|
||||
|
||||
$check = User::where('email', $request->email)->first();
|
||||
|
||||
if ($check) {
|
||||
return response()->json(['status' => 'error', 'message' => '此帳號已被註冊']);
|
||||
}
|
||||
|
||||
$user = User::create([
|
||||
'name' => $request->name,
|
||||
'email' => $request->email,
|
||||
'password' => bcrypt($request->password),
|
||||
'phone' => $request->phone,
|
||||
'line_id' => null,
|
||||
'can_login' => false,
|
||||
]);
|
||||
|
||||
return response()->json(['status' => 'success', 'message' => '註冊成功']);
|
||||
}
|
||||
|
||||
}
|
||||
65
app/Http/Controllers/Admin/SettingController.php
Normal file
65
app/Http/Controllers/Admin/SettingController.php
Normal file
@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\Admin;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Imports\PromoImport;
|
||||
use App\Models\Promocode;
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Http\Request;
|
||||
use Log;
|
||||
use Maatwebsite\Excel\Facades\Excel;
|
||||
|
||||
class SettingController extends Controller
|
||||
{
|
||||
|
||||
public function promoCode(Request $request)
|
||||
{
|
||||
$start = Carbon::now()->startOfMonth();
|
||||
$end = Carbon::now()->endOfMonth();
|
||||
|
||||
$result = Promocode::whereBetween('created_at', [$start, $end])->paginate(100);
|
||||
|
||||
return view('admin.setting.promocode', ['data' => $result]);
|
||||
}
|
||||
/**
|
||||
* @param Request $request ->file
|
||||
*
|
||||
* @return [type][string ]
|
||||
*/
|
||||
public function promoCodeCreate(Request $request)
|
||||
{
|
||||
// 驗證文件
|
||||
$request->validate([
|
||||
'file' => 'required|mimes:xlsx,xls,csv|max:2048',
|
||||
]);
|
||||
|
||||
if ($request->hasFile('file')) {
|
||||
$file = $request->file('file');
|
||||
Log::info('File uploaded: ', [
|
||||
'name' => $file->getClientOriginalName(),
|
||||
'size' => $file->getSize(),
|
||||
'mime' => $file->getMimeType(),
|
||||
'path' => $file->getRealPath(),
|
||||
]);
|
||||
|
||||
// 获取整个文件的内容并打印出来
|
||||
$data = Excel::toArray([], $file);
|
||||
// Log::info('Excel file content: ', $data); // 打印整个数据数组
|
||||
|
||||
// echo '<pre>';
|
||||
// print_r($data);
|
||||
// exit;
|
||||
|
||||
}
|
||||
|
||||
// 讀取並導入 Excel 文件
|
||||
try {
|
||||
Excel::import(new PromoImport, $file);
|
||||
return back()->with('success', '促銷代碼已成功導入!');
|
||||
} catch (\Exception $e) {
|
||||
return back()->with('error', '導入失敗: ' . $e->getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
263
app/Http/Controllers/EmailController.php
Normal file
263
app/Http/Controllers/EmailController.php
Normal file
@ -0,0 +1,263 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use Illuminate\Http\Request;
|
||||
use App\Models\EmailVerifications;
|
||||
use App\Models\Member;
|
||||
use Auth;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
use Exception;
|
||||
use Mail;
|
||||
use Str;
|
||||
class EmailController extends Controller
|
||||
{
|
||||
/**
|
||||
* 驗證電子郵件並更新會員狀態
|
||||
* @param Request $request
|
||||
* @return \Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public $token;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
|
||||
}
|
||||
public function index(Request $request)
|
||||
{
|
||||
Log::info('Email verification request received:', $request->all());
|
||||
|
||||
// 獲取當前登入的會員(若存在)
|
||||
$auth = Auth::guard('member')->user();
|
||||
|
||||
// 驗證請求中是否包含 token
|
||||
$validatedData = $request->validate([
|
||||
'token' => 'required|string',
|
||||
]);
|
||||
|
||||
// 查詢對應的驗證記錄
|
||||
$check = EmailVerifications::where('token', $validatedData['token'])->first();
|
||||
|
||||
if (!$check) {
|
||||
Log::warning('Invalid token provided for email verification:', ['token' => $validatedData['token']]);
|
||||
return response()->json(['status' => 'error', 'msg' => '無效的驗證連結或連結已過期'], 400);
|
||||
}
|
||||
|
||||
Log::info(message: 'Email verification record found:', context: $check->toArray());
|
||||
|
||||
// 查詢對應的會員
|
||||
$member = Member::where('email', $check->email)->orderBy('created_at', 'asc')->first();
|
||||
|
||||
|
||||
|
||||
|
||||
// 若當前登入用戶存在 line_id,則使用當前用戶更新
|
||||
if ($auth && isset($auth->line_id)) {
|
||||
$line_id = $auth->line_id;
|
||||
} else {
|
||||
$line_id = $member->line_id;
|
||||
}
|
||||
|
||||
if ($auth && isset($auth->avatar)) {
|
||||
$avatar = $auth->avatar;
|
||||
} else {
|
||||
$avatar = $member->avatar;
|
||||
}
|
||||
|
||||
|
||||
// 更新會員的 Email 與驗證時間
|
||||
|
||||
Log::info('Member email verification updated successfully:', $member->toArray());
|
||||
|
||||
// 如果當前登入用戶與驗證的會員不同,登出當前用戶並重新登入
|
||||
if ($auth && $auth->id != $member->id) {
|
||||
// 在登出之前執行需要刪除或處理的操作
|
||||
$needdeletaccount = Auth::guard('member')->user();
|
||||
|
||||
// 確保在登出前刪除帳號資料或執行其他操作
|
||||
if ($needdeletaccount) {
|
||||
$needdeletaccount->delete(); // 這會刪除登入用戶的資料
|
||||
$member->email_verified_at = now();
|
||||
$member->line_id = $line_id;
|
||||
$member->avatar = $avatar;
|
||||
Log::info('Deleted account after logout:', ['user_id' => $needdeletaccount->id]);
|
||||
}
|
||||
|
||||
$member->save();
|
||||
|
||||
// 登出並重新登入
|
||||
Auth::logout();
|
||||
Auth::guard('member')->loginUsingId($member->id);
|
||||
Log::info('Logged out previous user and logged in verified user:', ['user_id' => $member->id]);
|
||||
}
|
||||
|
||||
|
||||
// 刪除驗證記錄以防重複使用
|
||||
$check->delete();
|
||||
Log::info('Verification token record deleted successfully:', ['token' => $validatedData['token']]);
|
||||
|
||||
// return response()->json(['status' => 'success', 'msg' => '電子郵件驗證成功']);
|
||||
|
||||
return redirect()->route('member.index');
|
||||
|
||||
|
||||
|
||||
}
|
||||
public function sendemail(Request $request)
|
||||
{
|
||||
\Log::info('got send mail', ['function' => 'sendemail']);
|
||||
|
||||
// 驗證請求數據
|
||||
$validatedData = $request->validate([
|
||||
'email' => 'required|email',
|
||||
]);
|
||||
//判斷是否更新token
|
||||
|
||||
$check = EmailVerifications::where('email', $request->email)->first();
|
||||
|
||||
// 生成隨機 token
|
||||
$token = Str::random(32);
|
||||
|
||||
if (!$check) {
|
||||
$check = new EmailVerifications;
|
||||
}
|
||||
|
||||
$check->email = $request->email;
|
||||
$check->token = $token;
|
||||
$check->save();
|
||||
|
||||
\Log::info('Generated token', ['token' => $token]);
|
||||
|
||||
$subject = "卡菲姬系統-驗證email";
|
||||
|
||||
// 使用 route 生成驗證鏈接
|
||||
$verificationLink = route('email.verify', ['token' => $token]);
|
||||
\Log::info('Generated verification link', ['link' => $verificationLink]);
|
||||
|
||||
try {
|
||||
// 郵件內容
|
||||
$message = "您好,\n\n請點擊以下鏈接以驗證您的電子郵件地址:\n\n" . $verificationLink . "\n\n如果您未請求此操作,請忽略此郵件。\n\n感謝您!";
|
||||
|
||||
\Log::info('Preparing to send mail', ['email' => $validatedData['email'], 'subject' => $subject, 'message' => $message]);
|
||||
|
||||
// 發送電子郵件
|
||||
Mail::to($validatedData['email'])->send(new \App\Mail\CustomMail($subject, $message));
|
||||
|
||||
\Log::info('Mail sent successfully');
|
||||
|
||||
return response()->json(['status' => 'success', 'msg' => '郵件發送成功']);
|
||||
} catch (\Exception $e) {
|
||||
\Log::error('Failed to send mail', ['error' => $e->getMessage()]);
|
||||
|
||||
return response()->json(['status' => 'error', 'msg' => '郵件發送失敗,請稍後再試!', 'error' => $e->getMessage()], 500);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of validemail ajax 驗證email 是否註冊過
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return mixed|\Illuminate\Http\JsonResponse
|
||||
*/
|
||||
public function validemail(Request $request)
|
||||
{
|
||||
// 構建郵件內容
|
||||
|
||||
// 驗證輸入的數據
|
||||
$validatedData = $request->validate([
|
||||
'email' => 'required|email',
|
||||
]);
|
||||
|
||||
// 檢查是否已有其他會員使用相同的 email
|
||||
$user = Member::where('email', $validatedData['email'])->first();
|
||||
|
||||
if ($user) {
|
||||
// 查找是否已有驗證記錄
|
||||
$vaild = EmailVerifications::where('email', $validatedData['email'])->first();
|
||||
|
||||
return response()->json([
|
||||
'status' => 'error',
|
||||
'msg' => 'email 以使用 ,是否逕行合併,如果是 請先驗證email',
|
||||
]);
|
||||
}
|
||||
return response()->json([
|
||||
'status' => 'success',
|
||||
|
||||
]);
|
||||
|
||||
}
|
||||
/**
|
||||
* Summary of checkEmail email 寄送 token 點擊後 驗證
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return mixed|\Illuminate\Http\JsonResponse|\Illuminate\Http\RedirectResponse
|
||||
*/
|
||||
public function checkEmail(Request $request)
|
||||
{
|
||||
Log::info('Email verification request received:', $request->all());
|
||||
|
||||
// 獲取當前登入的會員(若存在)
|
||||
$auth = Auth::guard('member')->user();
|
||||
|
||||
// 驗證請求中是否包含 token
|
||||
$validatedData = $request->validate([
|
||||
'token' => 'required|string',
|
||||
]);
|
||||
|
||||
// 查詢對應的驗證記錄
|
||||
$check = EmailVerifications::where('token', $validatedData['token'])->first();
|
||||
|
||||
if (!$check) {
|
||||
Log::warning('Invalid token provided for email verification:', ['token' => $validatedData['token']]);
|
||||
return response()->json(['status' => 'error', 'msg' => '無效的驗證連結或連結已過期'], 400);
|
||||
}
|
||||
|
||||
Log::info(message: 'Email verification record found:', context: $check->toArray());
|
||||
|
||||
// 查詢對應的會員
|
||||
$member = Member::where('email', $check->email)->orderBy('created_at', 'asc')->first();
|
||||
|
||||
|
||||
|
||||
|
||||
// 若當前登入用戶存在 line_id,則使用當前用戶更新
|
||||
if ($auth && isset($auth->line_id)) {
|
||||
$line_id = $auth->line_id;
|
||||
} else {
|
||||
$line_id = $member->line_id;
|
||||
}
|
||||
|
||||
// 更新會員的 Email 與驗證時間
|
||||
|
||||
Log::info('Member email verification updated successfully:', $member->toArray());
|
||||
|
||||
// 如果當前登入用戶與驗證的會員不同,登出當前用戶並重新登入
|
||||
if ($auth && $auth->id != $member->id) {
|
||||
// 在登出之前執行需要刪除或處理的操作
|
||||
$needdeletaccount = Auth::guard('member')->user();
|
||||
|
||||
// 確保在登出前刪除帳號資料或執行其他操作
|
||||
if ($needdeletaccount) {
|
||||
$needdeletaccount->delete(); // 這會刪除登入用戶的資料
|
||||
$member->email_verified_at = now();
|
||||
$member->line_id = $line_id;
|
||||
Log::info('Deleted account after logout:', ['user_id' => $needdeletaccount->id]);
|
||||
}
|
||||
|
||||
$member->save();
|
||||
|
||||
// 登出並重新登入
|
||||
Auth::logout();
|
||||
Auth::guard('member')->loginUsingId($member->id);
|
||||
Log::info('Logged out previous user and logged in verified user:', ['user_id' => $member->id]);
|
||||
}
|
||||
|
||||
|
||||
// 刪除驗證記錄以防重複使用
|
||||
$check->delete();
|
||||
Log::info('Verification token record deleted successfully:', ['token' => $validatedData['token']]);
|
||||
|
||||
// return response()->json(['status' => 'success', 'msg' => '電子郵件驗證成功']);
|
||||
|
||||
return redirect()->route('member.index');
|
||||
|
||||
}
|
||||
}
|
||||
141
app/Http/Controllers/LoginController.php
Normal file
141
app/Http/Controllers/LoginController.php
Normal file
@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Member;
|
||||
use App\Models\User;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Laravel\Socialite\Facades\Socialite;
|
||||
use Log;
|
||||
use session;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
public $redirectTo = '';
|
||||
//
|
||||
public function index(Request $request)
|
||||
{
|
||||
return view('front.login');
|
||||
}
|
||||
|
||||
public function adminIndex(Request $request)
|
||||
{
|
||||
return view('admin.login');
|
||||
}
|
||||
|
||||
/** line 跳轉 由line登入
|
||||
* @return [type]
|
||||
*/
|
||||
public function redirectToProvider(Request $request)
|
||||
{
|
||||
$redirectTo = $request->is('admin/*') ? 'admin' : 'member';
|
||||
session(['redirect_to' => $redirectTo]); // 将值存入 Session
|
||||
return Socialite::driver('line')->redirect();
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of handleProviderCallback
|
||||
* line 登入後查詢
|
||||
* @return void
|
||||
*/
|
||||
public function handleProviderCallback(Request $request)
|
||||
{
|
||||
// 从 Session 获取 $redirectTo
|
||||
$redirectTo = session('redirect_to', 'member');
|
||||
|
||||
$user = Socialite::driver('line')->user();
|
||||
Log::info('line', ['user' => $user]);
|
||||
$lineId = $user->getId();
|
||||
$name = $user->getName();
|
||||
$avatar = $user->getAvatar() ?? '';
|
||||
$email = $user->getEmail() ?? '';
|
||||
|
||||
Log::info('email', [$email]);
|
||||
|
||||
if ($redirectTo == 'admin') {
|
||||
// Admin 登录逻辑
|
||||
$existingUser = $user = User::where('line_id', $lineId)
|
||||
->orWhere('email', $email)
|
||||
->first();
|
||||
|
||||
if ($existingUser) {
|
||||
Auth::guard('web')->login($existingUser);
|
||||
} else {
|
||||
$newUser = User::create([
|
||||
'name' => $name,
|
||||
'line_id' => $lineId,
|
||||
'password' => bcrypt(env('DEFAULT_PASSWORD')),
|
||||
'avatar' => $avatar,
|
||||
'source' => 'cafeg',
|
||||
'email' => $email,
|
||||
]);
|
||||
Auth::guard('web')->login($newUser);
|
||||
}
|
||||
|
||||
$user = Auth::guard('web')->user();
|
||||
return $user->email
|
||||
? redirect()->route('admin.index')
|
||||
: redirect()->route('admin.profile');
|
||||
} else {
|
||||
// Member 登录逻辑
|
||||
$existingUser = Member::where('line_id', $lineId)
|
||||
->orWhere('email', $email)
|
||||
->first();
|
||||
if ($existingUser) {
|
||||
Auth::guard('member')->login($existingUser);
|
||||
} else {
|
||||
$newUser = Member::create([
|
||||
'name' => $name,
|
||||
'line_id' => $lineId,
|
||||
'password' => bcrypt(env('DEFAULT_PASSWORD')),
|
||||
'avatar' => $avatar,
|
||||
'source' => 'cafeg',
|
||||
'email' => $email,
|
||||
]);
|
||||
Auth::guard('member')->login($newUser);
|
||||
}
|
||||
|
||||
$user = Auth::guard('member')->user();
|
||||
return $user->email
|
||||
? redirect()->route('member.index')
|
||||
: redirect()->route('member.profile');
|
||||
}
|
||||
}
|
||||
|
||||
public function adminLogout()
|
||||
{
|
||||
Auth::guard('web')->logout();
|
||||
return redirect()->route('admin.login');
|
||||
}
|
||||
|
||||
public function memberLogout()
|
||||
{
|
||||
Auth::guard('member')->logout();
|
||||
return redirect()->route('front.login.view');
|
||||
}
|
||||
|
||||
public function adminNormalLogin(Request $request)
|
||||
{
|
||||
|
||||
$credentials = $request->only('email', 'password');
|
||||
|
||||
if (Auth::guard('web')->attempt($credentials)) {
|
||||
return redirect()->route('admin.index');
|
||||
}
|
||||
return redirect()->route('admin.login');
|
||||
}
|
||||
|
||||
public function memberNormalLogin(Request $request)
|
||||
{
|
||||
$credentials = $request->only('email', 'password');
|
||||
|
||||
if (Auth::guard('member')->attempt($credentials)) {
|
||||
return redirect()->route('member.index');
|
||||
} else {
|
||||
|
||||
return redirect()->route('front.login.view')->with('error', '帳號密碼錯誤');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,77 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\front;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Member;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Laravel\Socialite\Facades\Socialite;
|
||||
|
||||
class LoginController extends Controller
|
||||
{
|
||||
//
|
||||
public function index(Request $request)
|
||||
{
|
||||
return view('front.login');
|
||||
|
||||
}
|
||||
|
||||
/** line 跳轉 由line登入
|
||||
* @return [type]
|
||||
*/
|
||||
public function redirectToProvider()
|
||||
{
|
||||
return Socialite::driver('line')->redirect();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Summary of handleProviderCallback
|
||||
* line 登入後查詢
|
||||
* @return void
|
||||
*/
|
||||
public function handleProviderCallback()
|
||||
{
|
||||
// 获取 LINE 用户信息
|
||||
$user = Socialite::driver('line')->user();
|
||||
|
||||
// 从返回的信息中获取数据
|
||||
$lineId = $user->getId(); // LINE ID
|
||||
$name = $user->getName(); // 用户名
|
||||
$avatar = $user->getAvatar(); // 用户头像
|
||||
|
||||
// 查询数据库中是否已有此用户
|
||||
$existingUser = Member::where('line_id', $lineId)->first();
|
||||
|
||||
if ($existingUser) {
|
||||
// 如果用户存在,使用 guard 'member' 登录
|
||||
Auth::guard('member')->login($existingUser);
|
||||
} else {
|
||||
|
||||
$user = [
|
||||
'name' => $name,
|
||||
'line_id' => $lineId,
|
||||
'password' => bcrypt(env('DEFAULT_PASSWORD')),
|
||||
'avatar' => $avatar,
|
||||
'phone' => '',
|
||||
'source' => 'cafeg',
|
||||
];
|
||||
|
||||
// 如果用户不存在,创建新用户并登录
|
||||
$newUser = Member::create($user);
|
||||
|
||||
Auth::guard('member')->login($newUser);
|
||||
}
|
||||
|
||||
$user = Auth::guard('member')->user();
|
||||
|
||||
if (!$user->email) {
|
||||
return redirect()->route('member.profile');
|
||||
} else {
|
||||
|
||||
// 登录成功后重定向到特定页面
|
||||
return redirect()->route('member.index');
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1,19 +1,94 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Controllers\front;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\EmailVerifications;
|
||||
use App\Models\Member;
|
||||
use App\Models\Promocode;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Illuminate\Http\Request;
|
||||
use Mail;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
|
||||
class MemberController extends Controller
|
||||
{
|
||||
//
|
||||
public function index()
|
||||
{
|
||||
$code = null;
|
||||
|
||||
return view('front.member.index');
|
||||
if (isset(Auth::guard('member')->user()->id)) {
|
||||
$user_id = Auth::guard('member')->user()->id;
|
||||
$code = Promocode::where('used_count', $user_id)->first();
|
||||
|
||||
return view('front.member.index', ['code' => $code]);
|
||||
} else {
|
||||
Auth::guard('member')->logout();
|
||||
return redirect()->route('front.login.view');
|
||||
}
|
||||
}
|
||||
public function profile()
|
||||
{
|
||||
return view('front.member.profile');
|
||||
}
|
||||
/**
|
||||
* Summary of profileUpdate
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @return \Illuminate\Http\RedirectResponse
|
||||
* @todo 目前沒有錢包與購買方案與report 以後要 一起下壓
|
||||
* @method put
|
||||
*/
|
||||
public function profileUpdate(Request $request)
|
||||
{
|
||||
// 驗證輸入的數據
|
||||
$validatedData = $request->validate([
|
||||
'email' => 'required|email',
|
||||
'password' => 'nullable|min:6', // password 與 password_confirmation 必須匹配
|
||||
'phone' => 'nullable|string|max:15',
|
||||
]);
|
||||
|
||||
$auth = Member::find(Auth::guard('member')->id());
|
||||
|
||||
// 檢查是否已有其他會員使用相同的 email
|
||||
$user = Member::where('email', $validatedData['email'])->first();
|
||||
|
||||
if ($user && $user->id != $auth->id) {
|
||||
// 如果該 Email 已被其他用戶使用,返回錯誤信息
|
||||
return response()->json(['status' => 'error', 'msg' => '該 Email 已被其他帳戶使用'], 422);
|
||||
}
|
||||
|
||||
// 更新當前用戶的資料
|
||||
$auth->email = $validatedData['email'];
|
||||
if ($request->has('password')) {
|
||||
$auth->password = Hash::make($validatedData['password']);
|
||||
}
|
||||
$auth->phone = $validatedData['phone'] ?? $auth->phone;
|
||||
|
||||
// 保存更改
|
||||
$auth->save();
|
||||
|
||||
return response()->json(['status' => 'success', 'msg' => '更新成功']);
|
||||
}
|
||||
|
||||
public function pageProfile(Request $request)
|
||||
{
|
||||
|
||||
return view('front.member.page-profile');
|
||||
}
|
||||
|
||||
public function checkPhone(Request $request)
|
||||
{
|
||||
$validatedData = $request->validate([
|
||||
'phone' => 'required|string|max:15',
|
||||
]);
|
||||
\Log::info('checkPhone', []);
|
||||
$user = Member::where('phone', $validatedData['phone'])->first();
|
||||
|
||||
if ($user) {
|
||||
return response()->json(['status' => 'error', 'msg' => '該電話號碼已被其他帳戶使用']);
|
||||
}
|
||||
|
||||
return response()->json(['status' => 'success', 'msg' => '該電話號碼可用']);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
81
app/Http/Controllers/front/PromoCodeController.php
Normal file
81
app/Http/Controllers/front/PromoCodeController.php
Normal file
@ -0,0 +1,81 @@
|
||||
<?php
|
||||
namespace App\Http\Controllers\front;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Promocode;
|
||||
use Auth;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class PromoCodeController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create()
|
||||
{
|
||||
$user_id = Auth::guard('member')->user()->id;
|
||||
$count = Promocode::where('used_count', $user_id)->count();
|
||||
|
||||
if (! $count) {
|
||||
|
||||
$row = Promocode::where('used_count', 0)->first();
|
||||
$row->used_count = $user_id;
|
||||
$row->save();
|
||||
return response()->json(['status' => 'success', 'msg' => '已成功取得', 'promocode' => $row->code]);
|
||||
} else {
|
||||
$code = Promocode::where('used_count', $user_id)->first();
|
||||
return response()->json(['status' => 'success', 'msg' => '你已取得過優惠碼', 'promocode' => $code->code]);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(Promocode $promocode)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit(Promocode $promocode)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, Promocode $promocode)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(Promocode $promocode)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
83
app/Http/Controllers/front/RegisterController.php
Normal file
83
app/Http/Controllers/front/RegisterController.php
Normal file
@ -0,0 +1,83 @@
|
||||
<?php
|
||||
namespace App\Http\Controllers\front;
|
||||
|
||||
use App\Http\Controllers\Controller;
|
||||
use App\Models\Member;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class RegisterController extends Controller
|
||||
{
|
||||
/**
|
||||
* Display a listing of the resource.
|
||||
*/
|
||||
public function index()
|
||||
{
|
||||
return view('front.member.auth-register');
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for creating a new resource.
|
||||
*/
|
||||
public function create(Request $request)
|
||||
{
|
||||
|
||||
$newUser = Member::create([
|
||||
'name' => $request->name,
|
||||
'password' => bcrypt($request->password),
|
||||
'avatar' => $request->avatar ?? '',
|
||||
'email' => $request->email ?? '',
|
||||
'source' => 'cafeg',
|
||||
'phone' => $request->phone ?? '',
|
||||
]);
|
||||
|
||||
if (isset($newUser->email)) {
|
||||
|
||||
return redirect()->route('member.index')->with('sucess', '完成註冊');
|
||||
|
||||
} else {
|
||||
|
||||
return redirect()->route('member.profile')->with('sucess', '完成註冊,請完善你得資料');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Store a newly created resource in storage.
|
||||
*/
|
||||
public function store(Request $request)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Display the specified resource.
|
||||
*/
|
||||
public function show(Member $member)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the form for editing the specified resource.
|
||||
*/
|
||||
public function edit(Member $member)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the specified resource in storage.
|
||||
*/
|
||||
public function update(Request $request, Member $member)
|
||||
{
|
||||
//
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the specified resource from storage.
|
||||
*/
|
||||
public function destroy(Member $member)
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
34
app/Http/Middleware/AdminRedirect.php
Normal file
34
app/Http/Middleware/AdminRedirect.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class AdminRedirect
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
|
||||
if (!Auth::check() && $request->path() != 'admin/register') {
|
||||
return redirect()->route('admin.login');
|
||||
}
|
||||
if (Auth::check() && $request->path() == 'admin/login') {
|
||||
return redirect()->route('admin.index');
|
||||
}
|
||||
|
||||
// $user = Auth::user();
|
||||
// if ($user->email == null) {
|
||||
// return redirect()->route('admin.profile');
|
||||
// }
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
29
app/Http/Middleware/GuestRedirect.php
Normal file
29
app/Http/Middleware/GuestRedirect.php
Normal file
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class GuestRedirect
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
if (!Auth::guard('member')->check() && $request->path() == '/') {
|
||||
|
||||
return redirect()->route('front.login.view');
|
||||
|
||||
} else if ($request->path() == '/' && Auth::guard('member')->check()) {
|
||||
return redirect()->route('member.index');
|
||||
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
31
app/Http/Middleware/MemberRedirect.php
Normal file
31
app/Http/Middleware/MemberRedirect.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
class MemberRedirect
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
|
||||
// 使用 'member' 守卫检查是否已登录
|
||||
if (Auth::guard('member')->check()) {
|
||||
|
||||
$loginUrlPath = parse_url(route('front.login.view'), PHP_URL_PATH);
|
||||
if ($request->is('login')) {
|
||||
return redirect()->route('member.index');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
namespace App\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
@ -11,23 +10,19 @@ class memberAuth
|
||||
{
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
|
||||
*/
|
||||
public function handle(Request $request, Closure $next): Response
|
||||
{
|
||||
|
||||
// 使用 'member' 守卫检查是否已登录
|
||||
if (Auth::guard('member')->check()) {
|
||||
|
||||
$loginUrlPath = parse_url(route('front.login.view'), PHP_URL_PATH);
|
||||
// if ($request->path() === ltrim($loginUrlPath, '/')) {
|
||||
// return redirect()->route('member.index');
|
||||
|
||||
// }
|
||||
// 使用 'member' 守衛進行身份驗證
|
||||
if (!Auth::guard('member')->check()) {
|
||||
// 未登入,記錄日誌並重導向
|
||||
|
||||
\Log::warning('Unauthorized access attempt.', ['url' => $request->url()]);
|
||||
return redirect()->route('front.login.view');
|
||||
}
|
||||
|
||||
// 驗證成功,繼續處理請求
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
|
||||
36
app/Imports/PromoImport.php
Normal file
36
app/Imports/PromoImport.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
namespace App\Imports;
|
||||
|
||||
use App\Models\Promocode;
|
||||
use Illuminate\Support\Collection;
|
||||
use Log;
|
||||
use Maatwebsite\Excel\Concerns\ToCollection;
|
||||
|
||||
class PromoImport implements ToCollection
|
||||
{
|
||||
|
||||
public function collection(Collection $rows)
|
||||
{
|
||||
// 打印每一行數據(這是從 Excel 讀取的行)
|
||||
|
||||
foreach ($rows as $row) {
|
||||
|
||||
Log::info('Row data: ', ['value' => $row->toArray()[3]]);
|
||||
|
||||
if ($row->toArray()[3] != '提货码') // 跳過第一行
|
||||
{
|
||||
Promocode::create([
|
||||
'code' => $row->toArray()[3], // 使用 "提货码" 列
|
||||
'discount' => 100, // 假設折扣為固定值 100
|
||||
'type' => 'percent', // 默認為百分比
|
||||
'usage_limit' => 1, // 默認每個代碼只能使用一次
|
||||
'valid_from' => date('Y-m-d'), // 當前日期
|
||||
'valid_to' => date('Y-m-d', strtotime('1 day')), // 默認有效期至第二天
|
||||
'is_active' => 1, // 默認啟用
|
||||
]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
36
app/Mail/CustomMail.php
Normal file
36
app/Mail/CustomMail.php
Normal file
@ -0,0 +1,36 @@
|
||||
<?php
|
||||
namespace App\Mail;
|
||||
|
||||
use Illuminate\Bus\Queueable;
|
||||
use Illuminate\Mail\Mailable;
|
||||
use Illuminate\Queue\SerializesModels;
|
||||
use Log;
|
||||
|
||||
class CustomMail extends Mailable
|
||||
{
|
||||
use Queueable, SerializesModels;
|
||||
|
||||
public $subject;
|
||||
public $emailMessage;
|
||||
|
||||
public function __construct(string $subject, string $emailMessage)
|
||||
{
|
||||
$this->subject = $subject;
|
||||
$this->emailMessage = $emailMessage;
|
||||
}
|
||||
|
||||
public function build()
|
||||
{
|
||||
Log::info('mail send log test:', [
|
||||
'subject' => $this->subject,
|
||||
'emailMessage' => $this->emailMessage,
|
||||
]);
|
||||
|
||||
return $this->subject($this->subject)
|
||||
->view('emails.custom')
|
||||
->with([
|
||||
'subject' => $this->subject,
|
||||
'emailMessage' => $this->emailMessage,
|
||||
]);
|
||||
}
|
||||
}
|
||||
12
app/Models/EmailVerifications.php
Normal file
12
app/Models/EmailVerifications.php
Normal file
@ -0,0 +1,12 @@
|
||||
<?php
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class EmailVerifications extends Model
|
||||
{
|
||||
protected $table = "email_verifications";
|
||||
|
||||
protected $guarded = [];
|
||||
|
||||
}
|
||||
@ -26,6 +26,20 @@ class Member extends Authenticatable
|
||||
'line_id',
|
||||
];
|
||||
|
||||
// 定義 Level 描述對應
|
||||
public static $levelName = [
|
||||
0 => '一般會員',
|
||||
1 => '白銀會員',
|
||||
2 => '黃金會員',
|
||||
9 => '管理員',
|
||||
];
|
||||
|
||||
// 訪問器:自動轉換 Level
|
||||
public function getLevelNameAttribute()
|
||||
{
|
||||
return self::$levelName[$this->level] ?? '未知會員';
|
||||
}
|
||||
|
||||
/**
|
||||
* 隱藏的屬性。
|
||||
*
|
||||
|
||||
21
app/Models/Promocode.php
Normal file
21
app/Models/Promocode.php
Normal file
@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Promocode extends Model
|
||||
{
|
||||
//
|
||||
protected $table = 'promocodes';
|
||||
protected $fillable = [
|
||||
'code',
|
||||
'discount',
|
||||
'type',
|
||||
'usage_limit',
|
||||
'used_count',
|
||||
'valid_from',
|
||||
'valid_to',
|
||||
'is_active',
|
||||
];
|
||||
}
|
||||
@ -19,7 +19,10 @@ class User extends Authenticatable
|
||||
protected $fillable = [
|
||||
'name',
|
||||
'email',
|
||||
'avatar',
|
||||
'phone',
|
||||
'password',
|
||||
'line_id',
|
||||
];
|
||||
|
||||
/**
|
||||
@ -28,7 +31,6 @@ class User extends Authenticatable
|
||||
* @var array<int, string>
|
||||
*/
|
||||
protected $hidden = [
|
||||
'password',
|
||||
'remember_token',
|
||||
];
|
||||
|
||||
|
||||
@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Pagination\Paginator;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
|
||||
@ -31,5 +32,11 @@ public function boot(): void
|
||||
$app['request'], $config['client_id'], $config['client_secret'], $config['redirect']
|
||||
);
|
||||
});
|
||||
|
||||
// 设置默认分页视图为 Materialize 样式
|
||||
Paginator::defaultView('vendor.pagination.materialize');
|
||||
|
||||
// 可选:设置简单分页的默认视图
|
||||
Paginator::defaultSimpleView('vendor.pagination.materialize');
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Support\ServiceProvider;
|
||||
@ -21,19 +20,19 @@ public function boot(): void
|
||||
{
|
||||
// 定義垂直與水平菜單的 JSON 文件路徑
|
||||
$verticalMenuPath = base_path('resources/menu/verticalMenu.json');
|
||||
$horizontalMenuPath = base_path('resources/menu/horizontalMenu.json');
|
||||
$memberMenuPath = base_path('resources/menu/memberMenu.json');
|
||||
|
||||
// 確保文件存在
|
||||
if (!file_exists($verticalMenuPath) || !file_exists($horizontalMenuPath)) {
|
||||
if (! file_exists($verticalMenuPath) || ! file_exists($memberMenuPath)) {
|
||||
throw new \Exception('Menu JSON files are missing.');
|
||||
}
|
||||
|
||||
// 讀取並解析 JSON 文件
|
||||
$verticalMenuJson = file_get_contents($verticalMenuPath);
|
||||
$horizontalMenuJson = file_get_contents($horizontalMenuPath);
|
||||
$memberMenuJson = file_get_contents($memberMenuPath);
|
||||
|
||||
$verticalMenuData = json_decode($verticalMenuJson);
|
||||
$horizontalMenuData = json_decode($horizontalMenuJson);
|
||||
$memberMenuData = json_decode($memberMenuJson);
|
||||
|
||||
// 確保解析成功
|
||||
if (json_last_error() !== JSON_ERROR_NONE) {
|
||||
@ -43,7 +42,7 @@ public function boot(): void
|
||||
// 分享數據到所有視圖
|
||||
view()->share('menuData', [
|
||||
$verticalMenuData,
|
||||
$horizontalMenuData,
|
||||
$memberMenuData,
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,41 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Providers;
|
||||
|
||||
use Illuminate\Cache\RateLimiting\Limit;
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The path to your application's "home" route.
|
||||
*
|
||||
* Typically, users are redirected here after authentication.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const HOME = '/home';
|
||||
protected $namespace = 'App\Http\Controllers';
|
||||
/**
|
||||
* Define your route model bindings, pattern filters, and other route configuration.
|
||||
*/
|
||||
public function boot(): void
|
||||
{
|
||||
RateLimiter::for('api', function (Request $request) {
|
||||
return Limit::perMinute(60)->by($request->user()?->id ?: $request->ip());
|
||||
});
|
||||
|
||||
$this->routes(function () {
|
||||
Route::middleware('api')
|
||||
->prefix('api')
|
||||
->group(base_path('routes/api.php'));
|
||||
|
||||
Route::middleware('web')
|
||||
->namespace('App\Http\Controllers')
|
||||
->group(base_path('routes/web.php'));
|
||||
});
|
||||
}
|
||||
}
|
||||
@ -23,6 +23,7 @@
|
||||
]);
|
||||
|
||||
})
|
||||
|
||||
->withExceptions(function (Exceptions $exceptions) {
|
||||
//
|
||||
})->create();
|
||||
|
||||
@ -3,4 +3,5 @@
|
||||
return [
|
||||
App\Providers\AppServiceProvider::class,
|
||||
App\Providers\MenuProvider::class,
|
||||
|
||||
];
|
||||
|
||||
@ -11,6 +11,7 @@
|
||||
"laravel/sanctum": "^4.0",
|
||||
"laravel/socialite": "^5.16",
|
||||
"laravel/tinker": "^2.9",
|
||||
"maatwebsite/excel": "^3.1",
|
||||
"socialiteproviders/line": "^4.1"
|
||||
},
|
||||
"require-dev": {
|
||||
|
||||
514
composer.lock
generated
514
composer.lock
generated
@ -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": "6124ac50e296caf206e7d2ec2e56ae8e",
|
||||
"content-hash": "a479f93c0f786bef7c2eb2887cbe259b",
|
||||
"packages": [
|
||||
{
|
||||
"name": "brick/math",
|
||||
@ -135,6 +135,87 @@
|
||||
],
|
||||
"time": "2024-02-09T16:56:22+00:00"
|
||||
},
|
||||
{
|
||||
"name": "composer/semver",
|
||||
"version": "3.4.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/composer/semver.git",
|
||||
"reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/composer/semver/zipball/4313d26ada5e0c4edfbd1dc481a92ff7bff91f12",
|
||||
"reference": "4313d26ada5e0c4edfbd1dc481a92ff7bff91f12",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^5.3.2 || ^7.0 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpstan/phpstan": "^1.11",
|
||||
"symfony/phpunit-bridge": "^3 || ^7"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Composer\\Semver\\": "src"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Nils Adermann",
|
||||
"email": "naderman@naderman.de",
|
||||
"homepage": "http://www.naderman.de"
|
||||
},
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "http://seld.be"
|
||||
},
|
||||
{
|
||||
"name": "Rob Bast",
|
||||
"email": "rob.bast@gmail.com",
|
||||
"homepage": "http://robbast.nl"
|
||||
}
|
||||
],
|
||||
"description": "Semver library that offers utilities, version constraint parsing and validation.",
|
||||
"keywords": [
|
||||
"semantic",
|
||||
"semver",
|
||||
"validation",
|
||||
"versioning"
|
||||
],
|
||||
"support": {
|
||||
"irc": "ircs://irc.libera.chat:6697/composer",
|
||||
"issues": "https://github.com/composer/semver/issues",
|
||||
"source": "https://github.com/composer/semver/tree/3.4.3"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://packagist.com",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/composer",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/composer/composer",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2024-09-19T14:15:21+00:00"
|
||||
},
|
||||
{
|
||||
"name": "dflydev/dot-access-data",
|
||||
"version": "v3.0.3",
|
||||
@ -510,6 +591,67 @@
|
||||
],
|
||||
"time": "2024-12-27T00:36:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "ezyang/htmlpurifier",
|
||||
"version": "v4.18.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/ezyang/htmlpurifier.git",
|
||||
"reference": "cb56001e54359df7ae76dc522d08845dc741621b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/ezyang/htmlpurifier/zipball/cb56001e54359df7ae76dc522d08845dc741621b",
|
||||
"reference": "cb56001e54359df7ae76dc522d08845dc741621b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "~5.6.0 || ~7.0.0 || ~7.1.0 || ~7.2.0 || ~7.3.0 || ~7.4.0 || ~8.0.0 || ~8.1.0 || ~8.2.0 || ~8.3.0 || ~8.4.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"cerdic/css-tidy": "^1.7 || ^2.0",
|
||||
"simpletest/simpletest": "dev-master"
|
||||
},
|
||||
"suggest": {
|
||||
"cerdic/css-tidy": "If you want to use the filter 'Filter.ExtractStyleBlocks'.",
|
||||
"ext-bcmath": "Used for unit conversion and imagecrash protection",
|
||||
"ext-iconv": "Converts text to and from non-UTF-8 encodings",
|
||||
"ext-tidy": "Used for pretty-printing HTML"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"files": [
|
||||
"library/HTMLPurifier.composer.php"
|
||||
],
|
||||
"psr-0": {
|
||||
"HTMLPurifier": "library/"
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/library/HTMLPurifier/Language/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"LGPL-2.1-or-later"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Edward Z. Yang",
|
||||
"email": "admin@htmlpurifier.org",
|
||||
"homepage": "http://ezyang.com"
|
||||
}
|
||||
],
|
||||
"description": "Standards compliant HTML filter written in PHP",
|
||||
"homepage": "http://htmlpurifier.org/",
|
||||
"keywords": [
|
||||
"html"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/ezyang/htmlpurifier/issues",
|
||||
"source": "https://github.com/ezyang/htmlpurifier/tree/v4.18.0"
|
||||
},
|
||||
"time": "2024-11-01T03:51:45+00:00"
|
||||
},
|
||||
{
|
||||
"name": "fahlisaputra/laravel-minify",
|
||||
"version": "v1.1.5",
|
||||
@ -2346,6 +2488,271 @@
|
||||
],
|
||||
"time": "2024-12-08T08:18:47+00:00"
|
||||
},
|
||||
{
|
||||
"name": "maatwebsite/excel",
|
||||
"version": "3.1.62",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/SpartnerNL/Laravel-Excel.git",
|
||||
"reference": "decfb9140161fcc117571e47e35ddf27983189ce"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/SpartnerNL/Laravel-Excel/zipball/decfb9140161fcc117571e47e35ddf27983189ce",
|
||||
"reference": "decfb9140161fcc117571e47e35ddf27983189ce",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"composer/semver": "^3.3",
|
||||
"ext-json": "*",
|
||||
"illuminate/support": "5.8.*||^6.0||^7.0||^8.0||^9.0||^10.0||^11.0",
|
||||
"php": "^7.0||^8.0",
|
||||
"phpoffice/phpspreadsheet": "^1.29.7",
|
||||
"psr/simple-cache": "^1.0||^2.0||^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"laravel/scout": "^7.0||^8.0||^9.0||^10.0",
|
||||
"orchestra/testbench": "^6.0||^7.0||^8.0||^9.0",
|
||||
"predis/predis": "^1.1"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"aliases": {
|
||||
"Excel": "Maatwebsite\\Excel\\Facades\\Excel"
|
||||
},
|
||||
"providers": [
|
||||
"Maatwebsite\\Excel\\ExcelServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Maatwebsite\\Excel\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Patrick Brouwers",
|
||||
"email": "patrick@spartner.nl"
|
||||
}
|
||||
],
|
||||
"description": "Supercharged Excel exports and imports in Laravel",
|
||||
"keywords": [
|
||||
"PHPExcel",
|
||||
"batch",
|
||||
"csv",
|
||||
"excel",
|
||||
"export",
|
||||
"import",
|
||||
"laravel",
|
||||
"php",
|
||||
"phpspreadsheet"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/SpartnerNL/Laravel-Excel/issues",
|
||||
"source": "https://github.com/SpartnerNL/Laravel-Excel/tree/3.1.62"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://laravel-excel.com/commercial-support",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/patrickbrouwers",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2025-01-04T12:14:36+00:00"
|
||||
},
|
||||
{
|
||||
"name": "maennchen/zipstream-php",
|
||||
"version": "3.1.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/maennchen/ZipStream-PHP.git",
|
||||
"reference": "6187e9cc4493da94b9b63eb2315821552015fca9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/maennchen/ZipStream-PHP/zipball/6187e9cc4493da94b9b63eb2315821552015fca9",
|
||||
"reference": "6187e9cc4493da94b9b63eb2315821552015fca9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-mbstring": "*",
|
||||
"ext-zlib": "*",
|
||||
"php-64bit": "^8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"ext-zip": "*",
|
||||
"friendsofphp/php-cs-fixer": "^3.16",
|
||||
"guzzlehttp/guzzle": "^7.5",
|
||||
"mikey179/vfsstream": "^1.6",
|
||||
"php-coveralls/php-coveralls": "^2.5",
|
||||
"phpunit/phpunit": "^10.0",
|
||||
"vimeo/psalm": "^5.0"
|
||||
},
|
||||
"suggest": {
|
||||
"guzzlehttp/psr7": "^2.4",
|
||||
"psr/http-message": "^2.0"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"ZipStream\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Paul Duncan",
|
||||
"email": "pabs@pablotron.org"
|
||||
},
|
||||
{
|
||||
"name": "Jonatan Männchen",
|
||||
"email": "jonatan@maennchen.ch"
|
||||
},
|
||||
{
|
||||
"name": "Jesse Donat",
|
||||
"email": "donatj@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "András Kolesár",
|
||||
"email": "kolesar@kolesar.hu"
|
||||
}
|
||||
],
|
||||
"description": "ZipStream is a library for dynamically streaming dynamic zip files from PHP without writing to the disk at all on the server.",
|
||||
"keywords": [
|
||||
"stream",
|
||||
"zip"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/maennchen/ZipStream-PHP/issues",
|
||||
"source": "https://github.com/maennchen/ZipStream-PHP/tree/3.1.1"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/maennchen",
|
||||
"type": "github"
|
||||
}
|
||||
],
|
||||
"time": "2024-10-10T12:33:01+00:00"
|
||||
},
|
||||
{
|
||||
"name": "markbaker/complex",
|
||||
"version": "3.0.2",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/MarkBaker/PHPComplex.git",
|
||||
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/MarkBaker/PHPComplex/zipball/95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
|
||||
"reference": "95c56caa1cf5c766ad6d65b6344b807c1e8405b9",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.2 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
|
||||
"phpcompatibility/php-compatibility": "^9.3",
|
||||
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
|
||||
"squizlabs/php_codesniffer": "^3.7"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Complex\\": "classes/src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mark Baker",
|
||||
"email": "mark@lange.demon.co.uk"
|
||||
}
|
||||
],
|
||||
"description": "PHP Class for working with complex numbers",
|
||||
"homepage": "https://github.com/MarkBaker/PHPComplex",
|
||||
"keywords": [
|
||||
"complex",
|
||||
"mathematics"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/MarkBaker/PHPComplex/issues",
|
||||
"source": "https://github.com/MarkBaker/PHPComplex/tree/3.0.2"
|
||||
},
|
||||
"time": "2022-12-06T16:21:08+00:00"
|
||||
},
|
||||
{
|
||||
"name": "markbaker/matrix",
|
||||
"version": "3.0.1",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/MarkBaker/PHPMatrix.git",
|
||||
"reference": "728434227fe21be27ff6d86621a1b13107a2562c"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/MarkBaker/PHPMatrix/zipball/728434227fe21be27ff6d86621a1b13107a2562c",
|
||||
"reference": "728434227fe21be27ff6d86621a1b13107a2562c",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^7.1 || ^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "dev-master",
|
||||
"phpcompatibility/php-compatibility": "^9.3",
|
||||
"phpdocumentor/phpdocumentor": "2.*",
|
||||
"phploc/phploc": "^4.0",
|
||||
"phpmd/phpmd": "2.*",
|
||||
"phpunit/phpunit": "^7.0 || ^8.0 || ^9.0",
|
||||
"sebastian/phpcpd": "^4.0",
|
||||
"squizlabs/php_codesniffer": "^3.7"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Matrix\\": "classes/src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Mark Baker",
|
||||
"email": "mark@demon-angel.eu"
|
||||
}
|
||||
],
|
||||
"description": "PHP Class for working with matrices",
|
||||
"homepage": "https://github.com/MarkBaker/PHPMatrix",
|
||||
"keywords": [
|
||||
"mathematics",
|
||||
"matrix",
|
||||
"vector"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/MarkBaker/PHPMatrix/issues",
|
||||
"source": "https://github.com/MarkBaker/PHPMatrix/tree/3.0.1"
|
||||
},
|
||||
"time": "2022-12-02T22:17:43+00:00"
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "3.8.1",
|
||||
@ -2965,6 +3372,111 @@
|
||||
},
|
||||
"time": "2020-10-15T08:29:30+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpoffice/phpspreadsheet",
|
||||
"version": "1.29.7",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/PHPOffice/PhpSpreadsheet.git",
|
||||
"reference": "02c8625411dcb96e1f63d58c47460284e15b2e80"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/PHPOffice/PhpSpreadsheet/zipball/02c8625411dcb96e1f63d58c47460284e15b2e80",
|
||||
"reference": "02c8625411dcb96e1f63d58c47460284e15b2e80",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"ext-ctype": "*",
|
||||
"ext-dom": "*",
|
||||
"ext-fileinfo": "*",
|
||||
"ext-gd": "*",
|
||||
"ext-iconv": "*",
|
||||
"ext-libxml": "*",
|
||||
"ext-mbstring": "*",
|
||||
"ext-simplexml": "*",
|
||||
"ext-xml": "*",
|
||||
"ext-xmlreader": "*",
|
||||
"ext-xmlwriter": "*",
|
||||
"ext-zip": "*",
|
||||
"ext-zlib": "*",
|
||||
"ezyang/htmlpurifier": "^4.15",
|
||||
"maennchen/zipstream-php": "^2.1 || ^3.0",
|
||||
"markbaker/complex": "^3.0",
|
||||
"markbaker/matrix": "^3.0",
|
||||
"php": "^7.4 || ^8.0",
|
||||
"psr/http-client": "^1.0",
|
||||
"psr/http-factory": "^1.0",
|
||||
"psr/simple-cache": "^1.0 || ^2.0 || ^3.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"dealerdirect/phpcodesniffer-composer-installer": "dev-main",
|
||||
"dompdf/dompdf": "^1.0 || ^2.0 || ^3.0",
|
||||
"friendsofphp/php-cs-fixer": "^3.2",
|
||||
"mitoteam/jpgraph": "^10.3",
|
||||
"mpdf/mpdf": "^8.1.1",
|
||||
"phpcompatibility/php-compatibility": "^9.3",
|
||||
"phpstan/phpstan": "^1.1",
|
||||
"phpstan/phpstan-phpunit": "^1.0",
|
||||
"phpunit/phpunit": "^8.5 || ^9.0",
|
||||
"squizlabs/php_codesniffer": "^3.7",
|
||||
"tecnickcom/tcpdf": "^6.5"
|
||||
},
|
||||
"suggest": {
|
||||
"dompdf/dompdf": "Option for rendering PDF with PDF Writer",
|
||||
"ext-intl": "PHP Internationalization Functions",
|
||||
"mitoteam/jpgraph": "Option for rendering charts, or including charts with PDF or HTML Writers",
|
||||
"mpdf/mpdf": "Option for rendering PDF with PDF Writer",
|
||||
"tecnickcom/tcpdf": "Option for rendering PDF with PDF Writer"
|
||||
},
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"PhpOffice\\PhpSpreadsheet\\": "src/PhpSpreadsheet"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Maarten Balliauw",
|
||||
"homepage": "https://blog.maartenballiauw.be"
|
||||
},
|
||||
{
|
||||
"name": "Mark Baker",
|
||||
"homepage": "https://markbakeruk.net"
|
||||
},
|
||||
{
|
||||
"name": "Franck Lefevre",
|
||||
"homepage": "https://rootslabs.net"
|
||||
},
|
||||
{
|
||||
"name": "Erik Tilt"
|
||||
},
|
||||
{
|
||||
"name": "Adrien Crivelli"
|
||||
}
|
||||
],
|
||||
"description": "PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine",
|
||||
"homepage": "https://github.com/PHPOffice/PhpSpreadsheet",
|
||||
"keywords": [
|
||||
"OpenXML",
|
||||
"excel",
|
||||
"gnumeric",
|
||||
"ods",
|
||||
"php",
|
||||
"spreadsheet",
|
||||
"xls",
|
||||
"xlsx"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/PHPOffice/PhpSpreadsheet/issues",
|
||||
"source": "https://github.com/PHPOffice/PhpSpreadsheet/tree/1.29.7"
|
||||
},
|
||||
"time": "2024-12-27T05:10:37+00:00"
|
||||
},
|
||||
{
|
||||
"name": "phpoption/phpoption",
|
||||
"version": "1.9.3",
|
||||
|
||||
@ -11,7 +11,7 @@
|
||||
| framework needs to place the application's name in a notification or
|
||||
| other UI elements where an application name needs to be displayed.
|
||||
|
|
||||
*/
|
||||
*/
|
||||
|
||||
'name' => env('APP_NAME', 'Laravel'),
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
| running in. This may determine how you prefer to configure various
|
||||
| services the application utilizes. Set this in your ".env" file.
|
||||
|
|
||||
*/
|
||||
*/
|
||||
|
||||
'env' => env('APP_ENV', 'production'),
|
||||
|
||||
@ -37,7 +37,7 @@
|
||||
| stack traces will be shown on every error that occurs within your
|
||||
| application. If disabled, a simple generic error page is shown.
|
||||
|
|
||||
*/
|
||||
*/
|
||||
|
||||
'debug' => (bool) env('APP_DEBUG', false),
|
||||
|
||||
@ -50,7 +50,7 @@
|
||||
| the Artisan command line tool. You should set this to the root of
|
||||
| the application so that it's available within Artisan commands.
|
||||
|
|
||||
*/
|
||||
*/
|
||||
|
||||
'url' => env('APP_URL', 'http://localhost'),
|
||||
|
||||
@ -63,9 +63,9 @@
|
||||
| will be used by the PHP date and date-time functions. The timezone
|
||||
| is set to "UTC" by default as it is suitable for most use cases.
|
||||
|
|
||||
*/
|
||||
*/
|
||||
|
||||
'timezone' => env('APP_TIMEZONE', 'UTC'),
|
||||
'timezone' => env('APP_TIMEZONE', 'asia/Taipei'),
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
@ -76,7 +76,7 @@
|
||||
| by Laravel's translation / localization methods. This option can be
|
||||
| set to any locale for which you plan to have translation strings.
|
||||
|
|
||||
*/
|
||||
*/
|
||||
|
||||
'locale' => env('APP_LOCALE', 'en'),
|
||||
|
||||
@ -93,14 +93,14 @@
|
||||
| to a random, 32 character string to ensure that all encrypted values
|
||||
| are secure. You should do this prior to deploying the application.
|
||||
|
|
||||
*/
|
||||
*/
|
||||
|
||||
'cipher' => 'AES-256-CBC',
|
||||
|
||||
'key' => env('APP_KEY'),
|
||||
|
||||
'previous_keys' => [
|
||||
...array_filter(
|
||||
...array_filter(
|
||||
explode(',', env('APP_PREVIOUS_KEYS', ''))
|
||||
),
|
||||
],
|
||||
@ -116,7 +116,7 @@
|
||||
|
|
||||
| Supported drivers: "file", "cache"
|
||||
|
|
||||
*/
|
||||
*/
|
||||
|
||||
'maintenance' => [
|
||||
'driver' => env('APP_MAINTENANCE_DRIVER', 'file'),
|
||||
|
||||
@ -14,12 +14,14 @@ public function up(): void
|
||||
Schema::create('users', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name');
|
||||
$table->string('email')->unique();
|
||||
$table->string('email')->nullable()->unique();
|
||||
$table->timestamp('email_verified_at')->nullable();
|
||||
$table->string('app_id')->comment('line user_id');
|
||||
$table->string('line_id')->nullable()->comment('line user_id');
|
||||
$table->string('phone')->nullable()->comment('手機電話');
|
||||
$table->string('role')->comment('admin,agent');
|
||||
// $table->string('role')->comment('admin,agent');
|
||||
$table->string('password');
|
||||
$table->string('avatar')->nullable(); // 頭像
|
||||
$table->boolean('can_login')->default(true); // 是否可以登入
|
||||
$table->rememberToken();
|
||||
$table->softDeletes();
|
||||
$table->timestamps();
|
||||
@ -32,12 +34,20 @@ public function up(): void
|
||||
});
|
||||
|
||||
Schema::create('sessions', function (Blueprint $table) {
|
||||
$table->string('id')->primary();
|
||||
$table->foreignId('user_id')->nullable()->index();
|
||||
$table->string('ip_address', 45)->nullable();
|
||||
$table->text('user_agent')->nullable();
|
||||
$table->longText('payload');
|
||||
$table->integer('last_activity')->index();
|
||||
$table->id();
|
||||
$table->string('name')->default('客戶')->nullable(); // 使用者名稱
|
||||
$table->string('email')->nullable()->unique(); // 電子郵件
|
||||
$table->string('password'); // 密碼
|
||||
$table->string('avatar')->nullable(); // 頭像
|
||||
$table->string('phone')->nullable(); // 電話
|
||||
$table->string('line_id')->nullable()->unique(); // Line ID
|
||||
$table->string('facebook_id')->nullable()->unique(); // Facebook ID
|
||||
$table->string('google_id')->nullable()->unique(); // Google ID
|
||||
$table->integer('level')->default(1)->comment('會員等級 一般,1.系統管理員,2工程師'); // 會員等級
|
||||
$table->string('reset_token')->nullable(); // 密碼重置 Token
|
||||
$table->timestamp('email_verified_at')->nullable(); // 電子郵件驗證時間
|
||||
$table->rememberToken(); // 記住登入 Token
|
||||
$table->timestamps(); // 建立與更新時間
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -15,20 +15,21 @@ public function up()
|
||||
{
|
||||
Schema::create('members', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('name')->default('客戶')->nullable(); // 使用者名稱
|
||||
$table->string('email')->nullable()->unique(); // 電子郵件
|
||||
$table->string('password'); // 密碼
|
||||
$table->string('avatar')->nullable(); // 頭像
|
||||
$table->string('phone')->nullable(); // 電話
|
||||
$table->string('source')->comment('來源'); // 來源
|
||||
$table->string('line_id')->nullable()->unique(); // Line ID
|
||||
$table->string('facebook_id')->nullable()->unique(); // Facebook ID
|
||||
$table->string('google_id')->nullable()->unique(); // Google ID
|
||||
$table->string('name')->default('客戶')->nullable(); // 使用者名稱
|
||||
$table->string('email')->nullable()->unique(); // 電子郵件
|
||||
$table->string('password'); // 密碼
|
||||
$table->string('avatar')->nullable(); // 頭像
|
||||
$table->string('phone')->nullable(); // 電話
|
||||
$table->string('source')->comment('來源'); // 來源
|
||||
$table->string('line_id')->nullable()->unique(); // Line ID
|
||||
$table->string('facebook_id')->nullable()->unique(); // Facebook ID
|
||||
$table->string('google_id')->nullable()->unique(); // Google ID
|
||||
$table->integer('level')->default(0)->comment('會員等級 0 一般,1.銀會員,2金會員,9.測試人員'); // 會員等級
|
||||
$table->string('reset_token')->nullable(); // 密碼重置 Token
|
||||
$table->timestamp('email_verified_at')->nullable(); // 電子郵件驗證時間
|
||||
$table->rememberToken(); // 記住登入 Token
|
||||
$table->timestamps(); // 建立與更新時間
|
||||
$table->string('reset_token')->nullable(); // 密碼重置 Token
|
||||
$table->softDeletes(); //軟刪除
|
||||
$table->timestamp('email_verified_at')->nullable(); // 電子郵件驗證時間
|
||||
$table->rememberToken(); // 記住登入 Token
|
||||
$table->timestamps(); // 建立與更新時間
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@ -16,10 +16,10 @@ public function up(): void
|
||||
$table->string('order_no')->comment('訂單編號');
|
||||
$table->string('member_id')->comment('會員編號');
|
||||
$table->string('name')->comment('姓名');
|
||||
$table->integer('goods_code', 8)->comment('提貨編號');
|
||||
$table->integer('goods_code')->nullable()->comment('提貨編號');
|
||||
$table->string('goods')->comment('商品');
|
||||
$table->string('amount')->comment('金額');
|
||||
$table->string('status')->comment('狀態0:未付款,1:已付款,2:已出貨,3:已完成,4:已取消');
|
||||
$table->string('status')->comment('狀態0:未付款,1:已付款,2:已兌換 ,3:優惠碼兌換,4:已完成,5:已取消');
|
||||
$table->string('note')->comment('備註');
|
||||
$table->string('price')->comment('單一價格');
|
||||
$table->timestamps();
|
||||
|
||||
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('promocodes', function (Blueprint $table) {
|
||||
$table->id(); // 自增主鍵
|
||||
$table->string('code', 8)->unique()->comment('優惠碼');
|
||||
$table->decimal('discount', 8, 2)->default(100)->comment('折扣金額或百分比');
|
||||
$table->enum('type', ['amount', 'percent'])->default('percent')->comment('優惠類型: 金額或百分比');
|
||||
$table->integer('usage_limit')->default(1)->comment('使用次數限制');
|
||||
$table->integer('used_count')->default(0)->comment('已使用次數');
|
||||
$table->date('valid_from')->nullable()->comment('有效期開始');
|
||||
$table->date('valid_to')->nullable()->comment('有效期結束');
|
||||
$table->boolean('is_active')->default(true)->comment('是否啟用');
|
||||
$table->timestamps(); // 自動生成 created_at 和 updated_at
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('promocodes');
|
||||
}
|
||||
};
|
||||
@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
return new class extends Migration
|
||||
{
|
||||
/**
|
||||
* Run the migrations.
|
||||
*/
|
||||
public function up(): void
|
||||
{
|
||||
Schema::create('email_verifications', function (Blueprint $table) {
|
||||
$table->id();
|
||||
$table->string('email')->unique();
|
||||
$table->string('token');
|
||||
$table->timestamps();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Reverse the migrations.
|
||||
*/
|
||||
public function down(): void
|
||||
{
|
||||
Schema::dropIfExists('email_verifications');
|
||||
}
|
||||
};
|
||||
17
database/seeders/PromocodeSeeder.php
Normal file
17
database/seeders/PromocodeSeeder.php
Normal file
@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Console\Seeds\WithoutModelEvents;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
||||
class PromocodeSeeder extends Seeder
|
||||
{
|
||||
/**
|
||||
* Run the database seeds.
|
||||
*/
|
||||
public function run(): void
|
||||
{
|
||||
//
|
||||
}
|
||||
}
|
||||
31
package-lock.json
generated
31
package-lock.json
generated
@ -5,6 +5,7 @@
|
||||
"packages": {
|
||||
"": {
|
||||
"devDependencies": {
|
||||
"@types/jquery": "^3.5.32",
|
||||
"axios": "^1.6.4",
|
||||
"laravel-vite-plugin": "^1.0",
|
||||
"vite": "^5.0"
|
||||
@ -631,6 +632,21 @@
|
||||
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/@types/jquery": {
|
||||
"version": "3.5.32",
|
||||
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.32.tgz",
|
||||
"integrity": "sha512-b9Xbf4CkMqS02YH8zACqN1xzdxc3cO735Qe5AbSUFmyOiaWAbcpqh9Wna+Uk0vgACvoQHpWDg2rGdHkYPLmCiQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@types/sizzle": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/sizzle": {
|
||||
"version": "2.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.9.tgz",
|
||||
"integrity": "sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
@ -1283,6 +1299,21 @@
|
||||
"integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/jquery": {
|
||||
"version": "3.5.32",
|
||||
"resolved": "https://registry.npmjs.org/@types/jquery/-/jquery-3.5.32.tgz",
|
||||
"integrity": "sha512-b9Xbf4CkMqS02YH8zACqN1xzdxc3cO735Qe5AbSUFmyOiaWAbcpqh9Wna+Uk0vgACvoQHpWDg2rGdHkYPLmCiQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@types/sizzle": "*"
|
||||
}
|
||||
},
|
||||
"@types/sizzle": {
|
||||
"version": "2.3.9",
|
||||
"resolved": "https://registry.npmjs.org/@types/sizzle/-/sizzle-2.3.9.tgz",
|
||||
"integrity": "sha512-xzLEyKB50yqCUPUJkIsrVvoWNfFUbIZI+RspLWt8u+tIW/BetMBZtgV2LY/2o+tYH8dRvQ+eoPf3NdhQCcLE2w==",
|
||||
"dev": true
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
|
||||
@ -6,6 +6,7 @@
|
||||
"build": "vite build"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/jquery": "^3.5.32",
|
||||
"axios": "^1.6.4",
|
||||
"laravel-vite-plugin": "^1.0",
|
||||
"vite": "^5.0"
|
||||
|
||||
BIN
public/assets/img/pages/profile_banner.png
Normal file
BIN
public/assets/img/pages/profile_banner.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 52 KiB |
@ -84,30 +84,30 @@ document.addEventListener('DOMContentLoaded', function (e) {
|
||||
formValidationEmail: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Please enter your email'
|
||||
message: '請輸入您的電子郵件'
|
||||
},
|
||||
emailAddress: {
|
||||
message: 'The value is not a valid email address'
|
||||
message: '這不是有效的電子郵件'
|
||||
}
|
||||
}
|
||||
},
|
||||
formValidationPass: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Please enter your password'
|
||||
message: '請輸入您的密碼'
|
||||
}
|
||||
}
|
||||
},
|
||||
formValidationConfirmPass: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Please confirm password'
|
||||
message: '請確認您的密碼'
|
||||
},
|
||||
identical: {
|
||||
compare: function () {
|
||||
return formValidationExamples.querySelector('[name="formValidationPass"]').value;
|
||||
},
|
||||
message: 'The password and its confirm are not the same'
|
||||
message: '密碼與確認密碼不相符'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -64,7 +64,7 @@ document.addEventListener('DOMContentLoaded', function (e) {
|
||||
message: 'Please enter billing email'
|
||||
},
|
||||
emailAddress: {
|
||||
message: 'Please enter valid email address'
|
||||
message: '請輸入正確的email地址'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -14,7 +14,7 @@ document.addEventListener('DOMContentLoaded', function (e) {
|
||||
username: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Please enter username'
|
||||
message: '請輸入您的名字'
|
||||
},
|
||||
stringLength: {
|
||||
min: 6,
|
||||
@ -25,10 +25,10 @@ document.addEventListener('DOMContentLoaded', function (e) {
|
||||
email: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Please enter your email'
|
||||
message: '請輸入電子郵件'
|
||||
},
|
||||
emailAddress: {
|
||||
message: 'Please enter valid email address'
|
||||
message: '請輸入有效的電子郵件'
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -46,28 +46,28 @@ document.addEventListener('DOMContentLoaded', function (e) {
|
||||
password: {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Please enter your password'
|
||||
message: '請輸入您的密碼'
|
||||
},
|
||||
stringLength: {
|
||||
min: 6,
|
||||
message: 'Password must be more than 6 characters'
|
||||
message: '密碼字元必須大於 6 個字元'
|
||||
}
|
||||
}
|
||||
},
|
||||
'confirm-password': {
|
||||
validators: {
|
||||
notEmpty: {
|
||||
message: 'Please confirm password'
|
||||
message: '請確認密碼'
|
||||
},
|
||||
identical: {
|
||||
compare: function () {
|
||||
return formAuthentication.querySelector('[name="password"]').value;
|
||||
},
|
||||
message: 'The password and its confirm are not the same'
|
||||
message: '密碼與確認密碼不相符'
|
||||
},
|
||||
stringLength: {
|
||||
min: 6,
|
||||
message: 'Password must be more than 6 characters'
|
||||
message: '密碼必須大於6個字元'
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
[
|
||||
{
|
||||
"name": "Profile",
|
||||
"icon": "menu-icon tf-icons ri-user-line",
|
||||
"slug": "profile",
|
||||
"url": "/profile"
|
||||
},
|
||||
{
|
||||
"name": "Help",
|
||||
"icon": "menu-icon tf-icons ri-question-line",
|
||||
"slug": "help",
|
||||
"url": "/help"
|
||||
}
|
||||
]
|
||||
15
resources/menu/memberMenu.json
Normal file
15
resources/menu/memberMenu.json
Normal file
@ -0,0 +1,15 @@
|
||||
[
|
||||
{
|
||||
"name": "個人資訊",
|
||||
"icon": "menu-icon tf-icons ri-user-line",
|
||||
"slug": "profile",
|
||||
"url": "member/page-profile"
|
||||
},
|
||||
{
|
||||
"name": "登 出",
|
||||
"icon": "menu-icon tf-icons ri-logout-circle-line",
|
||||
"slug": "logout",
|
||||
"url": "member/logout"
|
||||
}
|
||||
|
||||
]
|
||||
@ -5,21 +5,32 @@
|
||||
"slug": "dashboard",
|
||||
"submenu": [
|
||||
{
|
||||
"url": "/",
|
||||
"name": "Analytics",
|
||||
"url": "admin/memberlist",
|
||||
"name": "會員列表",
|
||||
"slug": "dashboard-analytics"
|
||||
},
|
||||
}
|
||||
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "設 定",
|
||||
"icon": "menu-icon tf-icons ri-settings-line",
|
||||
"slug": "setting",
|
||||
"submenu": [
|
||||
{
|
||||
"url": "/dashboard/crm",
|
||||
"name": "CRM",
|
||||
"slug": "dashboard-crm"
|
||||
"url": "admin/setting/promocode",
|
||||
"name": "優惠代碼",
|
||||
"slug": "setting-promocode"
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "Settings",
|
||||
"icon": "menu-icon tf-icons ri-settings-line",
|
||||
"slug": "settings",
|
||||
"submenu": []
|
||||
"name": "登 出",
|
||||
"icon": "menu-icon tf-icons ri-logout-circle-line",
|
||||
"slug": "logout",
|
||||
"url": "admin/logout",
|
||||
"submenu": [
|
||||
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
326
resources/views/admin/dashboard/auth-register.blade.php
Normal file
326
resources/views/admin/dashboard/auth-register.blade.php
Normal file
@ -0,0 +1,326 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
|
||||
|
||||
<html lang="en" class="light-style layout-wide customizer-hide" dir="ltr" data-theme="theme-bordered" data-assets-path="{{asset('assets')}}/" data-template="vertical-menu-template-bordered" data-style="light">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
|
||||
|
||||
<title>卡菲姬後台註冊</title>
|
||||
<meta name="description" content="Materialize – is the most developer friendly & highly customizable Admin Dashboard Template." />
|
||||
<meta name="keywords" content="dashboard, material, material design, bootstrap 5 dashboard, bootstrap 5 design, bootstrap 5">
|
||||
<!-- laravel CRUD token -->
|
||||
<meta name="csrf-token" content="6fa8KEfKxuHo22PqMwHmCoxMDArqCNYyqRXJNZSE">
|
||||
<!-- Canonical SEO -->
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/x-icon" href="../../demo/assets/img/favicon/favicon.ico" />
|
||||
|
||||
|
||||
|
||||
<!-- ? PROD Only: Google Tag Manager (Default ThemeSelection: GTM-5DDHKGP, PixInvent: GTM-5J3LMKC) -->
|
||||
<script>
|
||||
(function(w, d, s, l, i) {
|
||||
w[l] = w[l] || [];
|
||||
w[l].push({
|
||||
'gtm.start': new Date().getTime()
|
||||
, event: 'gtm.js'
|
||||
});
|
||||
var f = d.getElementsByTagName(s)[0]
|
||||
, j = d.createElement(s)
|
||||
, dl = l != 'dataLayer' ? '&l=' + l : '';
|
||||
j.async = true;
|
||||
j.src =
|
||||
'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
|
||||
f.parentNode.insertBefore(j, f);
|
||||
})(window, document, 'script', 'dataLayer', 'GTM-5J3LMKC');
|
||||
|
||||
</script>
|
||||
<!-- End Google Tag Manager -->
|
||||
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/x-icon" href="{{asset('assets')}}/img/favicon/favicon.ico" />
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Icons -->
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/fonts/remixicon/remixicon.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/fonts/flag-icons.css" />
|
||||
|
||||
<!-- Menu waves for no-customizer fix -->
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/libs/node-waves/node-waves.css" />
|
||||
|
||||
<!-- Core CSS -->
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/css/rtl/core.css" class="template-customizer-core-css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/css/rtl/theme-bordered.css" class="template-customizer-theme-css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/css/demo.css" />
|
||||
|
||||
<!-- Vendors CSS -->
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/libs/perfect-scrollbar/perfect-scrollbar.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/libs/typeahead-js/typeahead.css" />
|
||||
<!-- Vendor -->
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/libs/@form-validation/form-validation.css" />
|
||||
|
||||
<!-- Page CSS -->
|
||||
<!-- Page -->
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/css/pages/page-auth.css">
|
||||
|
||||
<!-- Helpers -->
|
||||
<script src="{{asset('assets')}}/vendor/js/helpers.js"></script>
|
||||
<!--! Template customizer & Theme config files MUST be included after core stylesheets and helpers.js in the <head> section -->
|
||||
<!--? Template customizer: To hide customizer set displayCustomizer value false in config.js. -->
|
||||
<script src="{{asset('assets')}}/vendor/js/template-customizer.js"></script>
|
||||
<!--? Config: Mandatory theme config file contain global vars & default theme options, Set your preferred theme option in this file. -->
|
||||
<script src="{{asset('assets')}}/js/config.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<!-- ?PROD Only: Google Tag Manager (noscript) (Default ThemeSelection: GTM-5DDHKGP, PixInvent: GTM-5J3LMKC) -->
|
||||
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5J3LMKC" height="0" width="0" style="display: none; visibility: hidden"></iframe></noscript>
|
||||
<!-- End Google Tag Manager (noscript) -->
|
||||
|
||||
<!-- Content -->
|
||||
|
||||
<div class="position-relative">
|
||||
<div class="authentication-wrapper authentication-basic container-p-y p-4 p-sm-0">
|
||||
<div class="authentication-inner py-6">
|
||||
|
||||
<!-- Register Card -->
|
||||
<div class="card p-md-7 p-1">
|
||||
<!-- Logo -->
|
||||
<div class="app-brand justify-content-center mt-5">
|
||||
<a href="#" class="app-brand-link gap-2">
|
||||
<span class="app-brand-logo demo"><span>
|
||||
<img src="{{asset('assets/img/logo/cafeg-logo.png')}}" width="50px" height="50px" alt="{{asset('img/logo/cafeg-logo.png')}}"> </img>
|
||||
|
||||
</span>
|
||||
</span>
|
||||
<span class="app-brand-text demo text-heading fw-semibold">
|
||||
<img src="{{asset('assets/img/logo/cafeg-logo-h.png')}}" width="120px" height="50px" alt="{{asset('img/logo/cafeg-logo.png')}}"> </img>
|
||||
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<!-- /Logo -->
|
||||
<div class="card-body mt-1">
|
||||
<h4 class="mb-1">由此註冊後臺 🚀</h4>
|
||||
<p class="mb-5">您好 !管理者 請花幾分鐘註冊</p>
|
||||
|
||||
<form id="formAuthentication" class="mb-5" >
|
||||
@csrf
|
||||
<div class="form-floating form-floating-outline mb-5">
|
||||
<input type="text" class="form-control" id="username" name="name" placeholder="輸入你的稱呼" required>
|
||||
<label for="username">稱 呼</label>
|
||||
<div class="invalid-feedback">請輸入稱呼。</div>
|
||||
</div>
|
||||
<div class="form-floating form-floating-outline mb-5">
|
||||
<input type="email" class="form-control" id="email" name="email" placeholder="輸入你的帳號" required>
|
||||
<label for="email">Email(帳號)</label>
|
||||
<div class="invalid-feedback">請輸入有效的 Email 地址。</div>
|
||||
</div>
|
||||
<div class="mb-5 form-password-toggle">
|
||||
<div class="input-group input-group-merge">
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input type="password" id="password" class="form-control" name="password" placeholder="輸入密碼" required minlength="6">
|
||||
<label for="password">密碼</label>
|
||||
<div class="invalid-feedback">請輸入至少 6 個字符的密碼。</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-floating form-floating-outline mb-5">
|
||||
<input type="text" class="form-control" id="phone" name="phone" placeholder="輸入您的手機號" required pattern="^[0-9]{10}$">
|
||||
<label for="phone">手機號碼</label>
|
||||
<div class="invalid-feedback">請輸入有效的 10 位手機號碼。</div>
|
||||
</div>
|
||||
<div class="mb-5">
|
||||
<div class="form-check mt-2">
|
||||
<input class="form-check-input" type="checkbox" id="terms-conditions" name="terms" required>
|
||||
<label class="form-check-label" for="terms-conditions">
|
||||
我同意
|
||||
<a href="javascript:void(0);">隱私權政策和條款</a>
|
||||
</label>
|
||||
<div class="invalid-feedback">請同意條款。</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary d-grid w-100">
|
||||
註冊
|
||||
</button>
|
||||
</form>
|
||||
|
||||
|
||||
<p class="text-center">
|
||||
<span>已經有帳號?</span>
|
||||
<a href="{{route('admin.login')}}" class="text-body">
|
||||
<span>由此登入</span>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<div class="divider my-5">
|
||||
<div class="divider-text">or</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-center gap-2">
|
||||
<a href="{{route('admin.login.line')}}" class="btn btn-icon rounded-circle btn-text-facebook">
|
||||
<i class="tf-icons ri-line-fill"></i>
|
||||
</a>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Register Card -->
|
||||
<img alt="mask" src="{{asset('assets')}}/img/illustrations/auth-basic-register-mask-light.png" class="authentication-image d-none d-lg-block" data-app-light-img="illustrations/auth-basic-register-mask-light.png" data-app-dark-img="illustrations/auth-basic-register-mask-dark.png" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- / Content -->
|
||||
|
||||
{{--
|
||||
<div class="buy-now">
|
||||
<a href="https://1.envato.market/materialize_admin" target="_blank" class="btn btn-danger btn-buy-now">Buy Now</a>
|
||||
</div>
|
||||
--}}
|
||||
|
||||
|
||||
|
||||
<!-- Core JS -->
|
||||
<!-- build:js assets/vendor/js/core.js -->
|
||||
<script src="{{asset('assets')}}/vendor/libs/jquery/jquery.js"></script>
|
||||
<script src="{{asset('assets')}}/vendor/libs/popper/popper.js"></script>
|
||||
<script src="{{asset('assets')}}/vendor/js/bootstrap.js"></script>
|
||||
<script src="{{asset('assets')}}/vendor/libs/node-waves/node-waves.js"></script>
|
||||
<script src="{{asset('assets')}}/vendor/libs/perfect-scrollbar/perfect-scrollbar.js"></script>
|
||||
<script src="{{asset('assets')}}/vendor/libs/hammer/hammer.js"></script>
|
||||
<script src="{{asset('assets')}}/vendor/libs/i18n/i18n.js"></script>
|
||||
<script src="{{asset('assets')}}/vendor/libs/typeahead-js/typeahead.js"></script>
|
||||
<script src="{{asset('assets')}}/vendor/js/menu.js"></script>
|
||||
|
||||
<!-- endbuild -->
|
||||
|
||||
<!-- Vendors JS -->
|
||||
<script src="{{asset('assets')}}/vendor/libs/@form-validation/popular.js"></script>
|
||||
<script src="{{asset('assets')}}/vendor/libs/@form-validation/bootstrap5.js"></script>
|
||||
<script src="{{asset('assets')}}/vendor/libs/@form-validation/auto-focus.js"></script>
|
||||
|
||||
<!-- Main JS -->
|
||||
<script src="{{asset('assets')}}/js/main.js"></script>
|
||||
|
||||
|
||||
<!-- Page JS -->
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// 驗證邏輯函數
|
||||
function validateField(field) {
|
||||
console.log('load');
|
||||
const id = field.attr('id');
|
||||
const value = field.val().trim();
|
||||
let isValid = true;
|
||||
let errorMsg = '';
|
||||
|
||||
if (id === 'username') {
|
||||
if (!value) {
|
||||
isValid = false;
|
||||
errorMsg = '請輸入稱呼。';
|
||||
}
|
||||
} else if (id === 'email') {
|
||||
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
if (!emailPattern.test(value)) {
|
||||
isValid = false;
|
||||
errorMsg = '請輸入有效的 Email 地址。';
|
||||
}
|
||||
} else if (id === 'password') {
|
||||
if (value.length < 6) {
|
||||
isValid = false;
|
||||
errorMsg = '密碼至少需要 6 個字符。';
|
||||
}
|
||||
} else if (id === 'phone') {
|
||||
const phonePattern = /^[0-9]{10}$/;
|
||||
if (!phonePattern.test(value)) {
|
||||
isValid = false;
|
||||
errorMsg = '請輸入有效的 10 位手機號碼。';
|
||||
}
|
||||
}
|
||||
|
||||
if (isValid) {
|
||||
field.removeClass('is-invalid');
|
||||
field.next('.invalid-feedback').hide();
|
||||
} else {
|
||||
field.addClass('is-invalid');
|
||||
if (field.next('.invalid-feedback').length) {
|
||||
field.next('.invalid-feedback').text(errorMsg).show();
|
||||
}
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
// 每個輸入框綁定失焦事件
|
||||
$('#formAuthentication input').on('blur', function() {
|
||||
validateField($(this));
|
||||
});
|
||||
|
||||
// 表單提交事件
|
||||
$('#formAuthentication').on('submit', function(event) {
|
||||
event.preventDefault(); // 阻止表單自動提交
|
||||
|
||||
let isFormValid = true;
|
||||
|
||||
// 驗證所有字段
|
||||
$('#formAuthentication input').each(function() {
|
||||
if (!validateField($(this))) {
|
||||
isFormValid = false;
|
||||
}
|
||||
});
|
||||
|
||||
// 如果表單有效,使用 AJAX 提交
|
||||
if (isFormValid) {
|
||||
$.ajax({
|
||||
url: "{{ route('admin.register.create') }}",
|
||||
type: 'POST',
|
||||
data: $(this).serialize(),
|
||||
success: function(response) {
|
||||
Swal.fire({
|
||||
title: '成功',
|
||||
text: '註冊成功',
|
||||
icon: 'success',
|
||||
confirmButtonText: '確定'
|
||||
}).then(() => {
|
||||
window.location.href = "{{ route('admin.index') }}";
|
||||
});
|
||||
},
|
||||
error: function(error) {
|
||||
Swal.fire({
|
||||
title: '失敗',
|
||||
text: '註冊失敗,請再試一次。',
|
||||
icon: 'error',
|
||||
confirmButtonText: '確定'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
||||
|
||||
</script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
|
||||
<!-- beautify ignore:end -->
|
||||
|
||||
|
||||
<script>
|
||||
</script>
|
||||
27
resources/views/admin/dashboard/index.blade.php
Normal file
27
resources/views/admin/dashboard/index.blade.php
Normal file
@ -0,0 +1,27 @@
|
||||
@extends('layouts.admin_app')
|
||||
@section('header')
|
||||
@endsection
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card-body">
|
||||
<!-- Basic Breadcrumb -->
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="javascript:void(0);">Home</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item">
|
||||
<a href="javascript:void(0);">Library</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active">Data</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
@endsection
|
||||
@section('scripts')
|
||||
@endsection
|
||||
435
resources/views/admin/dashboard/profile.blade.php
Normal file
435
resources/views/admin/dashboard/profile.blade.php
Normal file
@ -0,0 +1,435 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en" class="dark-style layout-menu-fixed customizer-hide" dir="ltr" data-theme="theme-default" data-assets-path="https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo/assets/" data-base-url="https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo-4" data-framework="laravel" data-template="blank-menu-theme-default-dark" data-style="dark">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
|
||||
|
||||
<title>卡菲姬後台登入</title>
|
||||
<meta name="description" content="Materialize – is the most developer friendly & highly customizable Admin Dashboard Template." />
|
||||
<meta name="keywords" content="dashboard, material, material design, bootstrap 5 dashboard, bootstrap 5 design, bootstrap 5">
|
||||
<!-- laravel CRUD token -->
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
|
||||
<!-- Canonical SEO -->
|
||||
<link rel="canonical" href="https://1.envato.market/materialize_admin">
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/x-icon" href="../../demo/assets/img/favicon/favicon.ico" />
|
||||
|
||||
|
||||
<!-- Include Styles -->
|
||||
<!-- $isFront is used to append the front layout styles only on the front layout otherwise the variable will be blank -->
|
||||
<!-- BEGIN: Theme CSS-->
|
||||
<!-- Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/fonts/remixicon/remixicon.css" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/fonts/flag-icons.css" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/libs/node-waves/node-waves.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/fonts/remixicon/remixicon.css" class="" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/fonts/flag-icons.css" class="" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/libs/node-waves/node-waves.css" class="" />
|
||||
<!-- Core CSS -->
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/css/core-dark.css" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/css/theme-default-dark.css" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/css/demo.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/css/core-dark.css" class="template-customizer-core-css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/css/theme-default-dark.css" class="template-customizer-theme-css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/css/demo.css" class="" />
|
||||
|
||||
<!-- Vendor Styles -->
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/libs/perfect-scrollbar/perfect-scrollbar.css" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/libs/typeahead-js/typeahead.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/libs/perfect-scrollbar/perfect-scrollbar.css" class="" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/libs/typeahead-js/typeahead.css" class="" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/libs/@form-validation/form-validation.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/libs/@form-validation/form-validation.css" class="" />
|
||||
<!-- Page Styles -->
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/css/pages/page-auth.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/css/pages/page-auth.css" class="" />
|
||||
<!-- Include Scripts for customizer, helper, analytics, config -->
|
||||
<!-- $isFront is used to append the front layout scriptsIncludes only on the front layout otherwise the variable will be blank -->
|
||||
<!-- laravel style -->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/helpers.js" />
|
||||
<script type="module" src="{{asset('assets')}}/vendor/js/helpers.js"></script>
|
||||
<!-- beautify ignore:start -->
|
||||
<!--! Template customizer & Theme config files MUST be included after core stylesheets and helpers.js in the <head> section -->
|
||||
<!--? Template customizer: To hide customizer set displayCustomizer value false in config.js. -->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/template-customizer.js" />
|
||||
<!--? Config: Mandatory theme config file contain global vars & default theme options, Set your preferred theme option in this file. -->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/js/config.js" /><script type="module" src="{{asset('assets')}}/js/config.js"></script>
|
||||
<script type="module">
|
||||
window.templateCustomizer = new TemplateCustomizer({
|
||||
cssPath: '',
|
||||
themesPath: '',
|
||||
defaultStyle: "dark",
|
||||
defaultShowDropdownOnHover: "1", // true/false (for horizontal layout only)
|
||||
displayCustomizer: "1",
|
||||
lang: 'en',
|
||||
pathResolver: function(path) {
|
||||
var resolvedPaths = {
|
||||
// Core stylesheets
|
||||
'core.scss': 'https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo/build/assets/core-kL5gEEKA.css',
|
||||
'core-dark.scss': 'https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo/build/assets/core-dark-DFvmi5J3.css',
|
||||
|
||||
// Themes
|
||||
'theme-default.scss': 'https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo/build/assets/theme-default-Bt2z4DrM.css',
|
||||
'theme-default-dark.scss': 'https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo/build/assets/theme-default-dark-CHvAJUy2.css',
|
||||
'theme-bordered.scss': 'https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo/build/assets/theme-bordered-DhjhTV9k.css',
|
||||
'theme-bordered-dark.scss': 'https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo/build/assets/theme-bordered-dark-C25VfhpZ.css',
|
||||
'theme-semi-dark.scss': 'https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo/build/assets/theme-semi-dark-D80v88qZ.css',
|
||||
'theme-semi-dark-dark.scss': 'https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo/build/assets/theme-semi-dark-dark-BZrM7P_B.css',
|
||||
}
|
||||
return resolvedPaths[path] || path;
|
||||
},
|
||||
'controls': ["rtl","style","headerType","contentLayout","layoutCollapsed","layoutNavbarOptions","themes"],
|
||||
});
|
||||
</script>
|
||||
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-5J3LMKC'); </script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5J3LMKC" height="0" width="0" style="display: none; visibility: hidden"></iframe></noscript>
|
||||
|
||||
<!-- Layout Content -->
|
||||
|
||||
<!-- Content -->
|
||||
<div class="position-relative">
|
||||
<div class="authentication-wrapper authentication-basic container-p-y p-4 p-sm-0">
|
||||
<div class="authentication-inner py-6">
|
||||
|
||||
<!-- Login -->
|
||||
<div class="card p-md-7 p-1">
|
||||
<!-- Logo -->
|
||||
<div class="app-brand justify-content-center mt-5">
|
||||
<a href="#" class="app-brand-link gap-2">
|
||||
<span class="app-brand-logo demo"><span>
|
||||
<img src="{{asset('assets/img/logo/cafeg-logo.png')}}" width="50px" height="50px" alt="{{asset('img/logo/cafeg-logo.png')}}"> </img>
|
||||
|
||||
</span>
|
||||
</span>
|
||||
<span class="app-brand-text demo text-heading fw-semibold">
|
||||
<img src="{{asset('assets/img/logo/cafeg-logo-h.png')}}" width="120px" height="50px" alt="{{asset('img/logo/cafeg-logo.png')}}"> </img>
|
||||
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<!-- /Logo -->
|
||||
|
||||
<div class="card-body mt-1">
|
||||
<h4 class="mb-1">卡菲姬個人資料</h4>
|
||||
<p class="mb-5">Hi, <span class="text-ifno"> {{$data->name }} 管理者 </span> 歡迎你 ! ,請花幾分鐘完善資料</p>
|
||||
|
||||
<div class="card" id="editUser">
|
||||
<div class="content">
|
||||
<div class="body p-0">
|
||||
<div class="text-center mb-6">
|
||||
<h4 class="mb-2">編輯您的資訊</h4>
|
||||
<p class="mb-6">更新用戶詳細資訊</p>
|
||||
</div>
|
||||
<form id="editUserForm" class="row g-5" >
|
||||
<!-- 暱稱 -->
|
||||
<div class="col-12">
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input
|
||||
readonly
|
||||
type="text"
|
||||
id="modalEditUserFirstName"
|
||||
name="modalEditUserFirstName"
|
||||
class="form-control"
|
||||
value="{{$data->name}}"
|
||||
placeholder="暱稱"
|
||||
aria-label="暱稱"
|
||||
/>
|
||||
<label for="modalEditUserFirstName">暱稱</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Email -->
|
||||
<div class="col-12">
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input
|
||||
type="email"
|
||||
id="formValidationEmail"
|
||||
class="form-control"
|
||||
placeholder="john.doe@example.com"
|
||||
aria-label="Email"
|
||||
required
|
||||
value="{{$data->email ?? ''}}"
|
||||
|
||||
/>
|
||||
<label for="formValidationEmail">Email</label>
|
||||
<div class="invalid-feedback">請輸入有效的 Email</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 密碼 -->
|
||||
<div class="col-12">
|
||||
<div class="form-password-toggle">
|
||||
<div class="input-group input-group-merge">
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input
|
||||
type="password"
|
||||
id="basic-default-password"
|
||||
class="form-control"
|
||||
placeholder="密碼"
|
||||
aria-label="密碼"
|
||||
value="{{$data->password ?? ''}}"
|
||||
|
||||
/>
|
||||
<label for="basic-default-password">密碼</label>
|
||||
<div class="invalid-feedback">請輸入有效密碼</div>
|
||||
|
||||
</div>
|
||||
<span
|
||||
class="input-group-text cursor-pointer"
|
||||
id="basic-default-password3"
|
||||
>
|
||||
<i class="ri-eye-off-line"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 確認密碼 -->
|
||||
<div class="col-12">
|
||||
<div class="form-password-toggle">
|
||||
<div class="input-group input-group-merge">
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input
|
||||
type="password"
|
||||
id="formValidationConfirmPass"
|
||||
name="formValidationConfirmPass"
|
||||
class="form-control"
|
||||
placeholder="確認密碼"
|
||||
aria-label="確認密碼"
|
||||
value="{{$data->password ?? ''}}"
|
||||
|
||||
/>
|
||||
<label for="formValidationConfirmPass">確認密碼</label>
|
||||
<div class="invalid-feedback">密碼與確認密碼不相符</div>
|
||||
|
||||
</div>
|
||||
<span
|
||||
class="input-group-text cursor-pointer"
|
||||
id="multicol-confirm-password2"
|
||||
>
|
||||
<i class="ri-eye-off-line"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 電話 -->
|
||||
<div class="col-12">
|
||||
<div class="input-group input-group-merge">
|
||||
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input
|
||||
type="text"
|
||||
id="modalEditUserPhone"
|
||||
name="modalEditUserPhone"
|
||||
class="form-control phone-number-mask"
|
||||
value="{{$data->phone ?? ''}}"
|
||||
placeholder="0920111222"
|
||||
aria-label="電話"
|
||||
/>
|
||||
<label for="modalEditUserPhone">電話</label>
|
||||
<div class="invalid-feedback">請輸入有效電話</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 按鈕 -->
|
||||
<div
|
||||
class="col-12 text-center d-flex flex-wrap justify-content-center gap-4 row-gap-4"
|
||||
|
||||
>
|
||||
<button type="submit" class="btn btn-primary">送出</button>
|
||||
<button
|
||||
type="reset"
|
||||
class="btn btn-outline-secondary"
|
||||
data-bs-dismiss="modal"
|
||||
aria-label="Close"
|
||||
>
|
||||
取消
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{{-- <p class="text-center">
|
||||
<span>新的裝置?</span>
|
||||
<a href="register-basic.html">
|
||||
<span>創建新的帳號</span>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<div class="divider my-5">
|
||||
<div class="divider-text">或</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-center gap-2">
|
||||
|
||||
<a href="{{route('admin.login.line')}}" class="btn btn-icon rounded-circle btn-text-line">
|
||||
<i class="tf-icons ri-line-fill"></i>
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="javascript:;" class="btn btn-icon rounded-circle btn-text-google-plus">
|
||||
<i class="tf-icons ri-google-fill"></i>
|
||||
</a> --}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /Login -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--/ Content -->
|
||||
|
||||
<!--/ Layout Content -->
|
||||
|
||||
|
||||
{{-- <div class="buy-now">
|
||||
<a href="#" target="" class="btn btn-danger btn-buy-now">Buy Now</a>
|
||||
</div> --}}
|
||||
|
||||
|
||||
<!-- Include Scripts -->
|
||||
<!-- $isFront is used to append the front layout scripts only on the front layout otherwise the variable will be blank -->
|
||||
<!-- BEGIN: Vendor JS-->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/jquery/jquery.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/helpers.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/popper/popper.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/bootstrap.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/node-waves/node-waves.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/perfect-scrollbar/perfect-scrollbar.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/hammer/hammer.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/typeahead-js/typeahead.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/menu.js" />
|
||||
<script type="module" src="{{asset('assets')}}/vendor/libs/jquery/jquery.js"></script>
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/@form-validation/popular.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/helpers.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/@form-validation/bootstrap5.js" />
|
||||
{{-- <link rel="modulepreload" href="{{asset('assets')}}/index.js" /> --}}
|
||||
{{-- <link rel="modulepreload" href="{{asset('assets')}}/auto.js" /> --}}
|
||||
<script type="module" src="{{asset('assets')}}/vendor/libs/@form-validation/popular.js">
|
||||
</script><script type="module" src="{{asset('assets')}}/vendor/libs/@form-validation/bootstrap5.js"></script>
|
||||
<script type="module" src="{{asset('assets')}}/vendor/libs/@form-validation/auto-focus.js"></script>
|
||||
<!-- END: Page Vendor JS-->
|
||||
<!-- BEGIN: Theme JS-->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/js/main.js" />
|
||||
<script type="module" src="{{asset('assets')}}/js/main.js"></script>
|
||||
<!-- END: Theme JS-->
|
||||
<!-- Pricing Modal JS-->
|
||||
<!-- END: Pricing Modal JS-->
|
||||
<!-- BEGIN: Page JS-->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/js/pages-auth.js" />
|
||||
<script type="module" src="{{asset('assets')}}/js/pages-auth.js"></script>
|
||||
<!-- END: Page JS-->
|
||||
<script src="{{asset('assets')}}/js/form-validation.js"></script>
|
||||
|
||||
</body>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$('#editUserForm').on('submit', function (e) {
|
||||
e.preventDefault(); // 防止表單提交
|
||||
|
||||
let valid = true;
|
||||
|
||||
// Email 驗證
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
const emailInput = $('#formValidationEmail');
|
||||
if (!emailRegex.test(emailInput.val())) {
|
||||
valid = false;
|
||||
emailInput.addClass('is-invalid');
|
||||
} else {
|
||||
emailInput.removeClass('is-invalid');
|
||||
}
|
||||
|
||||
// 密碼長度驗證
|
||||
const passwordInput = $('#basic-default-password');
|
||||
//if (passwordInput.val().length < 6) {
|
||||
// valid = false;
|
||||
//passwordInput.addClass('is-invalid');
|
||||
//} else {
|
||||
// passwordInput.removeClass('is-invalid');
|
||||
//}
|
||||
|
||||
// 確認密碼驗證
|
||||
const confirmPasswordInput = $('#formValidationConfirmPass');
|
||||
if (passwordInput.val() !== confirmPasswordInput.val()) {
|
||||
valid = false;
|
||||
confirmPasswordInput.addClass('is-invalid');
|
||||
} else {
|
||||
confirmPasswordInput.removeClass('is-invalid');
|
||||
}
|
||||
|
||||
// 手機號碼驗證
|
||||
const phoneRegex = /^09\d{8}$/;
|
||||
const phoneInput = $('#modalEditUserPhone');
|
||||
if (!phoneRegex.test(phoneInput.val())) {
|
||||
valid = false;
|
||||
phoneInput.addClass('is-invalid');
|
||||
} else {
|
||||
phoneInput.removeClass('is-invalid');
|
||||
}
|
||||
|
||||
// 若通過所有驗證,發送 AJAX 請求
|
||||
if (valid) {
|
||||
const formData = {
|
||||
email: emailInput.val(),
|
||||
password: passwordInput.val(),
|
||||
phone: phoneInput.val(),
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
url: "{{ route('admin.profile.update') }}",
|
||||
type: 'put',
|
||||
data: formData,
|
||||
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') },
|
||||
success: function (response) {
|
||||
Swal.fire({
|
||||
title: '成功'
|
||||
, text: "{{ session('success') }}"
|
||||
, icon: 'success'
|
||||
, confirmButtonText: '确定'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
// 跳轉到 admin.index 路由
|
||||
window.location.href = "{{ route('admin.index') }}";
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
},
|
||||
error: function (error) {
|
||||
Swal.fire({
|
||||
title: '失敗'
|
||||
, text: "更新失敗"
|
||||
, icon: 'error'
|
||||
, confirmButtonText: '确定'
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
|
||||
</html>
|
||||
@ -3,46 +3,62 @@
|
||||
<html lang="de" class="dark-style layout-menu-fixed customizer-hide" dir="ltr" data-theme="theme-default" data-assets-path="https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo/assets/" data-base-url="https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo-4" data-framework="laravel" data-template="blank-menu-theme-default-dark" data-style="dark">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
|
||||
|
||||
<title>Login Basic - Pages |
|
||||
Materialize -
|
||||
Materialize - Bootstrap 5 HTML Laravel Admin Template</title>
|
||||
<meta name="description" content="Materialize – is the most developer friendly & highly customizable Admin Dashboard Template." />
|
||||
<meta name="keywords" content="dashboard, material, material design, bootstrap 5 dashboard, bootstrap 5 design, bootstrap 5">
|
||||
<!-- laravel CRUD token -->
|
||||
<meta name="csrf-token" content="6fa8KEfKxuHo22PqMwHmCoxMDArqCNYyqRXJNZSE">
|
||||
<!-- Canonical SEO -->
|
||||
<link rel="canonical" href="https://1.envato.market/materialize_admin">
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/x-icon" href="../../demo/assets/img/favicon/favicon.ico" />
|
||||
<title>卡菲姬後台登入</title>
|
||||
<meta name="description" content="Materialize – is the most developer friendly & highly customizable Admin Dashboard Template." />
|
||||
<meta name="keywords" content="dashboard, material, material design, bootstrap 5 dashboard, bootstrap 5 design, bootstrap 5">
|
||||
<!-- laravel CRUD token -->
|
||||
<meta name="csrf-token" content="6fa8KEfKxuHo22PqMwHmCoxMDArqCNYyqRXJNZSE">
|
||||
<!-- Canonical SEO -->
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/x-icon" href="../../demo/assets/img/favicon/favicon.ico" />
|
||||
|
||||
|
||||
<!-- Include Styles -->
|
||||
<!-- $isFront is used to append the front layout styles only on the front layout otherwise the variable will be blank -->
|
||||
<!-- BEGIN: Theme CSS-->
|
||||
<!-- Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
<!-- Include Styles -->
|
||||
<!-- $isFront is used to append the front layout styles only on the front layout otherwise the variable will be blank -->
|
||||
<!-- BEGIN: Theme CSS-->
|
||||
<!-- Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<link rel="preload" as="style" href="../../demo/build/assets/remixicon-CvKjKgNI.css" /><link rel="preload" as="style" href="../../demo/build/assets/flag-icons-3vmHO8jy.css" /><link rel="preload" as="style" href="../../demo/build/assets/node-waves-D5r9FyLK.css" /><link rel="stylesheet" href="../../demo/build/assets/remixicon-CvKjKgNI.css" class="" /><link rel="stylesheet" href="../../demo/build/assets/flag-icons-3vmHO8jy.css" class="" /><link rel="stylesheet" href="../../demo/build/assets/node-waves-D5r9FyLK.css" class="" /><!-- Core CSS -->
|
||||
<link rel="preload" as="style" href="../../demo/build/assets/core-dark-DFvmi5J3.css" /><link rel="preload" as="style" href="../../demo/build/assets/theme-default-dark-CHvAJUy2.css" /><link rel="preload" as="style" href="../../demo/build/assets/demo-CQni_ElP.css" /><link rel="stylesheet" href="../../demo/build/assets/core-dark-DFvmi5J3.css" class="template-customizer-core-css" /><link rel="stylesheet" href="../../demo/build/assets/theme-default-dark-CHvAJUy2.css" class="template-customizer-theme-css" /><link rel="stylesheet" href="../../demo/build/assets/demo-CQni_ElP.css" class="" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/fonts/remixicon/remixicon.css" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/fonts/flag-icons.css" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/libs/node-waves/node-waves.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/fonts/remixicon/remixicon.css" class="" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/fonts/flag-icons.css" class="" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/libs/node-waves/node-waves.css" class="" />
|
||||
<!-- Core CSS -->
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/css/core-dark.css" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/css/theme-default-dark.css" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/css/demo.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/css/core-dark.css" class="template-customizer-core-css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/css/theme-default-dark.css" class="template-customizer-theme-css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/css/demo.css" class="" />
|
||||
|
||||
<!-- Vendor Styles -->
|
||||
<link rel="preload" as="style" href="../../demo/build/assets/perfect-scrollbar-Pb48Lfqx.css" /><link rel="preload" as="style" href="../../demo/build/assets/typeahead-CL05AX6P.css" /><link rel="stylesheet" href="../../demo/build/assets/perfect-scrollbar-Pb48Lfqx.css" class="" /><link rel="stylesheet" href="../../demo/build/assets/typeahead-CL05AX6P.css" class="" /><link rel="preload" as="style" href="../../demo/build/assets/form-validation-Z40eMZE8.css" /><link rel="stylesheet" href="../../demo/build/assets/form-validation-Z40eMZE8.css" class="" />
|
||||
<!-- Page Styles -->
|
||||
<link rel="preload" as="style" href="../../demo/build/assets/page-auth-Do3xZciJ.css" /><link rel="stylesheet" href="../../demo/build/assets/page-auth-Do3xZciJ.css" class="" />
|
||||
<!-- Include Scripts for customizer, helper, analytics, config -->
|
||||
<!-- $isFront is used to append the front layout scriptsIncludes only on the front layout otherwise the variable will be blank -->
|
||||
<!-- laravel style -->
|
||||
<link rel="modulepreload" href="../../demo/build/assets/helpers-B9_VIWCr.js" /><script type="module" src="../../demo/build/assets/helpers-B9_VIWCr.js"></script><!-- beautify ignore:start -->
|
||||
<!-- Vendor Styles -->
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/libs/perfect-scrollbar/perfect-scrollbar.css" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/libs/typeahead-js/typeahead.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/libs/perfect-scrollbar/perfect-scrollbar.css" class="" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/libs/typeahead-js/typeahead.css" class="" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/libs/@form-validation/form-validation.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/libs/@form-validation/form-validation.css" class="" />
|
||||
<!-- Page Styles -->
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/css/pages/page-auth.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/css/pages/page-auth.css" class="" />
|
||||
<!-- Include Scripts for customizer, helper, analytics, config -->
|
||||
<!-- $isFront is used to append the front layout scriptsIncludes only on the front layout otherwise the variable will be blank -->
|
||||
<!-- laravel style -->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/helpers.js" />
|
||||
<script type="module" src="{{asset('assets')}}/vendor/js/helpers.js"></script>
|
||||
<!-- beautify ignore:start -->
|
||||
<!--! Template customizer & Theme config files MUST be included after core stylesheets and helpers.js in the <head> section -->
|
||||
<!--? Template customizer: To hide customizer set displayCustomizer value false in config.js. -->
|
||||
<link rel="preload" as="style" href="../../demo/build/assets/template-customizer-C6tl466J.css" /><link rel="modulepreload" href="../../demo/build/assets/template-customizer-C9zWc80S.js" /><link rel="stylesheet" href="../../demo/build/assets/template-customizer-C6tl466J.css" /><script type="module" src="../../demo/build/assets/template-customizer-C9zWc80S.js"></script>
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/template-customizer.js" />
|
||||
<!--? Config: Mandatory theme config file contain global vars & default theme options, Set your preferred theme option in this file. -->
|
||||
<link rel="modulepreload" href="../../demo/build/assets/config-BpWx43Hd.js" /><script type="module" src="../../demo/build/assets/config-BpWx43Hd.js"></script>
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/js/config.js" /><script type="module" src="{{asset('assets')}}/js/config.js"></script>
|
||||
<script type="module">
|
||||
window.templateCustomizer = new TemplateCustomizer({
|
||||
cssPath: '',
|
||||
@ -50,7 +66,7 @@
|
||||
defaultStyle: "dark",
|
||||
defaultShowDropdownOnHover: "1", // true/false (for horizontal layout only)
|
||||
displayCustomizer: "1",
|
||||
lang: 'de',
|
||||
lang: 'en',
|
||||
pathResolver: function(path) {
|
||||
var resolvedPaths = {
|
||||
// Core stylesheets
|
||||
@ -87,48 +103,36 @@
|
||||
<div class="card p-md-7 p-1">
|
||||
<!-- Logo -->
|
||||
<div class="app-brand justify-content-center mt-5">
|
||||
<a href="../../demo-4.html" class="app-brand-link gap-2">
|
||||
<a href="#" class="app-brand-link gap-2">
|
||||
<span class="app-brand-logo demo"><span>
|
||||
<svg width="25" viewBox="0 0 38 20" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M30.0944 2.22569C29.0511 0.444187 26.7508 -0.172113 24.9566 0.849138C23.1623 1.87039 22.5536 4.14247 23.5969 5.92397L30.5368 17.7743C31.5801 19.5558 33.8804 20.1721 35.6746 19.1509C37.4689 18.1296 38.0776 15.8575 37.0343 14.076L30.0944 2.22569Z" fill="var(--bs-primary)" />
|
||||
<path d="M30.171 2.22569C29.1277 0.444187 26.8274 -0.172113 25.0332 0.849138C23.2389 1.87039 22.6302 4.14247 23.6735 5.92397L30.6134 17.7743C31.6567 19.5558 33.957 20.1721 35.7512 19.1509C37.5455 18.1296 38.1542 15.8575 37.1109 14.076L30.171 2.22569Z" fill="url(#paint0_linear_2989_100980)" fill-opacity="0.4" />
|
||||
<path d="M22.9676 2.22569C24.0109 0.444187 26.3112 -0.172113 28.1054 0.849138C29.8996 1.87039 30.5084 4.14247 29.4651 5.92397L22.5251 17.7743C21.4818 19.5558 19.1816 20.1721 17.3873 19.1509C15.5931 18.1296 14.9843 15.8575 16.0276 14.076L22.9676 2.22569Z" fill="var(--bs-primary)" />
|
||||
<path d="M14.9558 2.22569C13.9125 0.444187 11.6122 -0.172113 9.818 0.849138C8.02377 1.87039 7.41502 4.14247 8.45833 5.92397L15.3983 17.7743C16.4416 19.5558 18.7418 20.1721 20.5361 19.1509C22.3303 18.1296 22.9391 15.8575 21.8958 14.076L14.9558 2.22569Z" fill="var(--bs-primary)" />
|
||||
<path d="M14.9558 2.22569C13.9125 0.444187 11.6122 -0.172113 9.818 0.849138C8.02377 1.87039 7.41502 4.14247 8.45833 5.92397L15.3983 17.7743C16.4416 19.5558 18.7418 20.1721 20.5361 19.1509C22.3303 18.1296 22.9391 15.8575 21.8958 14.076L14.9558 2.22569Z" fill="url(#paint1_linear_2989_100980)" fill-opacity="0.4" />
|
||||
<path d="M7.82901 2.22569C8.87231 0.444187 11.1726 -0.172113 12.9668 0.849138C14.7611 1.87039 15.3698 4.14247 14.3265 5.92397L7.38656 17.7743C6.34325 19.5558 4.04298 20.1721 2.24875 19.1509C0.454514 18.1296 -0.154233 15.8575 0.88907 14.076L7.82901 2.22569Z" fill="var(--bs-primary)" />
|
||||
<defs>
|
||||
<linearGradient id="paint0_linear_2989_100980" x1="5.36642" y1="0.849138" x2="10.532" y2="24.104" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-opacity="1" />
|
||||
<stop offset="1" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_2989_100980" x1="5.19475" y1="0.849139" x2="10.3357" y2="24.1155" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-opacity="1" />
|
||||
<stop offset="1" stop-opacity="0" />
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
<img src="{{asset('assets/img/logo/cafeg-logo.png')}}" width="50px" height="50px" alt="{{asset('img/logo/cafeg-logo.png')}}"> </img>
|
||||
|
||||
</span>
|
||||
</span>
|
||||
<span class="app-brand-text demo text-heading fw-semibold">Materialize</span>
|
||||
<span class="app-brand-text demo text-heading fw-semibold">
|
||||
<img src="{{asset('assets/img/logo/cafeg-logo-h.png')}}" width="120px" height="50px" alt="{{asset('img/logo/cafeg-logo.png')}}"> </img>
|
||||
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<!-- /Logo -->
|
||||
|
||||
<div class="card-body mt-1">
|
||||
<h4 class="mb-1">Welcome to Materialize! 👋</h4>
|
||||
<p class="mb-5">Please sign-in to your account and start the adventure</p>
|
||||
<h4 class="mb-1">卡菲姬後台管理</h4>
|
||||
<p class="mb-5">Hi, Admin 歡迎你 !</p>
|
||||
|
||||
<form id="formAuthentication" class="mb-5" action="../../demo-4.html" method="GET">
|
||||
<form id="formAuthentication" class="mb-5" action="{{route('admin.login.post')}}" method="POST">
|
||||
@csrf
|
||||
<div class="form-floating form-floating-outline mb-5">
|
||||
<input type="text" class="form-control" id="email" name="email-username" placeholder="Enter your email or username" autofocus>
|
||||
<label for="email">Email or Username</label>
|
||||
<input type="text" class="form-control" id="email" name="email" placeholder="請填寫您的電子郵件" autofocus>
|
||||
<label for="email">電子郵件</label>
|
||||
</div>
|
||||
<div class="mb-5">
|
||||
<div class="form-password-toggle">
|
||||
<div class="input-group input-group-merge">
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input type="password" id="password" class="form-control" name="password" placeholder="············" aria-describedby="password" />
|
||||
<label for="password">Password</label>
|
||||
<label for="password">密碼</label>
|
||||
</div>
|
||||
<span class="input-group-text cursor-pointer"><i class="ri-eye-off-line"></i></span>
|
||||
</div>
|
||||
@ -136,13 +140,13 @@
|
||||
</div>
|
||||
<div class="mb-5 d-flex justify-content-between mt-5">
|
||||
<div class="form-check mt-2">
|
||||
<input class="form-check-input" type="checkbox" id="remember-me">
|
||||
<input class="form-check-input" type="checkbox" id="remember-me" name="remember-me">
|
||||
<label class="form-check-label" for="remember-me">
|
||||
Remember Me
|
||||
記住 我
|
||||
</label>
|
||||
</div>
|
||||
<a href="forgot-password-basic.html" class="float-end mb-1 mt-2">
|
||||
<span>Forgot Password?</span>
|
||||
<span>忘記密碼?</span>
|
||||
</a>
|
||||
</div>
|
||||
<div class="mb-5">
|
||||
@ -151,37 +155,32 @@
|
||||
</form>
|
||||
|
||||
<p class="text-center">
|
||||
<span>New on our platform?</span>
|
||||
<a href="register-basic.html">
|
||||
<span>Create an account</span>
|
||||
<span>新的裝置?</span>
|
||||
<a href="{{route('admin.register')}}" class="text-body">
|
||||
<span>創建新的帳號</span>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<div class="divider my-5">
|
||||
<div class="divider-text">or</div>
|
||||
<div class="divider-text">或</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-center gap-2">
|
||||
<a href="javascript:;" class="btn btn-icon rounded-circle btn-text-facebook">
|
||||
<i class="tf-icons ri-facebook-fill"></i>
|
||||
|
||||
<a href="{{route('admin.login.line')}}" class="btn btn-icon rounded-circle btn-text-line">
|
||||
<i class="tf-icons ri-line-fill"></i>
|
||||
</a>
|
||||
|
||||
|
||||
<a href="javascript:;" class="btn btn-icon rounded-circle btn-text-twitter">
|
||||
<i class="tf-icons ri-twitter-fill"></i>
|
||||
</a>
|
||||
|
||||
|
||||
<a href="javascript:;" class="btn btn-icon rounded-circle btn-text-github">
|
||||
<i class="tf-icons ri-github-fill"></i>
|
||||
</a>
|
||||
|
||||
<a href="javascript:;" class="btn btn-icon rounded-circle btn-text-google-plus">
|
||||
{{-- <a href="javascript:;" class="btn btn-icon rounded-circle btn-text-google-plus">
|
||||
<i class="tf-icons ri-google-fill"></i>
|
||||
</a>
|
||||
</a> --}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /Login -->
|
||||
{{-- <img alt="mask" src="../../demo/assets/img/illustrations/auth-basic-login-mask-dark.png" class="authentication-image d-none d-lg-block" data-app-light-img="illustrations/auth-basic-login-mask-light.png" data-app-dark-img="illustrations/auth-basic-login-mask-dark.png" /> --}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -190,24 +189,48 @@
|
||||
<!--/ Layout Content -->
|
||||
|
||||
|
||||
|
||||
{{-- <div class="buy-now">
|
||||
<a href="#" target="" class="btn btn-danger btn-buy-now">Buy Now</a>
|
||||
</div> --}}
|
||||
|
||||
|
||||
<!-- Include Scripts -->
|
||||
<!-- $isFront is used to append the front layout scripts only on the front layout otherwise the variable will be blank -->
|
||||
<!-- BEGIN: Vendor JS-->
|
||||
|
||||
<link rel="modulepreload" href="../../demo/build/assets/jquery-CbdDuLi-.js" />
|
||||
<link rel="modulepreload" href="../../demo/build/assets/jquery-CED9k22g.js" />
|
||||
<link rel="modulepreload" href="../../demo/build/assets/_commonjsHelpers-BosuxZz1.js" /><link rel="modulepreload" href="../../demo/build/assets/jquery-Czc5UB_B.js" /><link rel="modulepreload" href="../../demo/build/assets/popper-DNZnuk_L.js" /><link rel="modulepreload" href="../../demo/build/assets/bootstrap-B-W6M1Y3.js" /><link rel="modulepreload" href="../../demo/build/assets/node-waves-XDuO7R8f.js" /><link rel="modulepreload" href="../../demo/build/assets/perfect-scrollbar-CLUWhEAQ.js" /><link rel="modulepreload" href="../../demo/build/assets/hammer-DbFOON0O.js" /><link rel="modulepreload" href="../../demo/build/assets/typeahead-BKwBoP4T.js" /><link rel="modulepreload" href="../../demo/build/assets/menu-DAPneovL.js" /><script type="module" src="../../demo/build/assets/jquery-CbdDuLi-.js"></script><script type="module" src="../../demo/build/assets/popper-DNZnuk_L.js"></script><script type="module" src="../../demo/build/assets/bootstrap-B-W6M1Y3.js"></script><script type="module" src="../../demo/build/assets/node-waves-XDuO7R8f.js"></script><script type="module" src="../../demo/build/assets/perfect-scrollbar-CLUWhEAQ.js"></script><script type="module" src="../../demo/build/assets/hammer-DbFOON0O.js"></script><script type="module" src="../../demo/build/assets/typeahead-BKwBoP4T.js"></script><script type="module" src="../../demo/build/assets/menu-DAPneovL.js"></script>
|
||||
<link rel="modulepreload" href="../../demo/build/assets/popular-DxzY11pE.js" /><link rel="modulepreload" href="../../demo/build/assets/_commonjsHelpers-BosuxZz1.js" /><link rel="modulepreload" href="../../demo/build/assets/bootstrap5-DjMKukTX.js" /><link rel="modulepreload" href="../../demo/build/assets/index-D_6hAncj.js" /><link rel="modulepreload" href="../../demo/build/assets/auto-focus-BizrJr_R.js" /><script type="module" src="../../demo/build/assets/popular-DxzY11pE.js"></script><script type="module" src="../../demo/build/assets/bootstrap5-DjMKukTX.js"></script><script type="module" src="../../demo/build/assets/auto-focus-BizrJr_R.js"></script><!-- END: Page Vendor JS-->
|
||||
<!-- BEGIN: Vendor JS-->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/jquery/jquery.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/helpers.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/popper/popper.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/bootstrap.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/node-waves/node-waves.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/perfect-scrollbar/perfect-scrollbar.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/hammer/hammer.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/typeahead-js/typeahead.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/menu.js" />
|
||||
<script type="module" src="{{asset('assets')}}/vendor/libs/jquery/jquery.js"></script>
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/@form-validation/popular.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/helpers.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/@form-validation/bootstrap5.js" />
|
||||
{{-- <link rel="modulepreload" href="{{asset('assets')}}/index.js" /> --}}
|
||||
{{-- <link rel="modulepreload" href="{{asset('assets')}}/auto.js" /> --}}
|
||||
<script type="module" src="{{asset('assets')}}/vendor/libs/@form-validation/popular.js">
|
||||
</script><script type="module" src="{{asset('assets')}}/vendor/libs/@form-validation/bootstrap5.js"></script>
|
||||
<script type="module" src="{{asset('assets')}}/vendor/libs/@form-validation/auto-focus.js"></script>
|
||||
<!-- END: Page Vendor JS-->
|
||||
<!-- BEGIN: Theme JS-->
|
||||
<link rel="modulepreload" href="../../demo/build/assets/main-DRGn0ueN.js" /><script type="module" src="../../demo/build/assets/main-DRGn0ueN.js"></script>
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/js/main.js" />
|
||||
<script type="module" src="{{asset('assets')}}/js/main.js"></script>
|
||||
<!-- END: Theme JS-->
|
||||
<!-- Pricing Modal JS-->
|
||||
<!-- END: Pricing Modal JS-->
|
||||
<!-- BEGIN: Page JS-->
|
||||
<link rel="modulepreload" href="../../demo/build/assets/pages-auth-MEmkL_Hu.js" /><script type="module" src="../../demo/build/assets/pages-auth-MEmkL_Hu.js"></script><!-- END: Page JS-->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/js/pages-auth.js" />
|
||||
<script type="module" src="{{asset('assets')}}/js/pages-auth.js"></script>
|
||||
<!-- END: Page JS-->
|
||||
<script src="{{asset('assets')}}/js/form-validation.js"></script>
|
||||
|
||||
</body>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
|
||||
|
||||
</body>
|
||||
|
||||
|
||||
194
resources/views/admin/member/index.blade.php
Normal file
194
resources/views/admin/member/index.blade.php
Normal file
@ -0,0 +1,194 @@
|
||||
@extends('layouts.admin_app')
|
||||
@section('header')
|
||||
@endsection
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card-body">
|
||||
<!-- Basic Breadcrumb -->
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="javascript:void(0);">首頁</a>
|
||||
</li>
|
||||
|
||||
<li class="breadcrumb-item active">會員列表</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Content wrapper -->
|
||||
<div class="content-wrapper">
|
||||
|
||||
<!-- Content MemberList-->
|
||||
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
|
||||
|
||||
|
||||
<div class="row g-6 mb-6">
|
||||
<div class="col-sm-6 col-xl-3">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="me-1">
|
||||
<p class="text-heading mb-1">會員共計</p>
|
||||
<div class="d-flex align-items-center">
|
||||
<h4 class="mb-1 me-2">21,459</h4>
|
||||
<p class="text-success mb-1">(+29%)</p>
|
||||
</div>
|
||||
<small class="mb-0">Total Users</small>
|
||||
</div>
|
||||
<div class="avatar">
|
||||
<div class="avatar-initial bg-label-primary rounded-3">
|
||||
<div class="ri-group-line ri-26px"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-xl-3">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="me-1">
|
||||
<p class="text-heading mb-1">普通會員</p>
|
||||
<div class="d-flex align-items-center">
|
||||
<h4 class="mb-1 me-1">4,567</h4>
|
||||
<p class="text-success mb-1">(+18%)</p>
|
||||
</div>
|
||||
<small class="mb-0">Last week analytics</small>
|
||||
</div>
|
||||
<div class="avatar">
|
||||
<div class="avatar-initial bg-label-danger rounded-3">
|
||||
<div class="ri-user-add-line ri-26px"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-xl-3">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="me-1">
|
||||
<p class="text-heading mb-1">白銀會員</p>
|
||||
<div class="d-flex align-items-center">
|
||||
<h4 class="mb-1 me-1">19,860</h4>
|
||||
<p class="text-danger mb-1">(-14%)</p>
|
||||
</div>
|
||||
<small class="mb-0">Last week analytics</small>
|
||||
</div>
|
||||
<div class="avatar">
|
||||
<div class="avatar-initial bg-label-success rounded-3">
|
||||
<div class="ri-user-follow-line ri-26px"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-sm-6 col-xl-3">
|
||||
<div class="card">
|
||||
<div class="card-body">
|
||||
<div class="d-flex justify-content-between">
|
||||
<div class="me-1">
|
||||
<p class="text-heading mb-1">白金會員</p>
|
||||
<div class="d-flex align-items-center">
|
||||
<h4 class="mb-1 me-1">237</h4>
|
||||
<p class="text-success mb-1">(+42%)</p>
|
||||
</div>
|
||||
<small class="mb-0">Last week analytics</small>
|
||||
</div>
|
||||
<div class="avatar">
|
||||
<div class="avatar-initial bg-label-warning rounded-3">
|
||||
<div class="ri-user-search-line ri-26px"></div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<!-- Users List Table -->
|
||||
<div class="card">
|
||||
<div class="card-header border-bottom">
|
||||
<h5 class="card-title mb-0">Filters</h5>
|
||||
<div class="d-flex justify-content-between align-items-center row gx-5 pt-4 gap-5 gap-md-0">
|
||||
<div class="col-md-4 user_role"></div>
|
||||
<div class="col-md-4 user_plan"></div>
|
||||
<div class="col-md-4 user_status"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-datatable table-responsive">
|
||||
<table class="datatables-users table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>會員id</th>
|
||||
<th>會員名稱</th>
|
||||
<th>手機號碼</th>
|
||||
<th>會員等級</th>
|
||||
<th>兌換碼</th>
|
||||
<th>操 作</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($data as $item)
|
||||
<tr>
|
||||
<td>{{$item->id}}</td>
|
||||
<td class="sorting_1">
|
||||
<div class="d-flex justify-content-start align-items-center user-name">
|
||||
<div class="avatar-wrapper">
|
||||
<div class="avatar avatar-sm me-3">
|
||||
<img src="{{$item->avatar??""}}" alt="Avatar" class="rounded-circle">
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex flex-column">
|
||||
<a href="#" class="text-truncate text-heading">
|
||||
<span class="fw-medium">{{$item->name}}</span></a>
|
||||
<small>{{$item->email}}</small>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
|
||||
<td>{{$item->phone}}</td>
|
||||
<td>
|
||||
|
||||
<span class="text-truncate d-flex align-items-center text-heading">
|
||||
@if($item->level == 0)
|
||||
<i class="ri-user-line ri-22px text-danger me-2"></i>
|
||||
@elseif($item->level == 1)
|
||||
<i class="ri-user-line ri-22px text-info me-2"></i>
|
||||
@elseif($item->level == 2)
|
||||
<i class="ri-user-line ri-22px text-sucess me-2"></i>
|
||||
|
||||
@endif
|
||||
|
||||
{{$item->Level_Name}}
|
||||
</span>
|
||||
|
||||
|
||||
</td>
|
||||
<td>未實作</td>
|
||||
<td></td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
<div class="content-backdrop fade"></div>
|
||||
{{$data->links()}}
|
||||
</div>
|
||||
<!-- Content wrapper -->
|
||||
</div>
|
||||
<!-- / Layout page -->
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@section('scripts')
|
||||
@endsection
|
||||
@ -1,160 +1,343 @@
|
||||
@extends('layouts.app')
|
||||
@extends('layouts.admin_app')
|
||||
@section('header')
|
||||
@endsection
|
||||
@section('content')
|
||||
<div class="row">
|
||||
<div class="col col-6">
|
||||
<div class="card theme--dark card--density-default card--variant-elevated">
|
||||
<!---->
|
||||
<div class="card__loader">
|
||||
<div class="progress-linear progress-linear--rounded progress-linear--rounded-bar progress-linear--rounded theme--dark locale--is-ltr" role="progressbar" aria-hidden="true" aria-valuemin="0" aria-valuemax="100" style="top: 0px; height: 0px; --progress-linear-height: 2px;">
|
||||
<!---->
|
||||
<div class="progress-linear__background bg-primary"></div>
|
||||
<div class="progress-linear__buffer bg-primary" style="width: 0%;"></div>
|
||||
<div class="progress-linear__indeterminate">
|
||||
<div class="progress-linear__indeterminate long bg-primary"></div>
|
||||
<div class="progress-linear__indeterminate short bg-primary"></div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="card-text text-center pt-12 pb-6">
|
||||
<div class="avatar theme--dark avatar--density-default rounded-lg avatar--variant-flat" style="width: 120px; height: 120px;">
|
||||
<div class="responsive img">
|
||||
<div class="responsive__sizer" style="padding-bottom: 100%;"></div><img class="img__img img__img--cover" src="{{asset('assets/img/avatars/3.png')}}" style="">
|
||||
<!---->
|
||||
<!---->
|
||||
<!---->
|
||||
<!---->
|
||||
<!---->
|
||||
</div>
|
||||
<!----><span class="avatar__underlay"></span>
|
||||
</div>
|
||||
<h5 class="text-h5 mt-4">Selina Kyle</h5><span class="chip theme--dark text-error chip--density-default chip--size-small chip--variant-tonal text-capitalize mt-4" draggable="false">
|
||||
<!----><span class="chip__underlay"></span>
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="chip__content" data-no-activator="">admin</div>
|
||||
<!---->
|
||||
<!---->
|
||||
</span>
|
||||
</div>
|
||||
<div class="card-text d-flex justify-center flex-wrap gap-6 pb-6">
|
||||
<div class="d-flex align-center me-8">
|
||||
<div class="avatar theme--dark text-primary avatar--density-default avatar--rounded avatar--variant-tonal me-4" style="width: 40px; height: 40px;"><i class="ri-check-line icon notranslate theme--dark" aria-hidden="true" style="font-size: 24px; height: 24px; width: 24px;"></i>
|
||||
<!----><span class="avatar__underlay"></span></div>
|
||||
<div >
|
||||
<h5 class="text-h5">1,230</h5><span >Task Done</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="d-flex align-center me-4">
|
||||
<div class="avatar theme--dark text-primary avatar--density-default avatar--rounded avatar--variant-tonal me-4" style="width: 44px; height: 44px;"><i class="ri-briefcase-line icon notranslate theme--dark" aria-hidden="true" style="font-size: 24px; height: 24px; width: 24px;"></i>
|
||||
<!----><span class="avatar__underlay"></span></div>
|
||||
<div >
|
||||
<h5 class="text-h5">568</h5><span >Project Done</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-text pb-6">
|
||||
<h5 class="text-h5"> Details </h5>
|
||||
<hr class="divider theme--dark my-4" aria-orientation="horizontal" role="separator">
|
||||
<div class="list theme--dark list--density-default list--one-line card-list" tabindex="0" role="listbox">
|
||||
<div class="list-item theme--dark list-item--density-default list-item--one-line rounded-0 list-item--variant-text">
|
||||
<!----><span class="list-item__underlay"></span>
|
||||
<!---->
|
||||
<div class="list-item__content" data-no-activator="">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="list-item-title text-sm"><span class="font-weight-medium">Username:</span><span class="text-body-1"> @catwomen1940</span></div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<div class="list-item theme--dark list-item--density-default list-item--one-line rounded-0 list-item--variant-text">
|
||||
<!----><span class="list-item__underlay"></span>
|
||||
<!---->
|
||||
<div class="list-item__content" data-no-activator="">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="list-item-title text-sm"><span class="font-weight-medium"> Billing Email: </span><span class="text-body-1">irena.dubrovna@wayne.com</span></div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<div class="list-item theme--dark list-item--density-default list-item--one-line rounded-0 list-item--variant-text">
|
||||
<!----><span class="list-item__underlay"></span>
|
||||
<!---->
|
||||
<div class="list-item__content" data-no-activator="">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="list-item-title text-sm"><span class="font-weight-medium"> Status: </span><span class="text-body-1 text-capitalize">Active</span></div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<div class="list-item theme--dark list-item--density-default list-item--one-line rounded-0 list-item--variant-text">
|
||||
<!----><span class="list-item__underlay"></span>
|
||||
<!---->
|
||||
<div class="list-item__content" data-no-activator="">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="list-item-title text-sm"><span class="font-weight-medium">Role: </span><span class="text-capitalize text-body-1">admin</span></div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<div class="list-item theme--dark list-item--density-default list-item--one-line rounded-0 list-item--variant-text">
|
||||
<!----><span class="list-item__underlay"></span>
|
||||
<!---->
|
||||
<div class="list-item__content" data-no-activator="">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="list-item-title text-sm"><span class="font-weight-medium"> Tax ID: </span><span class="text-body-1">Tax-8894</span></div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<div class="list-item theme--dark list-item--density-default list-item--one-line rounded-0 list-item--variant-text">
|
||||
<!----><span class="list-item__underlay"></span>
|
||||
<!---->
|
||||
<div class="list-item__content" data-no-activator="">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="list-item-title text-sm"><span class="font-weight-medium"> Contact: </span><span class="text-body-1">(829) 537-0057</span></div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<div class="list-item theme--dark list-item--density-default list-item--one-line rounded-0 list-item--variant-text">
|
||||
<!----><span class="list-item__underlay"></span>
|
||||
<!---->
|
||||
<div class="list-item__content" data-no-activator="">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="list-item-title text-sm"><span class="font-weight-medium"> Language: </span><span class="text-body-1">English</span></div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
<div class="list-item theme--dark list-item--density-default list-item--one-line rounded-0 list-item--variant-text">
|
||||
<!----><span class="list-item__underlay"></span>
|
||||
<!---->
|
||||
<div class="list-item__content" data-no-activator="">
|
||||
<!---->
|
||||
<!---->
|
||||
<div class="list-item-title text-sm"><span class="font-weight-medium"> Country: </span><span class="text-body-1">United States</span></div>
|
||||
</div>
|
||||
<!---->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="card-text d-flex justify-center"><button type="button" class="btn btn--elevated theme--dark bg-primary btn--density-default btn--size-default btn--variant-elevated me-4"><span class="btn__overlay"></span><span class="btn__underlay"></span>
|
||||
<!----><span class="btn__content" data-no-activator=""> Edit </span>
|
||||
<!---->
|
||||
<!----></button><button type="button" class="btn theme--dark text-error btn--density-default btn--size-default btn--variant-outlined"><span class="btn__overlay"></span><span class="btn__underlay"></span>
|
||||
<!----><span class="btn__content" data-no-activator=""> Suspend </span>
|
||||
<!---->
|
||||
<!----></button></div>
|
||||
<!---->
|
||||
<!----><span class="card__underlay"></span>
|
||||
<!-- Layout Content -->
|
||||
|
||||
<!-- Content -->
|
||||
<div class="position-relative">
|
||||
<div class="authentication-wrapper authentication-basic container-p-y p-4 p-sm-0">
|
||||
<div class="authentication-inner py-6">
|
||||
|
||||
<!-- Login -->
|
||||
<div class="card p-md-7 p-1">
|
||||
<!-- Logo -->
|
||||
<div class="app-brand justify-content-center mt-5">
|
||||
<a href="#" class="app-brand-link gap-2">
|
||||
<span class="app-brand-logo demo"><span>
|
||||
<img src="{{asset('assets/img/logo/cafeg-logo.png')}}" width="50px" height="50px" alt="{{asset('img/logo/cafeg-logo.png')}}"> </img>
|
||||
|
||||
</span>
|
||||
</span>
|
||||
<span class="app-brand-text demo text-heading fw-semibold">
|
||||
<img src="{{asset('assets/img/logo/cafeg-logo-h.png')}}" width="120px" height="50px" alt="{{asset('img/logo/cafeg-logo.png')}}"> </img>
|
||||
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<!-- /Logo -->
|
||||
|
||||
<div class="card-body mt-1">
|
||||
<h4 class="mb-1">卡菲姬個人資料</h4>
|
||||
<p class="mb-5">Hi, <span class="text-ifno"> {{$data->name }} 管理者 </span> 歡迎你 ! ,請花幾分鐘完善資料</p>
|
||||
|
||||
<div class="card" id="editUser">
|
||||
<div class="content">
|
||||
<div class="body p-0">
|
||||
<div class="text-center mb-6">
|
||||
<h4 class="mb-2">編輯您的資訊</h4>
|
||||
<p class="mb-6">更新用戶詳細資訊</p>
|
||||
</div>
|
||||
<form id="editUserForm" class="row g-5" >
|
||||
<!-- 暱稱 -->
|
||||
<div class="col-12">
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input
|
||||
readonly
|
||||
type="text"
|
||||
id="modalEditUserFirstName"
|
||||
name="modalEditUserFirstName"
|
||||
class="form-control"
|
||||
value="{{$data->name}}"
|
||||
placeholder="暱稱"
|
||||
aria-label="暱稱"
|
||||
/>
|
||||
<label for="modalEditUserFirstName">暱稱</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Email -->
|
||||
<div class="col-12">
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input
|
||||
type="email"
|
||||
id="formValidationEmail"
|
||||
class="form-control"
|
||||
placeholder="john.doe@example.com"
|
||||
aria-label="Email"
|
||||
required
|
||||
value="{{$data->email ?? ''}}"
|
||||
|
||||
/>
|
||||
<label for="formValidationEmail">Email</label>
|
||||
<div class="invalid-feedback">請輸入有效的 Email</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 密碼 -->
|
||||
<div class="col-12">
|
||||
<div class="form-password-toggle">
|
||||
<div class="input-group input-group-merge">
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input
|
||||
type="password"
|
||||
id="basic-default-password"
|
||||
class="form-control"
|
||||
placeholder="密碼"
|
||||
aria-label="密碼"
|
||||
value="{{$data->password ?? ''}}"
|
||||
|
||||
/>
|
||||
<label for="basic-default-password">密碼</label>
|
||||
<div class="invalid-feedback">請輸入有效密碼</div>
|
||||
|
||||
</div>
|
||||
<span
|
||||
class="input-group-text cursor-pointer"
|
||||
id="basic-default-password3"
|
||||
>
|
||||
<i class="ri-eye-off-line"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 確認密碼 -->
|
||||
<div class="col-12">
|
||||
<div class="form-password-toggle">
|
||||
<div class="input-group input-group-merge">
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input
|
||||
type="password"
|
||||
id="formValidationConfirmPass"
|
||||
name="formValidationConfirmPass"
|
||||
class="form-control"
|
||||
placeholder="確認密碼"
|
||||
aria-label="確認密碼"
|
||||
value="{{$data->password ?? ''}}"
|
||||
|
||||
/>
|
||||
<label for="formValidationConfirmPass">確認密碼</label>
|
||||
<div class="invalid-feedback">密碼與確認密碼不相符</div>
|
||||
|
||||
</div>
|
||||
<span
|
||||
class="input-group-text cursor-pointer"
|
||||
id="multicol-confirm-password2"
|
||||
>
|
||||
<i class="ri-eye-off-line"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 電話 -->
|
||||
<div class="col-12">
|
||||
<div class="input-group input-group-merge">
|
||||
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input
|
||||
type="text"
|
||||
id="modalEditUserPhone"
|
||||
name="modalEditUserPhone"
|
||||
class="form-control phone-number-mask"
|
||||
value="{{$data->phone ?? ''}}"
|
||||
placeholder="0920111222"
|
||||
aria-label="電話"
|
||||
/>
|
||||
<label for="modalEditUserPhone">電話</label>
|
||||
<div class="invalid-feedback">請輸入有效電話</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 按鈕 -->
|
||||
<div
|
||||
class="col-12 text-center d-flex flex-wrap justify-content-center gap-4 row-gap-4"
|
||||
|
||||
>
|
||||
<button type="submit" class="btn btn-primary">送出</button>
|
||||
<button
|
||||
type="reset"
|
||||
class="btn btn-outline-secondary"
|
||||
data-bs-dismiss="modal"
|
||||
aria-label="Close"
|
||||
>
|
||||
取消
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@section('scripts')
|
||||
|
||||
|
||||
{{-- <p class="text-center">
|
||||
<span>新的裝置?</span>
|
||||
<a href="register-basic.html">
|
||||
<span>創建新的帳號</span>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<div class="divider my-5">
|
||||
<div class="divider-text">或</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-center gap-2">
|
||||
|
||||
<a href="{{route('admin.login.line')}}" class="btn btn-icon rounded-circle btn-text-line">
|
||||
<i class="tf-icons ri-line-fill"></i>
|
||||
</a>
|
||||
|
||||
|
||||
|
||||
|
||||
<a href="javascript:;" class="btn btn-icon rounded-circle btn-text-google-plus">
|
||||
<i class="tf-icons ri-google-fill"></i>
|
||||
</a> --}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- /Login -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--/ Content -->
|
||||
|
||||
<!--/ Layout Content -->
|
||||
|
||||
|
||||
{{-- <div class="buy-now">
|
||||
<a href="#" target="" class="btn btn-danger btn-buy-now">Buy Now</a>
|
||||
</div> --}}
|
||||
|
||||
|
||||
<!-- Include Scripts -->
|
||||
<!-- $isFront is used to append the front layout scripts only on the front layout otherwise the variable will be blank -->
|
||||
<!-- BEGIN: Vendor JS-->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/jquery/jquery.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/helpers.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/popper/popper.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/bootstrap.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/node-waves/node-waves.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/perfect-scrollbar/perfect-scrollbar.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/hammer/hammer.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/typeahead-js/typeahead.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/menu.js" />
|
||||
<script type="module" src="{{asset('assets')}}/vendor/libs/jquery/jquery.js"></script>
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/@form-validation/popular.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/helpers.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/@form-validation/bootstrap5.js" />
|
||||
{{-- <link rel="modulepreload" href="{{asset('assets')}}/index.js" /> --}}
|
||||
{{-- <link rel="modulepreload" href="{{asset('assets')}}/auto.js" /> --}}
|
||||
<script type="module" src="{{asset('assets')}}/vendor/libs/@form-validation/popular.js">
|
||||
</script><script type="module" src="{{asset('assets')}}/vendor/libs/@form-validation/bootstrap5.js"></script>
|
||||
<script type="module" src="{{asset('assets')}}/vendor/libs/@form-validation/auto-focus.js"></script>
|
||||
<!-- END: Page Vendor JS-->
|
||||
<!-- BEGIN: Theme JS-->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/js/main.js" />
|
||||
<script type="module" src="{{asset('assets')}}/js/main.js"></script>
|
||||
<!-- END: Theme JS-->
|
||||
<!-- Pricing Modal JS-->
|
||||
<!-- END: Pricing Modal JS-->
|
||||
<!-- BEGIN: Page JS-->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/js/pages-auth.js" />
|
||||
<script type="module" src="{{asset('assets')}}/js/pages-auth.js"></script>
|
||||
<!-- END: Page JS-->
|
||||
<script src="{{asset('assets')}}/js/form-validation.js"></script>
|
||||
|
||||
</body>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
$('#editUserForm').on('submit', function (e) {
|
||||
e.preventDefault(); // 防止表單提交
|
||||
|
||||
let valid = true;
|
||||
|
||||
// Email 驗證
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
const emailInput = $('#formValidationEmail');
|
||||
if (!emailRegex.test(emailInput.val())) {
|
||||
valid = false;
|
||||
emailInput.addClass('is-invalid');
|
||||
} else {
|
||||
emailInput.removeClass('is-invalid');
|
||||
}
|
||||
|
||||
// 密碼長度驗證
|
||||
const passwordInput = $('#basic-default-password');
|
||||
//if (passwordInput.val().length < 6) {
|
||||
// valid = false;
|
||||
//passwordInput.addClass('is-invalid');
|
||||
//} else {
|
||||
// passwordInput.removeClass('is-invalid');
|
||||
//}
|
||||
|
||||
// 確認密碼驗證
|
||||
const confirmPasswordInput = $('#formValidationConfirmPass');
|
||||
if (passwordInput.val() !== confirmPasswordInput.val()) {
|
||||
valid = false;
|
||||
confirmPasswordInput.addClass('is-invalid');
|
||||
} else {
|
||||
confirmPasswordInput.removeClass('is-invalid');
|
||||
}
|
||||
|
||||
// 手機號碼驗證
|
||||
const phoneRegex = /^09\d{8}$/;
|
||||
const phoneInput = $('#modalEditUserPhone');
|
||||
if (!phoneRegex.test(phoneInput.val())) {
|
||||
valid = false;
|
||||
phoneInput.addClass('is-invalid');
|
||||
} else {
|
||||
phoneInput.removeClass('is-invalid');
|
||||
}
|
||||
|
||||
// 若通過所有驗證,發送 AJAX 請求
|
||||
if (valid) {
|
||||
const formData = {
|
||||
email: emailInput.val(),
|
||||
password: passwordInput.val(),
|
||||
phone: phoneInput.val(),
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
url: "{{ route('admin.profile.update') }}",
|
||||
type: 'put',
|
||||
data: formData,
|
||||
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') },
|
||||
success: function (response) {
|
||||
Swal.fire({
|
||||
title: '成功'
|
||||
, text: "{{ session('success') }}"
|
||||
, icon: 'success'
|
||||
, confirmButtonText: '确定'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
// 跳轉到 admin.index 路由
|
||||
window.location.href = "{{ route('admin.index') }}";
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
},
|
||||
error: function (error) {
|
||||
Swal.fire({
|
||||
title: '失敗'
|
||||
, text: "更新失敗"
|
||||
, icon: 'error'
|
||||
, confirmButtonText: '确定'
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
|
||||
@endsection
|
||||
|
||||
168
resources/views/admin/setting/promocode.blade.php
Normal file
168
resources/views/admin/setting/promocode.blade.php
Normal file
@ -0,0 +1,168 @@
|
||||
@extends('layouts.admin_app')
|
||||
@section('header')
|
||||
@endsection
|
||||
@section('content')
|
||||
<style>
|
||||
.table th,
|
||||
.table td {
|
||||
white-space: nowrap;
|
||||
/* 禁止文字換行 */
|
||||
text-align: center;
|
||||
/* 內容置中 */
|
||||
overflow: hidden;
|
||||
/* 隱藏超出內容 */
|
||||
text-overflow: ellipsis;
|
||||
/* 超出用省略號顯示 */
|
||||
}
|
||||
|
||||
.table th {
|
||||
width: auto;
|
||||
/* 可根據內容自適應,但不要超出 */
|
||||
}
|
||||
|
||||
.table {
|
||||
width: 100%;
|
||||
/* 撐滿父容器 */
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<div clas="content-wrapper">
|
||||
<div class="row">
|
||||
<div class="col-md-12">
|
||||
<div class="card-body">
|
||||
<!-- Basic Breadcrumb -->
|
||||
<nav aria-label="breadcrumb">
|
||||
<ol class="breadcrumb">
|
||||
<li class="breadcrumb-item">
|
||||
<a href="javascript:void(0);">首頁</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item">
|
||||
<a href="javascript:void(0);">設定</a>
|
||||
</li>
|
||||
<li class="breadcrumb-item active">優惠代碼</li>
|
||||
</ol>
|
||||
</nav>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<!-- Basic Layout -->
|
||||
<div class="row">
|
||||
<div class="col-xl">
|
||||
<div class="card mb-12" style="margin-bottom: 20px;">
|
||||
|
||||
<div class="card-body">
|
||||
<form action="{{route('admin.promocode.create')}}" method="POST" enctype="multipart/form-data">
|
||||
@csrf
|
||||
|
||||
<h5 class="card-header">輸入檔案</h5>
|
||||
<div class="card-body">
|
||||
<div class="mb-4">
|
||||
<label for="formFile" class="form-label">檔案類型 excels</label>
|
||||
<input class="form-control" name="file" type="file" id="formFile">
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-primary">Send</button>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- DataTable with Buttons -->
|
||||
<div class="card">
|
||||
<div class="card-datatable table-responsive pt-0">
|
||||
<table class="datatables-basic table table-bordered">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th style="width: 20%; !important"> 優惠碼</th>
|
||||
<th style="width: 15%; !important">優惠類型</th>
|
||||
<th style="width: 20%; !important">折扣比例</th>
|
||||
<th style="width: 15%; !important"> 是否派發</th>
|
||||
<th style="width: 30%; !important">生效期間</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
@foreach($data as $item)
|
||||
<tr>
|
||||
<td><strong class="text-danger blod">{{$item->code}}</strong></td>
|
||||
<td>{{$item->type}}</td>
|
||||
<td> {{ number_format($item->discount, 0) }}</td>
|
||||
<td>{{$item->used_count}} </td>
|
||||
<td>{{$item->valid_from}} </td>
|
||||
</tr>
|
||||
@endforeach
|
||||
</tbody>
|
||||
|
||||
|
||||
</table>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{{$data->links()}}
|
||||
|
||||
</div>
|
||||
@endsection
|
||||
@section('scripts')
|
||||
@if (session('success'))
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
Swal.fire({
|
||||
title: '成功'
|
||||
, text: "{{ session('success') }}"
|
||||
, icon: 'success'
|
||||
, confirmButtonText: '确定'
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
@endif
|
||||
@if (session('error'))
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
Swal.fire({
|
||||
title: '失敗'
|
||||
, text: "{{ session('error') }}"
|
||||
, icon: 'error'
|
||||
, confirmButtonText: '确定'
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
@endif
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$('.datatables-basic').DataTable({
|
||||
columnDefs: [{
|
||||
width: "20%"
|
||||
, targets: 0
|
||||
}
|
||||
, {
|
||||
width: "15%"
|
||||
, targets: 1
|
||||
}
|
||||
, {
|
||||
width: "20%"
|
||||
, targets: 2
|
||||
}
|
||||
, {
|
||||
width: "15%"
|
||||
, targets: 3
|
||||
}
|
||||
, {
|
||||
width: "30%"
|
||||
, targets: 4
|
||||
}
|
||||
]
|
||||
, autoWidth: false // 禁止自動計算列寬
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
@endsection
|
||||
11
resources/views/emails/custom.blade.php
Normal file
11
resources/views/emails/custom.blade.php
Normal file
@ -0,0 +1,11 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<title>{{ $subject }}</title>
|
||||
</head>
|
||||
<body>
|
||||
<h1>{{ $subject }}</h1>
|
||||
<p>{!! nl2br(e($emailMessage)) !!}</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
@ -1,6 +1,6 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="de" class="dark-style layout-menu-fixed customizer-hide" dir="ltr" data-theme="theme-default" data-assets-path="https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo/assets/" data-base-url="https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo-4" data-framework="laravel" data-template="blank-menu-theme-default-dark" data-style="dark">
|
||||
<html lang="en" class="dark-style layout-menu-fixed customizer-hide" dir="ltr" data-theme="theme-default" data-assets-path="https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo/assets/" data-base-url="https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo-4" data-framework="laravel" data-template="blank-menu-theme-default-dark" data-style="dark">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
@ -24,41 +24,41 @@
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/fonts/remixicon/remixicon.css" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/fonts/flag-icons.css" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/libs/node-waves/node-waves.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/fonts/remixicon/remixicon.css" class="" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/fonts/flag-icons.css" class="" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/libs/node-waves/node-waves.css" class="" /><!-- Core CSS -->
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/libs/node-waves/node-waves.css" class="" />
|
||||
<!-- Core CSS -->
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/css/core-dark.css" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/css/theme-default-dark.css" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/css/demo.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/css/core-dark.css" class="template-customizer-core-css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/css/theme-default-dark.css" class="template-customizer-theme-css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/css/demo.css" class="" />
|
||||
|
||||
<!-- Vendor Styles -->
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/venodr/lib/perfect-scrollbar/perfect-scrollbar.css" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/typeahead.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/venodr/lib/perfect-scrollbar/perfect-scrollbar.css" class="" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/typeahead.css" class="" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/form-validation.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/form-validation.css" class="" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/libs/perfect-scrollbar/perfect-scrollbar.css" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/libs/typeahead-js/typeahead.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/libs/perfect-scrollbar/perfect-scrollbar.css" class="" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/libs/typeahead-js/typeahead.css" class="" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/libs/@form-validation/form-validation.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/libs/@form-validation/form-validation.css" class="" />
|
||||
<!-- Page Styles -->
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/css/pages/page-auth.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/css/pages/page-auth.css" class="" />
|
||||
<!-- Include Scripts for customizer, helper, analytics, config -->
|
||||
<!-- $isFront is used to append the front layout scriptsIncludes only on the front layout otherwise the variable will be blank -->
|
||||
<!-- laravel style -->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/helpers.js" />
|
||||
<script type="module" src="{{asset('assets')}}/helpers.js"></script>
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/helpers.js" />
|
||||
<script type="module" src="{{asset('assets')}}/vendor/js/helpers.js"></script>
|
||||
<!-- beautify ignore:start -->
|
||||
<!--! Template customizer & Theme config files MUST be included after core stylesheets and helpers.js in the <head> section -->
|
||||
<!--? Template customizer: To hide customizer set displayCustomizer value false in config.js. -->
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/template-customizer.css" /><link rel="modulepreload" href="{{asset('assets')}}/template-customizer.js" /><link rel="stylesheet" href="{{asset('assets')}}/template-customizer-C6tl466J.css" /><script type="module" src="{{asset('assets')}}/template-customizer-C9zWc80S.js"></script>
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/template-customizer.js" />
|
||||
<!--? Config: Mandatory theme config file contain global vars & default theme options, Set your preferred theme option in this file. -->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/js/config.js" /><script type="module" src="{{asset('assets')}}/config.js"></script>
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/js/config.js" /><script type="module" src="{{asset('assets')}}/js/config.js"></script>
|
||||
|
||||
<script type="module">
|
||||
window.templateCustomizer = new TemplateCustomizer({
|
||||
cssPath: '',
|
||||
@ -121,9 +121,10 @@
|
||||
<h4 class="mb-1">歡迎來到卡菲姬 👋</h4>
|
||||
<p class="mb-5">請登入後逕行兌換飲品,希望您會喜歡</p>
|
||||
|
||||
<form id="formAuthentication" class="mb-5" action="" method="GET">
|
||||
<form id="formAuthentication" class="mb-5" action="{{route(name: 'member.login.post')}}" method="POST">
|
||||
@csrf
|
||||
<div class="form-floating form-floating-outline mb-5">
|
||||
<input type="text" class="form-control" id="email" name="email-username" placeholder="請填寫您的電子郵件" autofocus>
|
||||
<input type="text" class="form-control" id="email" name="email" placeholder="請填寫您的電子郵件" autofocus>
|
||||
<label for="email">電子郵件</label>
|
||||
</div>
|
||||
<div class="mb-5">
|
||||
@ -149,13 +150,13 @@
|
||||
</a>
|
||||
</div>
|
||||
<div class="mb-5">
|
||||
<button class="btn btn-primary d-grid w-100" type="submit">Sign in</button>
|
||||
<button class="btn btn-primary d-grid w-100" type="submit">登 入</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<p class="text-center">
|
||||
<span>新的裝置?</span>
|
||||
<a href="register-basic.html">
|
||||
<a href="{{route('member.register')}}">
|
||||
<span>創建新的帳號</span>
|
||||
</a>
|
||||
</p>
|
||||
@ -173,9 +174,9 @@
|
||||
|
||||
|
||||
|
||||
<a href="javascript:;" class="btn btn-icon rounded-circle btn-text-google-plus">
|
||||
{{-- <a href="javascript:;" class="btn btn-icon rounded-circle btn-text-google-plus">
|
||||
<i class="tf-icons ri-google-fill"></i>
|
||||
</a>
|
||||
</a> --}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@ -195,25 +196,25 @@
|
||||
|
||||
<!-- Include Scripts -->
|
||||
<!-- $isFront is used to append the front layout scripts only on the front layout otherwise the variable will be blank -->
|
||||
<!-- BEGIN: Vendor JS-->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/jquery.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/_commonjsHelpers" />
|
||||
<!-- BEGIN: Vendor JS-->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/jquery/jquery.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/helpers.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/popper/popper.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/bootstrap.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/node-waves/node-waves.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/perfect-scrollbar.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/perfect-scrollbar/perfect-scrollbar.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/hammer/hammer.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/typeahead-js/typeahead.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/menu.js" />
|
||||
<script type="module" src="{{asset('assets')}}/vendor/libs/jquery.js"></script>
|
||||
<script type="module" src="{{asset('assets')}}/vendor/libs/jquery/jquery.js"></script>
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/@form-validation/popular.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/_commonjsHelpers-BosuxZz1.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/bootstrap5.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/helpers.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/@form-validation/bootstrap5.js" />
|
||||
{{-- <link rel="modulepreload" href="{{asset('assets')}}/index.js" /> --}}
|
||||
{{-- <link rel="modulepreload" href="{{asset('assets')}}/auto.js" /> --}}
|
||||
<script type="module" src="{{asset('assets')}}/vendor/libs/@form-validation/popular.js">
|
||||
</script><script type="module" src="{{asset('assets')}}/bootstrap5.js"></script>
|
||||
<script type="module" src="{{asset('assets')}}/auto-focus.js"></script>
|
||||
</script><script type="module" src="{{asset('assets')}}/vendor/libs/@form-validation/bootstrap5.js"></script>
|
||||
<script type="module" src="{{asset('assets')}}/vendor/libs/@form-validation/auto-focus.js"></script>
|
||||
<!-- END: Page Vendor JS-->
|
||||
<!-- BEGIN: Theme JS-->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/js/main.js" />
|
||||
@ -225,7 +226,38 @@
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/js/pages-auth.js" />
|
||||
<script type="module" src="{{asset('assets')}}/js/pages-auth.js"></script>
|
||||
<!-- END: Page JS-->
|
||||
<script src="{{asset('assets')}}/js/form-validation.js"></script>
|
||||
|
||||
</body>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
</body>
|
||||
|
||||
@if (session('success'))
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
Swal.fire({
|
||||
title: '成功'
|
||||
, text: "{{ session('success') }}"
|
||||
, icon: 'success'
|
||||
, confirmButtonText: '确定'
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
@endif
|
||||
@if (session('error'))
|
||||
<script>
|
||||
document.addEventListener("DOMContentLoaded", function() {
|
||||
Swal.fire({
|
||||
title: '失敗'
|
||||
, text: "{{ session('error') }}"
|
||||
, icon: 'error'
|
||||
, confirmButtonText: '确定'
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
@endif
|
||||
|
||||
</html>
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
|
||||
375
resources/views/front/member/auth-register.blade.php
Normal file
375
resources/views/front/member/auth-register.blade.php
Normal file
@ -0,0 +1,375 @@
|
||||
<!DOCTYPE html>
|
||||
|
||||
|
||||
|
||||
<html lang="en" class="light-style layout-wide dark customizer-hide" dir="ltr" data-theme="theme-bordered" data-assets-path="{{ asset('assets') }}/" data-template="vertical-menu-template-bordered" data-style="light">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
|
||||
|
||||
<title>卡菲姬APP註冊</title>
|
||||
<meta name="description" content="卡菲姬 cafeg 是一個自助咖啡機 " />
|
||||
<meta name="keywords" content="smart-cafe-g smart-cafe smart-coffee">
|
||||
<!-- laravel CRUD token -->
|
||||
<meta name="csrf-token" content="6fa8KEfKxuHo22PqMwHmCoxMDArqCNYyqRXJNZSE">
|
||||
<!-- Canonical SEO -->
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/x-icon" href="../../demo/assets/img/favicon/favicon.ico" />
|
||||
|
||||
|
||||
|
||||
<!-- ? PROD Only: Google Tag Manager (Default ThemeSelection: GTM-5DDHKGP, PixInvent: GTM-5J3LMKC) -->
|
||||
<script>
|
||||
(function(w, d, s, l, i) {
|
||||
w[l] = w[l] || [];
|
||||
w[l].push({
|
||||
'gtm.start': new Date().getTime()
|
||||
, event: 'gtm.js'
|
||||
});
|
||||
var f = d.getElementsByTagName(s)[0]
|
||||
, j = d.createElement(s)
|
||||
, dl = l != 'dataLayer' ? '&l=' + l : '';
|
||||
j.async = true;
|
||||
j.src =
|
||||
'https://www.googletagmanager.com/gtm.js?id=' + i + dl;
|
||||
f.parentNode.insertBefore(j, f);
|
||||
})(window, document, 'script', 'dataLayer', 'GTM-5J3LMKC');
|
||||
|
||||
</script>
|
||||
<!-- End Google Tag Manager -->
|
||||
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/x-icon" href="{{ asset('assets') }}/img/favicon/favicon.ico" />
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<!-- Icons -->
|
||||
<link rel="stylesheet" href="{{ asset('assets') }}/vendor/fonts/remixicon/remixicon.css" />
|
||||
<link rel="stylesheet" href="{{ asset('assets') }}/vendor/fonts/flag-icons.css" />
|
||||
|
||||
<!-- Menu waves for no-customizer fix -->
|
||||
<link rel="stylesheet" href="{{ asset('assets') }}/vendor/libs/node-waves/node-waves.css" />
|
||||
|
||||
<!-- Core CSS -->
|
||||
<link rel="stylesheet" href="{{ asset('assets') }}/vendor/css/rtl/core.css" class="template-customizer-core-css" />
|
||||
<link rel="stylesheet" href="{{ asset('assets') }}/vendor/css/rtl/theme-bordered.css" class="template-customizer-theme-css" />
|
||||
<link rel="stylesheet" href="{{ asset('assets') }}/css/demo.css" />
|
||||
|
||||
<!-- Vendors CSS -->
|
||||
<link rel="stylesheet" href="{{ asset('assets') }}/vendor/libs/perfect-scrollbar/perfect-scrollbar.css" />
|
||||
<link rel="stylesheet" href="{{ asset('assets') }}/vendor/libs/typeahead-js/typeahead.css" />
|
||||
<!-- Vendor -->
|
||||
<link rel="stylesheet" href="{{ asset('assets') }}/vendor/libs/@form-validation/form-validation.css" />
|
||||
|
||||
<!-- Page CSS -->
|
||||
<!-- Page -->
|
||||
<link rel="stylesheet" href="{{ asset('assets') }}/vendor/css/pages/page-auth.css">
|
||||
|
||||
<!-- Helpers -->
|
||||
<script src="{{ asset('assets') }}/vendor/js/helpers.js"></script>
|
||||
<!--! Template customizer & Theme config files MUST be included after core stylesheets and helpers.js in the <head> section -->
|
||||
<!--? Template customizer: To hide customizer set displayCustomizer value false in config.js. -->
|
||||
<script src="{{ asset('assets') }}/vendor/js/template-customizer.js"></script>
|
||||
<!--? Config: Mandatory theme config file contain global vars & default theme options, Set your preferred theme option in this file. -->
|
||||
<script src="{{ asset('assets') }}/js/config.js"></script>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
|
||||
<!-- ?PROD Only: Google Tag Manager (noscript) (Default ThemeSelection: GTM-5DDHKGP, PixInvent: GTM-5J3LMKC) -->
|
||||
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5J3LMKC" height="0" width="0" style="display: none; visibility: hidden"></iframe></noscript>
|
||||
<!-- End Google Tag Manager (noscript) -->
|
||||
|
||||
<!-- Content -->
|
||||
|
||||
<div class="position-relative">
|
||||
<div class="authentication-wrapper authentication-basic container-p-y p-4 p-sm-0">
|
||||
<div class="authentication-inner py-6">
|
||||
|
||||
<!-- Register Card -->
|
||||
<div class="card p-md-7 p-1">
|
||||
<!-- Logo -->
|
||||
<div class="app-brand justify-content-center mt-5">
|
||||
<a href="#" class="app-brand-link gap-2">
|
||||
<span class="app-brand-logo demo"><span>
|
||||
<img src="{{ asset('assets/img/logo/cafeg-logo.png') }}" width="50px" height="50px" alt="{{ asset('img/logo/cafeg-logo.png') }}"> </img>
|
||||
|
||||
</span>
|
||||
</span>
|
||||
<span class="app-brand-text demo text-heading fw-semibold">
|
||||
<img src="{{ asset('assets/img/logo/cafeg-logo-h.png') }}" width="120px" height="50px" alt="{{ asset('img/logo/cafeg-logo.png') }}"> </img>
|
||||
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<!-- /Logo -->
|
||||
<div class="card-body mt-1">
|
||||
<h4 class="mb-1">由此註冊卡菲姬 APP 🚀</h4>
|
||||
<p class="mb-5">您好 !客戶 請花幾分鐘註冊</p>
|
||||
|
||||
<form id="formAuthentication" class="mb-5">
|
||||
@csrf
|
||||
<div class="form-floating form-floating-outline mb-5">
|
||||
<input type="text" class="form-control" id="username" name="name" placeholder="輸入你的稱呼" required>
|
||||
<label for="username">稱 呼</label>
|
||||
<div class="invalid-feedback">請輸入稱呼。</div>
|
||||
</div>
|
||||
<div class="form-floating form-floating-outline mb-5">
|
||||
<input type="email" class="form-control" id="email" name="email" placeholder="輸入你的帳號" required>
|
||||
<label for="email">Email(帳號)</label>
|
||||
<div class="invalid-feedback">請輸入有效的 Email 地址。</div>
|
||||
</div>
|
||||
<div class="mb-5 form-password-toggle">
|
||||
<div class="input-group input-group-merge">
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input type="password" id="password" class="form-control" name="password" placeholder="輸入密碼" required minlength="6">
|
||||
<label for="password">密碼</label>
|
||||
<div class="invalid-feedback">請輸入至少 6 個字符的密碼。</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-floating form-floating-outline mb-5">
|
||||
<input type="text" class="form-control" id="phone" name="phone" placeholder="輸入您的手機號" required pattern="^[0-9]{10}$">
|
||||
<label for="phone">手機號碼</label>
|
||||
<div class="invalid-feedback" id="checkphone">請輸入有效的 10 位手機號碼。</div>
|
||||
</div>
|
||||
<div class="mb-5">
|
||||
<div class="form-check mt-2">
|
||||
<input class="form-check-input" type="checkbox" id="terms-conditions" name="terms" required>
|
||||
<label class="form-check-label" for="terms-conditions">
|
||||
我同意
|
||||
<a href="javascript:void(0);">隱私權政策和條款</a>
|
||||
</label>
|
||||
<div class="invalid-feedback">請同意條款。</div>
|
||||
</div>
|
||||
</div>
|
||||
<button type="submit" class="btn btn-primary d-grid w-100">
|
||||
註冊
|
||||
</button>
|
||||
</form>
|
||||
|
||||
|
||||
<p class="text-center">
|
||||
<span>已經有帳號?</span>
|
||||
<a href="{{ route('front.login.view') }}" class="text-body">
|
||||
<span>由此登入</span>
|
||||
</a>
|
||||
</p>
|
||||
|
||||
<div class="divider my-5">
|
||||
<div class="divider-text">or</div>
|
||||
</div>
|
||||
|
||||
<div class="d-flex justify-content-center gap-2">
|
||||
<a href="{{ route('front.login.line') }}" class="btn btn-icon rounded-circle btn-text-facebook">
|
||||
<i class="tf-icons ri-line-fill"></i>
|
||||
</a>
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Register Card -->
|
||||
<img alt="mask" src="{{ asset('assets') }}/img/illustrations/auth-basic-register-mask-light.png" class="authentication-image d-none d-lg-block" data-app-light-img="illustrations/auth-basic-register-mask-light.png" data-app-dark-img="illustrations/auth-basic-register-mask-dark.png" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- / Content -->
|
||||
|
||||
{{--
|
||||
<div class="buy-now">
|
||||
<a href="https://1.envato.market/materialize_admin" target="_blank" class="btn btn-danger btn-buy-now">Buy Now</a>
|
||||
</div>
|
||||
--}}
|
||||
|
||||
|
||||
|
||||
<!-- Core JS -->
|
||||
<!-- build:js assets/vendor/js/core.js -->
|
||||
<script src="{{ asset('assets') }}/vendor/libs/jquery/jquery.js"></script>
|
||||
<script src="{{ asset('assets') }}/vendor/libs/popper/popper.js"></script>
|
||||
<script src="{{ asset('assets') }}/vendor/js/bootstrap.js"></script>
|
||||
<script src="{{ asset('assets') }}/vendor/libs/node-waves/node-waves.js"></script>
|
||||
<script src="{{ asset('assets') }}/vendor/libs/perfect-scrollbar/perfect-scrollbar.js"></script>
|
||||
<script src="{{ asset('assets') }}/vendor/libs/hammer/hammer.js"></script>
|
||||
<script src="{{ asset('assets') }}/vendor/libs/i18n/i18n.js"></script>
|
||||
<script src="{{ asset('assets') }}/vendor/libs/typeahead-js/typeahead.js"></script>
|
||||
<script src="{{ asset('assets') }}/vendor/js/menu.js"></script>
|
||||
|
||||
<!-- endbuild -->
|
||||
|
||||
<!-- Vendors JS -->
|
||||
<script src="{{ asset('assets') }}/vendor/libs/@form-validation/popular.js"></script>
|
||||
<script src="{{ asset('assets') }}/vendor/libs/@form-validation/bootstrap5.js"></script>
|
||||
<script src="{{ asset('assets') }}/vendor/libs/@form-validation/auto-focus.js"></script>
|
||||
|
||||
<!-- Main JS -->
|
||||
<script src="{{ asset('assets') }}/js/main.js"></script>
|
||||
|
||||
|
||||
<!-- Page JS -->
|
||||
|
||||
</body>
|
||||
|
||||
</html>
|
||||
|
||||
|
||||
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
|
||||
<!-- beautify ignore:end -->
|
||||
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
// 驗證欄位的函數
|
||||
function validateField(field) {
|
||||
const id = field.attr('id');
|
||||
const value = field.val().trim();
|
||||
let isValid = true;
|
||||
let errorMsg = '';
|
||||
|
||||
// 根據欄位 ID 驗證
|
||||
switch (id) {
|
||||
case 'username':
|
||||
if (!value) {
|
||||
isValid = false;
|
||||
errorMsg = '請輸入稱呼。';
|
||||
}
|
||||
break;
|
||||
case 'email':
|
||||
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
if (!emailPattern.test(value)) {
|
||||
isValid = false;
|
||||
errorMsg = '請輸入有效的 Email 地址。';
|
||||
}
|
||||
break;
|
||||
case 'password':
|
||||
if (value.length < 6) {
|
||||
isValid = false;
|
||||
errorMsg = '密碼至少需要 6 個字符。';
|
||||
}
|
||||
break;
|
||||
case 'phone':
|
||||
const phonePattern = /^[0-9]{10}$/;
|
||||
if (!phonePattern.test(value)) {
|
||||
isValid = false;
|
||||
errorMsg = '請輸入有效的 10 位手機號碼。';
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// 顯示或隱藏錯誤訊息
|
||||
if (isValid) {
|
||||
field.removeClass('is-invalid');
|
||||
field.next('.invalid-feedback').hide();
|
||||
} else {
|
||||
field.addClass('is-invalid');
|
||||
field.next('.invalid-feedback').text(errorMsg).show();
|
||||
}
|
||||
|
||||
return isValid;
|
||||
}
|
||||
|
||||
// 手機號碼驗證,包含資料庫檢查
|
||||
function validatePhoneField(field) {
|
||||
const value = field.val().trim();
|
||||
const phonePattern = /^[0-9]{10}$/;
|
||||
|
||||
// 驗證格式
|
||||
if (!phonePattern.test(value)) {
|
||||
field.addClass('is-invalid');
|
||||
$("#checkphone").text('請輸入有效的 10 位手機號碼。').show();
|
||||
return Promise.resolve(false);
|
||||
}
|
||||
|
||||
// 檢查手機號是否已被註冊
|
||||
return new Promise((resolve) => {
|
||||
$.ajax({
|
||||
url: "{{ route('member.checkphone') }}",
|
||||
method: 'GET',
|
||||
data: {
|
||||
phone: value
|
||||
},
|
||||
success: function(response) {
|
||||
if (response.status === 'error') {
|
||||
field.addClass('is-invalid');
|
||||
$("#checkphone").text(response.msg).show(); // 顯示伺服器返回的錯誤訊息
|
||||
resolve(false);
|
||||
} else {
|
||||
field.removeClass('is-invalid');
|
||||
$("#checkphone").hide(); // 隱藏錯誤訊息
|
||||
resolve(true);
|
||||
}
|
||||
},
|
||||
error: function() {
|
||||
field.addClass('is-invalid');
|
||||
$("#checkphone").text('檢查手機號時發生錯誤,請稍後再試。').show();
|
||||
resolve(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
// 綁定每個欄位的失焦事件
|
||||
$('#formAuthentication input').on('blur', function() {
|
||||
if ($(this).attr('id') === 'phone') {
|
||||
validatePhoneField($(this));
|
||||
} else {
|
||||
validateField($(this));
|
||||
}
|
||||
});
|
||||
|
||||
// 表單提交事件
|
||||
$('#formAuthentication').on('submit', async function(event) {
|
||||
event.preventDefault(); // 阻止表單默認提交
|
||||
|
||||
let isFormValid = true;
|
||||
|
||||
// 驗證其他欄位(同步驗證)
|
||||
$('#formAuthentication input').not('#phone').each(function() {
|
||||
if (!validateField($(this))) {
|
||||
isFormValid = false;
|
||||
}
|
||||
});
|
||||
|
||||
// 驗證手機欄位(非同步驗證)
|
||||
const isPhoneValid = await validatePhoneField($('#phone'));
|
||||
|
||||
// 如果所有欄位均有效,執行表單提交
|
||||
if (isFormValid && isPhoneValid) {
|
||||
$.ajax({
|
||||
url: "{{ route('member.register.create') }}",
|
||||
type: 'POST',
|
||||
data: $(this).serialize(),
|
||||
success: function(response) {
|
||||
Swal.fire({
|
||||
title: '成功',
|
||||
text: '註冊成功',
|
||||
icon: 'success',
|
||||
confirmButtonText: '確定'
|
||||
}).then(() => {
|
||||
window.location.href = "{{ route('member.index') }}";
|
||||
});
|
||||
},
|
||||
error: function() {
|
||||
Swal.fire({
|
||||
title: '失敗',
|
||||
text: '註冊失敗,請再試一次。',
|
||||
icon: 'error',
|
||||
confirmButtonText: '確定'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
|
||||
@ -1 +1,202 @@
|
||||
<h1>hello world</h1>
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
<style>
|
||||
.table th,
|
||||
.table td {
|
||||
white-space: nowrap;
|
||||
/* 禁止文字換行 */
|
||||
text-align: center;
|
||||
/* 內容置中 */
|
||||
overflow: hidden;
|
||||
/* 隱藏超出內容 */
|
||||
text-overflow: ellipsis;
|
||||
/* 超出用省略號顯示 */
|
||||
}
|
||||
|
||||
.table th {
|
||||
width: auto;
|
||||
/* 可根據內容自適應,但不要超出 */
|
||||
}
|
||||
|
||||
.table {
|
||||
width: 100%;
|
||||
/* 撐滿父容器 */
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
<!-- / Navbar -->
|
||||
|
||||
<!-- Content wrapper -->
|
||||
<div class="content-wrapper">
|
||||
|
||||
<!-- Content -->
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
|
||||
<!-- Header -->
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<div class="card mb-6">
|
||||
<div class="user-profile-header-banner">
|
||||
<img src="https://cafeg.ukyo.idv.tw/assets/img/pages/profile-banner.png" style="width:100%; height:200px;" alt="Banner image" class="rounded-top">
|
||||
</div>
|
||||
<div class="user-profile-header d-flex flex-column flex-sm-row text-sm-start text-center mb-5">
|
||||
<div class="flex-shrink-0 mt-n2 mx-sm-0 mx-auto">
|
||||
@if(Auth::guard('member')->user()->avatar)
|
||||
<img src="{{Auth::guard('member')->user()->avatar}}" style="width:100px;hieght:100px;" alt="user image" class="d-block h-auto ms-0 ms-sm-5 rounded-4 user-profile-img">
|
||||
@else
|
||||
<img src="../../assets/img/avatars/1.png" style="width:100px;hieght:100px;" alt="user image" class="d-block h-auto ms-0 ms-sm-5 rounded-4 user-profile-img">
|
||||
@endif
|
||||
</div>
|
||||
<div class="flex-grow-1 mt-4 mt-sm-12">
|
||||
<div class="d-flex align-items-md-end align-items-sm-start align-items-center justify-content-md-between justify-content-start mx-5 flex-md-row flex-column gap-6">
|
||||
<div class="user-profile-info">
|
||||
<h4 class="mb-2">{{Auth::guard('member')->user()->name}}</h4>
|
||||
<ul class="list-inline mb-0 d-flex align-items-center flex-wrap justify-content-sm-start justify-content-center gap-4">
|
||||
<li class="list-inline-item">
|
||||
<i class='ri-User-line me-2 ri-24px'></i><span class="fw-medium">{{Auth::guard('member')->user()->Level_Name}}</span>
|
||||
</li>
|
||||
<li class="list-inline-item">
|
||||
<i class='ri-home-heart-fill me-2 ri-24px'></i><span class="fw-medium">客戶編號 : {{Auth::guard('member')->user()->id}}</span>
|
||||
</li>
|
||||
<li class="list-inline-item">
|
||||
<i class="ri-calendar-line me-2 ri-24px"></i>
|
||||
<span class="fw-medium">
|
||||
加 入 : {{ \Carbon\Carbon::parse(Auth::guard('member')->user()->created_at)->format('Y 年 m 月') }}
|
||||
</span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<a href="javascript:void(0)" class="btn btn-primary" id="submit-btn">
|
||||
<i class="ri-qr-code-fill ri-16px me-2"></i>顯示兌換編碼
|
||||
</a>
|
||||
</div>
|
||||
<div class="card mb-12" id="promocode">
|
||||
<h5 class="card-header">兌換編碼</h5>
|
||||
<div class="card-body">
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input type="text" class="form-control" id="floatingInput" aria-describedby="floatingInputHelp">
|
||||
<label for="floatingInput">兌換碼</label>
|
||||
{{-- <div id="floatingInputHelp" class="form-text">We'll never share your details with anyone else.</div> --}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xl-4 col-lg-5 col-md-5">
|
||||
<!-- About User -->
|
||||
<div class="card mb-6">
|
||||
<div class="card-body">
|
||||
<small class="card-text text-uppercase text-muted small">QRCode</small>
|
||||
<div class="d-flex justify-content-center" id="qrcode"></div> <!-- Flexbox居中 -->
|
||||
</div>
|
||||
</div>
|
||||
<!--/ About User -->
|
||||
</div>
|
||||
<div class="col-xl-8 col-lg-7 col-md-7">
|
||||
<!-- Activity Timeline -->
|
||||
<div class="card card-action mb-6">
|
||||
<div class="card-header align-items-center">
|
||||
<h5 class="card-action-title mb-0"><i class='ri-bar-chart-2-line ri-24px text-body me-4'></i>消費紀錄</h5>
|
||||
</div>
|
||||
<div class="card-body pt-5">
|
||||
<!-- Order List Table -->
|
||||
<div class="card">
|
||||
<div class="card-datatable table-responsive">
|
||||
<table class="datatables-order table">
|
||||
<thead>
|
||||
<tr>
|
||||
|
||||
<th>訂單號</th>
|
||||
<th>日期</th>
|
||||
<th>品項</th>
|
||||
<th>金額</th>
|
||||
<th>狀態</th>
|
||||
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>000001</td>
|
||||
<td>2025/01/01</td>
|
||||
<td>大杯 冰拿鐵</td>
|
||||
<td class="text-danger">60</td>
|
||||
<td class="text-success">成功</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>000002</td>
|
||||
<td>2025/01/01</td>
|
||||
<td>大杯 冰拿鐵</td>
|
||||
<td class="text-danger">60</td>
|
||||
<td class="text-success">成功</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--/ Activity Timeline -->
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- / Header -->
|
||||
|
||||
<!-- Navbar pills -->
|
||||
|
||||
<!--/ User Profile Content -->
|
||||
|
||||
</div>
|
||||
<!-- / Content -->
|
||||
|
||||
</div>
|
||||
<!-- beautify ignore:end -->
|
||||
|
||||
<!-- Include necessary scripts -->
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script src="https://cdn.rawgit.com/davidshimjs/qrcodejs/gh-pages/qrcode.min.js"></script>
|
||||
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
$("#promocode").hide();
|
||||
var qrcode = new QRCode(document.getElementById("qrcode"), {
|
||||
text: "https://www.example.com", // 要顯示的內容
|
||||
width: 250, // QR code 的寬度
|
||||
height: 250 // QR code 的高度
|
||||
});
|
||||
});
|
||||
$("#submit-btn").on('click', function() {
|
||||
var id = "{{Auth::guard('member')->user()->id}}";
|
||||
$("#promocode").show();
|
||||
|
||||
console.log('id:', id);
|
||||
// 發送 AJAX 請求
|
||||
$.ajax({
|
||||
url: "{{route('member.getpromocode')}}", // 設定你的路由 URL
|
||||
type: 'POST'
|
||||
, data: {
|
||||
_token: '{{ csrf_token() }}', // CSRF token
|
||||
id: id
|
||||
}
|
||||
, success: function(response) {
|
||||
|
||||
$("#floatingInput").val(response.promocode);
|
||||
|
||||
console.log(response); // 顯示後端回應資料
|
||||
}
|
||||
, error: function(xhr, status, error) {
|
||||
console.log(xhr.responseText); // 顯示錯誤資訊
|
||||
}
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
|
||||
@endsection
|
||||
|
||||
391
resources/views/front/member/page-profile.blade.php
Normal file
391
resources/views/front/member/page-profile.blade.php
Normal file
@ -0,0 +1,391 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('content')
|
||||
|
||||
<!-- Content -->
|
||||
<div class="position-relative">
|
||||
<div class="authentication-wrapper authentication-basic container-p-y p-4 p-sm-0">
|
||||
<div class="authentication-inner py-6">
|
||||
|
||||
<!-- Login -->
|
||||
<div class="card p-md-7 p-1">
|
||||
<!-- Logo -->
|
||||
<div class="app-brand justify-content-center mt-5">
|
||||
<a href="#" class="app-brand-link gap-2">
|
||||
<span class="app-brand-logo demo"><span>
|
||||
<img src="{{asset('assets/img/logo/cafeg-logo.png')}}" width="50px" height="50px" alt="{{asset('img/logo/cafeg-logo.png')}}"> </img>
|
||||
|
||||
</span>
|
||||
</span>
|
||||
<span class="app-brand-text demo text-heading fw-semibold">
|
||||
<img src="{{asset('assets/img/logo/cafeg-logo-h.png')}}" width="120px" height="50px" alt="{{asset('img/logo/cafeg-logo.png')}}"> </img>
|
||||
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<!-- /Logo -->
|
||||
@php
|
||||
if(empty($data)){
|
||||
$data = Auth::guard('member')->user();
|
||||
unset($data['password']);
|
||||
}
|
||||
@endphp
|
||||
<div class="card-body mt-1">
|
||||
<h4 class="mb-1">卡菲姬個人資料</h4>
|
||||
<p class="mb-5">Hi, <span class="text-ifno"> {{$data->name }} 用戶 </span> 歡迎你 ! ,請花幾分鐘完善資料</p>
|
||||
|
||||
<div class="card" id="editUser">
|
||||
<div class="content">
|
||||
<div class="body p-0">
|
||||
<div class="text-center mb-6">
|
||||
<h4 class="mb-2">編輯您的資訊</h4>
|
||||
<p class="mb-6">更新用戶詳細資訊</p>
|
||||
</div>
|
||||
<form id="editUserForm" class="row g-5">
|
||||
<!-- 暱稱 -->
|
||||
<div class="col-12">
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input readonly type="text" id="modalEditUserFirstName" name="modalEditUserFirstName" class="form-control" value="{{$data->name}}" placeholder="暱稱" aria-label="暱稱" />
|
||||
<label for="modalEditUserFirstName">暱稱</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Email -->
|
||||
<div class="col-12">
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input type="email" id="formValidationEmail" class="form-control" placeholder="john.doe@example.com" aria-label="Email" required value="{{$data->email ?? ''}}" />
|
||||
<label for="formValidationEmail">Email</label>
|
||||
<div class="invalid-feedback">請輸入有效的 Email</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 密碼 -->
|
||||
<div class="col-12">
|
||||
<div class="form-password-toggle">
|
||||
<div class="input-group input-group-merge">
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input type="password" id="basic-default-password" class="form-control" placeholder="密碼" aria-label="密碼" value="{{$data->password ?? ''}}" />
|
||||
<label for="basic-default-password">密碼</label>
|
||||
<div class="invalid-feedback">請輸入有效密碼</div>
|
||||
|
||||
</div>
|
||||
<span class="input-group-text cursor-pointer" id="basic-default-password3">
|
||||
<i class="ri-eye-off-line"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 確認密碼 -->
|
||||
<div class="col-12">
|
||||
<div class="form-password-toggle">
|
||||
<div class="input-group input-group-merge">
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input type="password" id="formValidationConfirmPass" name="formValidationConfirmPass" class="form-control" placeholder="確認密碼" aria-label="確認密碼" value="{{$data->password ?? ''}}" />
|
||||
<label for="formValidationConfirmPass">確認密碼</label>
|
||||
<div class="invalid-feedback">密碼與確認密碼不相符</div>
|
||||
|
||||
</div>
|
||||
<span class="input-group-text cursor-pointer" id="multicol-confirm-password2">
|
||||
<i class="ri-eye-off-line"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 電話 -->
|
||||
<div class="col-12">
|
||||
<div class="input-group input-group-merge">
|
||||
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input type="text" id="modalEditUserPhone" name="modalEditUserPhone" class="form-control phone-number-mask" value="{{$data->phone ?? ''}}" placeholder="0920111222" aria-label="電話" />
|
||||
<label for="modalEditUserPhone">電話</label>
|
||||
<div class="invalid-feedback">請輸入有效電話</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 按鈕 -->
|
||||
<div class="col-12 text-center d-flex flex-wrap justify-content-center gap-4 row-gap-4">
|
||||
<button type="submit" class="btn btn-primary">送出</button>
|
||||
<button id='cancel' type="reset" class="btn btn-outline-secondary" data-bs-dismiss="modal" aria-label="Close">
|
||||
取消
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--/ Content -->
|
||||
|
||||
<!--/ Layout Content -->
|
||||
|
||||
|
||||
{{-- <div class="buy-now">
|
||||
<a href="#" target="" class="btn btn-danger btn-buy-now">Buy Now</a>
|
||||
</div> --}}
|
||||
|
||||
|
||||
<!-- Include Scripts -->
|
||||
<!-- $isFront is used to append the front layout scripts only on the front layout otherwise the variable will be blank -->
|
||||
<!-- BEGIN: Vendor JS-->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/jquery/jquery.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/helpers.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/popper/popper.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/bootstrap.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/node-waves/node-waves.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/perfect-scrollbar/perfect-scrollbar.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/hammer/hammer.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/typeahead-js/typeahead.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/menu.js" />
|
||||
<script type="module" src="{{asset('assets')}}/vendor/libs/jquery/jquery.js"></script>
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/@form-validation/popular.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/helpers.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/@form-validation/bootstrap5.js" />
|
||||
{{-- <link rel="modulepreload" href="{{asset('assets')}}/index.js" /> --}}
|
||||
{{-- <link rel="modulepreload" href="{{asset('assets')}}/auto.js" /> --}}
|
||||
<script type="module" src="{{asset('assets')}}/vendor/libs/@form-validation/popular.js">
|
||||
</script>
|
||||
<script type="module" src="{{asset('assets')}}/vendor/libs/@form-validation/bootstrap5.js"></script>
|
||||
<script type="module" src="{{asset('assets')}}/vendor/libs/@form-validation/auto-focus.js"></script>
|
||||
<!-- END: Page Vendor JS-->
|
||||
<!-- BEGIN: Theme JS-->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/js/main.js" />
|
||||
<script type="module" src="{{asset('assets')}}/js/main.js"></script>
|
||||
<!-- END: Theme JS-->
|
||||
<!-- Pricing Modal JS-->
|
||||
<!-- END: Pricing Modal JS-->
|
||||
<!-- BEGIN: Page JS-->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/js/pages-auth.js" />
|
||||
<script type="module" src="{{asset('assets')}}/js/pages-auth.js"></script>
|
||||
<!-- END: Page JS-->
|
||||
<script src="{{asset('assets')}}/js/form-validation.js"></script>
|
||||
|
||||
</body>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script>
|
||||
$(document).ready(function() {
|
||||
|
||||
$("#formValidationEmail").on('blur', function() {
|
||||
var email = $(this).val(); // 獲取電子郵件輸入框的值
|
||||
|
||||
// 簡單的電子郵件格式驗證(可選)
|
||||
if (!email.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/)) {
|
||||
Swal.fire({
|
||||
icon: 'error'
|
||||
, title: '格式錯誤'
|
||||
, text: '請輸入有效的電子郵件地址!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 發送 AJAX 請求到伺服器進行進一步驗證
|
||||
$.ajax({
|
||||
url: "{{route('member.validemail')}}", // 替換成你的 API 路徑
|
||||
type: 'get', // 或 'GET',根據你的需求
|
||||
data: {
|
||||
email: email
|
||||
}
|
||||
, headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') // 如果使用 Laravel CSRF 保護
|
||||
}
|
||||
, success: function(response) {
|
||||
// 如果電子郵件已被註冊
|
||||
if (!response.valid) {
|
||||
Swal.fire({
|
||||
icon: 'warning'
|
||||
, title: '電子郵件已被註冊'
|
||||
, text: '該電子郵件已存在,請選擇下一步操作。'
|
||||
, showCancelButton: true
|
||||
, confirmButtonText: '驗證電子郵件'
|
||||
, cancelButtonText: '我知道了,換一個'
|
||||
, reverseButtons: true // 按鈕排列反向
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
// 使用者選擇驗證電子郵件
|
||||
Swal.fire({
|
||||
icon: 'info'
|
||||
, title: '驗證發送中'
|
||||
, text: '已向該電子郵件發送驗證信,請檢查郵箱。'
|
||||
});
|
||||
// 可在此處調用發送驗證郵件的函式
|
||||
sendVerificationEmail(email);
|
||||
} else if (result.dismiss === Swal.DismissReason.cancel) {
|
||||
// 使用者選擇換一個電子郵件
|
||||
$('#formValidationEmail').val(''); // 清空輸入框
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Swal.fire({
|
||||
icon: 'success'
|
||||
, title: '電子郵件可用'
|
||||
, text: '您可以繼續使用此電子郵件。'
|
||||
});
|
||||
}
|
||||
}
|
||||
, error: function(xhr) {
|
||||
// 錯誤處理
|
||||
Swal.fire({
|
||||
icon: 'error'
|
||||
, title: '伺服器錯誤'
|
||||
, text: '驗證失敗,請稍後再試!'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
// 發送驗證郵件的函式
|
||||
function sendVerificationEmail(email) {
|
||||
console.log('email:', email);
|
||||
$.ajax({
|
||||
url: "{{route('member.sendemail')}}", // 替換為發送驗證郵件的 API
|
||||
type: 'POST'
|
||||
, data: {
|
||||
email: email
|
||||
}
|
||||
, headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
||||
}
|
||||
, success: function(Response) {
|
||||
console.log('Response:', Response);
|
||||
|
||||
if (Response.status == 'success') {
|
||||
Swal.fire({
|
||||
icon: 'success'
|
||||
, title: '驗證信已發送'
|
||||
, text: '請檢查您的電子郵件以完成驗證。'
|
||||
});
|
||||
}
|
||||
|
||||
}
|
||||
, error: function() {
|
||||
Swal.fire({
|
||||
icon: 'error'
|
||||
, title: '驗證信發送失敗'
|
||||
, text: '請稍後再試!'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$('#editUserForm').on('submit', function(e) {
|
||||
e.preventDefault(); // 防止表單提交
|
||||
|
||||
let valid = true;
|
||||
|
||||
// Email 驗證
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
const emailInput = $('#formValidationEmail');
|
||||
if (!emailRegex.test(emailInput.val())) {
|
||||
valid = false;
|
||||
emailInput.addClass('is-invalid');
|
||||
} else {
|
||||
emailInput.removeClass('is-invalid');
|
||||
}
|
||||
|
||||
// 密碼長度驗證
|
||||
const passwordInput = $('#basic-default-password');
|
||||
//if (passwordInput.val().length < 6) {
|
||||
// valid = false;
|
||||
//passwordInput.addClass('is-invalid');
|
||||
//} else {
|
||||
// passwordInput.removeClass('is-invalid');
|
||||
//}
|
||||
|
||||
// 確認密碼驗證
|
||||
const confirmPasswordInput = $('#formValidationConfirmPass');
|
||||
if (passwordInput.val() !== confirmPasswordInput.val()) {
|
||||
valid = false;
|
||||
confirmPasswordInput.addClass('is-invalid');
|
||||
} else {
|
||||
confirmPasswordInput.removeClass('is-invalid');
|
||||
}
|
||||
|
||||
// 手機號碼驗證
|
||||
const phoneRegex = /^09\d{8}$/;
|
||||
const phoneInput = $('#modalEditUserPhone');
|
||||
if (!phoneRegex.test(phoneInput.val())) {
|
||||
valid = false;
|
||||
phoneInput.addClass('is-invalid');
|
||||
} else {
|
||||
phoneInput.removeClass('is-invalid');
|
||||
}
|
||||
|
||||
// 若通過所有驗證,發送 AJAX 請求
|
||||
if (valid) {
|
||||
const formData = {
|
||||
email: emailInput.val()
|
||||
, password: passwordInput.val()
|
||||
, phone: phoneInput.val()
|
||||
, };
|
||||
|
||||
$.ajax({
|
||||
url: "{{ route('member.profile.update') }}"
|
||||
, type: 'put'
|
||||
, data: formData
|
||||
, headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
||||
}
|
||||
, success: function(response) {
|
||||
Swal.fire({
|
||||
title: '成功'
|
||||
, text: "{{ session('success') }}"
|
||||
, icon: 'success'
|
||||
, confirmButtonText: '确定'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
// 跳轉到 member.index 路由
|
||||
window.location.href = "{{ route('member.index') }}";
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
}
|
||||
, error: function(error) {
|
||||
Swal.fire({
|
||||
title: '失敗'
|
||||
, text: "更新失敗"
|
||||
, icon: 'error'
|
||||
, confirmButtonText: '确定'
|
||||
});
|
||||
}
|
||||
, });
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$("#cancel").on('click', function() {
|
||||
let valid = true;
|
||||
|
||||
// Email 驗證
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
const emailInput = $('#formValidationEmail');
|
||||
if (!emailRegex.test(emailInput.val())) {
|
||||
valid = false;
|
||||
emailInput.addClass('is-invalid');
|
||||
} else {
|
||||
emailInput.removeClass('is-invalid');
|
||||
}
|
||||
if (valid == true) {
|
||||
window.location.href = "{{ route('member.index') }}";
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
</script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
|
||||
|
||||
@endsection
|
||||
@ -1 +1,540 @@
|
||||
<h1> 需完善profile</h1>
|
||||
<!DOCTYPE html>
|
||||
|
||||
<html lang="en" class="dark-style layout-menu-fixed customizer-hide" dir="ltr" data-theme="theme-default" data-assets-path="https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo/assets/" data-base-url="https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo-4" data-framework="laravel" data-template="blank-menu-theme-default-dark" data-style="dark">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
|
||||
|
||||
<title>卡菲姬APP</title>
|
||||
<meta name="description" content="Materialize – is the most developer friendly & highly customizable Admin Dashboard Template." />
|
||||
<meta name="keywords" content="dashboard, material, material design, bootstrap 5 dashboard, bootstrap 5 design, bootstrap 5">
|
||||
<!-- laravel CRUD token -->
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
|
||||
<!-- Canonical SEO -->
|
||||
<link rel="canonical" href="https://1.envato.market/materialize_admin">
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/x-icon" href="../../demo/assets/img/favicon/favicon.ico" />
|
||||
|
||||
|
||||
<!-- Include Styles -->
|
||||
<!-- $isFront is used to append the front layout styles only on the front layout otherwise the variable will be blank -->
|
||||
<!-- BEGIN: Theme CSS-->
|
||||
<!-- Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com">
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
|
||||
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/fonts/remixicon/remixicon.css" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/fonts/flag-icons.css" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/libs/node-waves/node-waves.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/fonts/remixicon/remixicon.css" class="" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/fonts/flag-icons.css" class="" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/libs/node-waves/node-waves.css" class="" />
|
||||
<!-- Core CSS -->
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/css/core-dark.css" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/css/theme-default-dark.css" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/css/demo.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/css/core-dark.css" class="template-customizer-core-css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/css/theme-default-dark.css" class="template-customizer-theme-css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/css/demo.css" class="" />
|
||||
|
||||
<!-- Vendor Styles -->
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/libs/perfect-scrollbar/perfect-scrollbar.css" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/libs/typeahead-js/typeahead.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/libs/perfect-scrollbar/perfect-scrollbar.css" class="" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/libs/typeahead-js/typeahead.css" class="" />
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/libs/@form-validation/form-validation.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/libs/@form-validation/form-validation.css" class="" />
|
||||
<!-- Page Styles -->
|
||||
<link rel="preload" as="style" href="{{asset('assets')}}/vendor/css/pages/page-auth.css" />
|
||||
<link rel="stylesheet" href="{{asset('assets')}}/vendor/css/pages/page-auth.css" class="" />
|
||||
<!-- Include Scripts for customizer, helper, analytics, config -->
|
||||
<!-- $isFront is used to append the front layout scriptsIncludes only on the front layout otherwise the variable will be blank -->
|
||||
<!-- laravel style -->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/helpers.js" />
|
||||
<script type="module" src="{{asset('assets')}}/vendor/js/helpers.js"></script>
|
||||
<!-- beautify ignore:start -->
|
||||
<!--! Template customizer & Theme config files MUST be included after core stylesheets and helpers.js in the <head> section -->
|
||||
<!--? Template customizer: To hide customizer set displayCustomizer value false in config.js. -->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/template-customizer.js" />
|
||||
<!--? Config: Mandatory theme config file contain global vars & default theme options, Set your preferred theme option in this file. -->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/js/config.js" /><script type="module" src="{{asset('assets')}}/js/config.js"></script>
|
||||
{{-- <script type="module">
|
||||
window.templateCustomizer = new TemplateCustomizer({
|
||||
cssPath: '',
|
||||
themesPath: '',
|
||||
defaultStyle: "dark",
|
||||
defaultShowDropdownOnHover: "1", // true/false (for horizontal layout only)
|
||||
displayCustomizer: "1",
|
||||
lang: 'en',
|
||||
pathResolver: function(path) {
|
||||
var resolvedPaths = {
|
||||
// Core stylesheets
|
||||
'core.scss': 'https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo/build/assets/core-kL5gEEKA.css',
|
||||
'core-dark.scss': 'https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo/build/assets/core-dark-DFvmi5J3.css',
|
||||
|
||||
// Themes
|
||||
'theme-default.scss': 'https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo/build/assets/theme-default-Bt2z4DrM.css',
|
||||
'theme-default-dark.scss': 'https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo/build/assets/theme-default-dark-CHvAJUy2.css',
|
||||
'theme-bordered.scss': 'https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo/build/assets/theme-bordered-DhjhTV9k.css',
|
||||
'theme-bordered-dark.scss': 'https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo/build/assets/theme-bordered-dark-C25VfhpZ.css',
|
||||
'theme-semi-dark.scss': 'https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo/build/assets/theme-semi-dark-D80v88qZ.css',
|
||||
'theme-semi-dark-dark.scss': 'https://demos.pixinvent.com/materialize-html-laravel-admin-template/demo/build/assets/theme-semi-dark-dark-BZrM7P_B.css',
|
||||
}
|
||||
return resolvedPaths[path] || path;
|
||||
},
|
||||
'controls': ["rtl","style","headerType","contentLayout","layoutCollapsed","layoutNavbarOptions","themes"],
|
||||
});
|
||||
</script>--}}
|
||||
<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start': new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0], j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src= 'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f); })(window,document,'script','dataLayer','GTM-5J3LMKC'); </script>
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<noscript><iframe src="https://www.googletagmanager.com/ns.html?id=GTM-5J3LMKC" height="0" width="0" style="display: none; visibility: hidden"></iframe></noscript>
|
||||
|
||||
<!-- Layout Content -->
|
||||
|
||||
<!-- Content -->
|
||||
<div class="position-relative">
|
||||
<div class="authentication-wrapper authentication-basic container-p-y p-4 p-sm-0">
|
||||
<div class="authentication-inner py-6">
|
||||
|
||||
<!-- Login -->
|
||||
<div class="card p-md-7 p-1">
|
||||
<!-- Logo -->
|
||||
<div class="app-brand justify-content-center mt-5">
|
||||
<a href="#" class="app-brand-link gap-2">
|
||||
<span class="app-brand-logo demo"><span>
|
||||
<img src="{{asset('assets/img/logo/cafeg-logo.png')}}" width="50px" height="50px" alt="{{asset('img/logo/cafeg-logo.png')}}"> </img>
|
||||
|
||||
</span>
|
||||
</span>
|
||||
<span class="app-brand-text demo text-heading fw-semibold">
|
||||
<img src="{{asset('assets/img/logo/cafeg-logo-h.png')}}" width="120px" height="50px" alt="{{asset('img/logo/cafeg-logo.png')}}"> </img>
|
||||
|
||||
</span>
|
||||
</a>
|
||||
</div>
|
||||
<!-- /Logo -->
|
||||
@php
|
||||
if(empty($data)){
|
||||
$data = Auth::guard('member')->user();
|
||||
unset($data['password']);
|
||||
}
|
||||
@endphp
|
||||
<div class="card-body mt-1">
|
||||
<h4 class="mb-1">卡菲姬個人資料</h4>
|
||||
<p class="mb-5">Hi, <span class="text-ifno"> {{$data->name }} 用戶 </span> 歡迎你 ! ,請花幾分鐘完善資料</p>
|
||||
|
||||
<div class="card" id="editUser">
|
||||
<div class="content">
|
||||
<div class="body p-0">
|
||||
<div class="text-center mb-6">
|
||||
<h4 class="mb-2">編輯您的資訊</h4>
|
||||
<p class="mb-6">更新用戶詳細資訊</p>
|
||||
</div>
|
||||
<form id="editUserForm" class="row g-5" >
|
||||
<!-- 暱稱 -->
|
||||
<div class="col-12">
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input
|
||||
readonly
|
||||
type="text"
|
||||
id="modalEditUserFirstName"
|
||||
name="modalEditUserFirstName"
|
||||
class="form-control"
|
||||
value="{{$data->name}}"
|
||||
placeholder="暱稱"
|
||||
aria-label="暱稱"
|
||||
/>
|
||||
<label for="modalEditUserFirstName">暱稱</label>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Email -->
|
||||
<div class="col-12">
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input
|
||||
type="email"
|
||||
id="formValidationEmail"
|
||||
class="form-control"
|
||||
placeholder="john.doe@example.com"
|
||||
aria-label="Email"
|
||||
required
|
||||
value="{{$data->email ?? ''}}"
|
||||
|
||||
/>
|
||||
<label for="formValidationEmail">Email</label>
|
||||
<div class="invalid-feedback">請輸入有效的 Email</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 密碼 -->
|
||||
<div class="col-12">
|
||||
<div class="form-password-toggle">
|
||||
<div class="input-group input-group-merge">
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input
|
||||
type="password"
|
||||
id="basic-default-password"
|
||||
class="form-control"
|
||||
placeholder="密碼"
|
||||
aria-label="密碼"
|
||||
value="{{$data->password ?? ''}}"
|
||||
|
||||
/>
|
||||
<label for="basic-default-password">密碼</label>
|
||||
<div class="invalid-feedback">請輸入有效密碼</div>
|
||||
|
||||
</div>
|
||||
<span
|
||||
class="input-group-text cursor-pointer"
|
||||
id="basic-default-password3"
|
||||
>
|
||||
<i class="ri-eye-off-line"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 確認密碼 -->
|
||||
<div class="col-12">
|
||||
<div class="form-password-toggle">
|
||||
<div class="input-group input-group-merge">
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input
|
||||
type="password"
|
||||
id="formValidationConfirmPass"
|
||||
name="formValidationConfirmPass"
|
||||
class="form-control"
|
||||
placeholder="確認密碼"
|
||||
aria-label="確認密碼"
|
||||
value="{{$data->password ?? ''}}"
|
||||
|
||||
/>
|
||||
<label for="formValidationConfirmPass">確認密碼</label>
|
||||
<div class="invalid-feedback">密碼與確認密碼不相符</div>
|
||||
|
||||
</div>
|
||||
<span
|
||||
class="input-group-text cursor-pointer"
|
||||
id="multicol-confirm-password2"
|
||||
>
|
||||
<i class="ri-eye-off-line"></i>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- 電話 -->
|
||||
<div class="col-12">
|
||||
<div class="input-group input-group-merge">
|
||||
|
||||
<div class="form-floating form-floating-outline">
|
||||
<input
|
||||
type="text"
|
||||
id="modalEditUserPhone"
|
||||
name="modalEditUserPhone"
|
||||
class="form-control phone-number-mask"
|
||||
value="{{$data->phone ?? ''}}"
|
||||
placeholder="0920111222"
|
||||
aria-label="電話"
|
||||
/>
|
||||
<label for="modalEditUserPhone">電話</label>
|
||||
<div class="invalid-feedback">請輸入有效電話</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- 按鈕 -->
|
||||
<div
|
||||
class="col-12 text-center d-flex flex-wrap justify-content-center gap-4 row-gap-4"
|
||||
|
||||
>
|
||||
<button type="submit" class="btn btn-primary">送出</button>
|
||||
<button
|
||||
id = 'cancel'
|
||||
type="reset"
|
||||
class="btn btn-outline-secondary"
|
||||
data-bs-dismiss="modal"
|
||||
aria-label="Close"
|
||||
>
|
||||
取消
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!--/ Content -->
|
||||
|
||||
<!--/ Layout Content -->
|
||||
|
||||
|
||||
{{-- <div class="buy-now">
|
||||
<a href="#" target="" class="btn btn-danger btn-buy-now">Buy Now</a>
|
||||
</div> --}}
|
||||
|
||||
|
||||
<!-- Include Scripts -->
|
||||
<!-- $isFront is used to append the front layout scripts only on the front layout otherwise the variable will be blank -->
|
||||
<!-- BEGIN: Vendor JS-->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/jquery/jquery.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/helpers.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/popper/popper.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/bootstrap.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/node-waves/node-waves.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/perfect-scrollbar/perfect-scrollbar.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/hammer/hammer.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/typeahead-js/typeahead.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/menu.js" />
|
||||
<script type="module" src="{{asset('assets')}}/vendor/libs/jquery/jquery.js"></script>
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/@form-validation/popular.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/js/helpers.js" />
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/vendor/libs/@form-validation/bootstrap5.js" />
|
||||
{{-- <link rel="modulepreload" href="{{asset('assets')}}/index.js" /> --}}
|
||||
{{-- <link rel="modulepreload" href="{{asset('assets')}}/auto.js" /> --}}
|
||||
<script type="module" src="{{asset('assets')}}/vendor/libs/@form-validation/popular.js">
|
||||
</script><script type="module" src="{{asset('assets')}}/vendor/libs/@form-validation/bootstrap5.js"></script>
|
||||
<script type="module" src="{{asset('assets')}}/vendor/libs/@form-validation/auto-focus.js"></script>
|
||||
<!-- END: Page Vendor JS-->
|
||||
<!-- BEGIN: Theme JS-->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/js/main.js" />
|
||||
<script type="module" src="{{asset('assets')}}/js/main.js"></script>
|
||||
<!-- END: Theme JS-->
|
||||
<!-- Pricing Modal JS-->
|
||||
<!-- END: Pricing Modal JS-->
|
||||
<!-- BEGIN: Page JS-->
|
||||
<link rel="modulepreload" href="{{asset('assets')}}/js/pages-auth.js" />
|
||||
<script type="module" src="{{asset('assets')}}/js/pages-auth.js"></script>
|
||||
<!-- END: Page JS-->
|
||||
<script src="{{asset('assets')}}/js/form-validation.js"></script>
|
||||
|
||||
</body>
|
||||
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
|
||||
<script>
|
||||
$(document).ready(function () {
|
||||
|
||||
$("#formValidationEmail").on('blur', function () {
|
||||
var email = $(this).val(); // 獲取電子郵件輸入框的值
|
||||
|
||||
// 簡單的電子郵件格式驗證(可選)
|
||||
if (!email.match(/^[^\s@]+@[^\s@]+\.[^\s@]+$/)) {
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: '格式錯誤',
|
||||
text: '請輸入有效的電子郵件地址!'
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// 發送 AJAX 請求到伺服器進行進一步驗證
|
||||
$.ajax({
|
||||
url: "{{route('member.validemail')}}", // 替換成你的 API 路徑
|
||||
type: 'get', // 或 'GET',根據你的需求
|
||||
data: {
|
||||
email: email
|
||||
},
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') // 如果使用 Laravel CSRF 保護
|
||||
},
|
||||
success: function (response) {
|
||||
// 如果電子郵件已被註冊
|
||||
if (!response.valid) {
|
||||
Swal.fire({
|
||||
icon: 'warning',
|
||||
title: '電子郵件已被註冊',
|
||||
text: '該電子郵件已存在,請選擇下一步操作。',
|
||||
showCancelButton: true,
|
||||
confirmButtonText: '驗證電子郵件',
|
||||
cancelButtonText: '我知道了,換一個',
|
||||
reverseButtons: true // 按鈕排列反向
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
// 使用者選擇驗證電子郵件
|
||||
Swal.fire({
|
||||
icon: 'info',
|
||||
title: '驗證發送中',
|
||||
text: '已向該電子郵件發送驗證信,請檢查郵箱。'
|
||||
});
|
||||
// 可在此處調用發送驗證郵件的函式
|
||||
sendVerificationEmail(email);
|
||||
} else if (result.dismiss === Swal.DismissReason.cancel) {
|
||||
// 使用者選擇換一個電子郵件
|
||||
$('#formValidationEmail').val(''); // 清空輸入框
|
||||
}
|
||||
});
|
||||
} else {
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: '電子郵件可用',
|
||||
text: '您可以繼續使用此電子郵件。'
|
||||
});
|
||||
}
|
||||
},
|
||||
error: function (xhr) {
|
||||
// 錯誤處理
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: '伺服器錯誤',
|
||||
text: '驗證失敗,請稍後再試!'
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
// 發送驗證郵件的函式
|
||||
function sendVerificationEmail(email) {
|
||||
console.log('email:',email);
|
||||
$.ajax({
|
||||
url: "{{route('member.sendemail')}}", // 替換為發送驗證郵件的 API
|
||||
type: 'POST',
|
||||
data: {
|
||||
email: email
|
||||
},
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
||||
},
|
||||
success: function ( Response) {
|
||||
console.log('Response:',Response);
|
||||
|
||||
if(Response.status =='success'){
|
||||
Swal.fire({
|
||||
icon: 'success',
|
||||
title: '驗證信已發送',
|
||||
text: '請檢查您的電子郵件以完成驗證。'
|
||||
});
|
||||
}
|
||||
|
||||
},
|
||||
error: function () {
|
||||
Swal.fire({
|
||||
icon: 'error',
|
||||
title: '驗證信發送失敗',
|
||||
text: '請稍後再試!'
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
$('#editUserForm').on('submit', function (e) {
|
||||
e.preventDefault(); // 防止表單提交
|
||||
|
||||
let valid = true;
|
||||
|
||||
// Email 驗證
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
const emailInput = $('#formValidationEmail');
|
||||
if (!emailRegex.test(emailInput.val())) {
|
||||
valid = false;
|
||||
emailInput.addClass('is-invalid');
|
||||
} else {
|
||||
emailInput.removeClass('is-invalid');
|
||||
}
|
||||
|
||||
// 密碼長度驗證
|
||||
const passwordInput = $('#basic-default-password');
|
||||
//if (passwordInput.val().length < 6) {
|
||||
// valid = false;
|
||||
//passwordInput.addClass('is-invalid');
|
||||
//} else {
|
||||
// passwordInput.removeClass('is-invalid');
|
||||
//}
|
||||
|
||||
// 確認密碼驗證
|
||||
const confirmPasswordInput = $('#formValidationConfirmPass');
|
||||
if (passwordInput.val() !== confirmPasswordInput.val()) {
|
||||
valid = false;
|
||||
confirmPasswordInput.addClass('is-invalid');
|
||||
} else {
|
||||
confirmPasswordInput.removeClass('is-invalid');
|
||||
}
|
||||
|
||||
// 手機號碼驗證
|
||||
const phoneRegex = /^09\d{8}$/;
|
||||
const phoneInput = $('#modalEditUserPhone');
|
||||
if (!phoneRegex.test(phoneInput.val())) {
|
||||
valid = false;
|
||||
phoneInput.addClass('is-invalid');
|
||||
} else {
|
||||
phoneInput.removeClass('is-invalid');
|
||||
}
|
||||
|
||||
// 若通過所有驗證,發送 AJAX 請求
|
||||
if (valid) {
|
||||
const formData = {
|
||||
email: emailInput.val(),
|
||||
password: passwordInput.val(),
|
||||
phone: phoneInput.val(),
|
||||
};
|
||||
|
||||
$.ajax({
|
||||
url: "{{ route('member.profile.update') }}",
|
||||
type: 'put',
|
||||
data: formData,
|
||||
headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') },
|
||||
success: function (response) {
|
||||
Swal.fire({
|
||||
title: '成功'
|
||||
, text: "{{ session('success') }}"
|
||||
, icon: 'success'
|
||||
, confirmButtonText: '确定'
|
||||
}).then((result) => {
|
||||
if (result.isConfirmed) {
|
||||
// 跳轉到 member.index 路由
|
||||
window.location.href = "{{ route('member.index') }}";
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
},
|
||||
error: function (error) {
|
||||
Swal.fire({
|
||||
title: '失敗'
|
||||
, text: "更新失敗"
|
||||
, icon: 'error'
|
||||
, confirmButtonText: '确定'
|
||||
});
|
||||
},
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$("#cancel").on('click',function(){
|
||||
let valid = true;
|
||||
|
||||
// Email 驗證
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
||||
const emailInput = $('#formValidationEmail');
|
||||
if (!emailRegex.test(emailInput.val())) {
|
||||
valid = false;
|
||||
emailInput.addClass('is-invalid');
|
||||
} else {
|
||||
emailInput.removeClass('is-invalid');
|
||||
}
|
||||
if(valid == true){
|
||||
window.location.href = "{{ route('member.index') }}";
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
</script>
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
|
||||
</html>
|
||||
|
||||
124
resources/views/layouts/admin_app.blade.php
Normal file
124
resources/views/layouts/admin_app.blade.php
Normal file
@ -0,0 +1,124 @@
|
||||
<html lang="en" class="light-style layout-navbar-fixed layout-menu-fixed layout-compact" dir="ltr" data-theme="theme-default" data-assets-path="{{ asset('assets') }}/" data-template="vertical-menu-template-starter" data-style="light">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
|
||||
|
||||
|
||||
<title>卡菲姬後台管理</title>
|
||||
|
||||
<meta name="description" content="" />
|
||||
|
||||
<!-- Favicon -->
|
||||
<link rel="icon" type="image/x-icon" href="{{ asset('assets/img/favicon/favicon.ico') }}" />
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
|
||||
|
||||
<link rel="stylesheet" href="{{ asset('assets/vendor/fonts/remixicon/remixicon.css') }}" />
|
||||
|
||||
|
||||
<!-- Menu waves for no-customizer fix -->
|
||||
<link rel="stylesheet" href="{{ asset('assets/vendor/libs/node-waves/node-waves.css') }}" />
|
||||
|
||||
<!-- Core CSS -->
|
||||
<link rel="stylesheet" href="{{ asset('assets/vendor/css/rtl/core.css') }}" class="template-customizer-core-css" />
|
||||
<link rel="stylesheet" href="{{ asset('assets/vendor/css/rtl/theme-default.css') }}" class="template-customizer-theme-css" />
|
||||
<link rel="stylesheet" href="{{ asset('assets/css/demo.css') }}" />
|
||||
|
||||
<!-- Vendors CSS -->
|
||||
<link rel="stylesheet" href="{{ asset('assets/vendor/libs/perfect-scrollbar/perfect-scrollbar.css') }}" />
|
||||
|
||||
<!-- Page CSS -->
|
||||
|
||||
<!-- Helpers -->
|
||||
<script src="{{ asset('assets/vendor/js/helpers.js') }}"></script>
|
||||
<!--! Template customizer & Theme config files MUST be included after core stylesheets and helpers.js in the <head> section -->
|
||||
<!--? Template customizer: To hide customizer set displayCustomizer value false in config.js. -->
|
||||
<script src="{{ asset('assets/vendor/js/template-customizer.js') }}"></script>
|
||||
<!--? Config: Mandatory theme config file contain global vars & default theme options, Set your preferred theme option in this file. -->
|
||||
<script src="{{ asset('assets/js/config.js') }}"></script>
|
||||
<!-- 在<head>中引入SweetAlert2 CDN -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
|
||||
@yield('header')
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<!-- Layout wrapper -->
|
||||
<div class="layout-wrapper layout-content-navbar">
|
||||
<div class="layout-container">
|
||||
<!-- Menu -->
|
||||
|
||||
@include('layouts.admin_aside')
|
||||
<!-- / Menu -->
|
||||
|
||||
<!-- Layout container -->
|
||||
<div class="layout-page">
|
||||
<!-- Navbar -->
|
||||
|
||||
@include('layouts.admin_navbar')
|
||||
|
||||
<!-- / Navbar -->
|
||||
|
||||
<!-- Content wrapper -->
|
||||
<div class="content-wrapper">
|
||||
<!-- Content -->
|
||||
|
||||
<div class="container-xxl flex-grow-1 container-p-y">
|
||||
@yield('content')
|
||||
</div>
|
||||
<!-- / Content -->
|
||||
|
||||
@include('layouts.admin_footer')
|
||||
|
||||
<div class="content-backdrop fade"></div>
|
||||
</div>
|
||||
<!-- Content wrapper -->
|
||||
</div>
|
||||
<!-- / Layout page -->
|
||||
</div>
|
||||
|
||||
<!-- Overlay -->
|
||||
<div class="layout-overlay layout-menu-toggle"></div>
|
||||
|
||||
<!-- Drag Target Area To SlideIn Menu On Small Screens -->
|
||||
<div class="drag-target"></div>
|
||||
</div>
|
||||
<!-- / Layout wrapper -->
|
||||
|
||||
<!-- Core JS -->
|
||||
<!-- build:js assets/vendor/js/core.js -->
|
||||
<script src="{{ asset('assets/vendor/libs/jquery/jquery.js') }}"></script>
|
||||
<script src="{{ asset('assets/vendor/libs/popper/popper.js') }}"></script>
|
||||
<script src="{{ asset('assets/vendor/js/bootstrap.js') }}"></script>
|
||||
<script src="{{ asset('assets/vendor/libs/node-waves/node-waves.js') }}"></script>
|
||||
<script src="{{ asset('assets/vendor/libs/perfect-scrollbar/perfect-scrollbar.js') }}"></script>
|
||||
<script src="{{ asset('assets/vendor/libs/hammer/hammer.js') }}"></script>
|
||||
|
||||
<script src="{{ asset('assets/vendor/js/menu.js') }}"></script>
|
||||
|
||||
<!-- endbuild -->
|
||||
|
||||
<!-- Vendors JS -->
|
||||
|
||||
<!-- Main JS -->
|
||||
<script src="{{ asset('assets/js/main.js') }}"></script>
|
||||
|
||||
<!-- Page JS -->
|
||||
@yield('scripts')
|
||||
|
||||
<script>
|
||||
//doucument ready functions
|
||||
$(document).ready(function() {
|
||||
console.log('Document ready');
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
</html>
|
||||
61
resources/views/layouts/admin_aside.blade.php
Normal file
61
resources/views/layouts/admin_aside.blade.php
Normal file
@ -0,0 +1,61 @@
|
||||
<aside id="layout-menu" class="layout-menu menu-vertical menu bg-menu-theme">
|
||||
<div class="app-brand demo">
|
||||
<a href="{{url('/')}}" class="app-brand-link">
|
||||
<span class="app-brand-logo demo">
|
||||
<span style="color: var(--bs-primary)">
|
||||
<img src="{{asset('assets/img/logo/cafeg-logo.png')}}" width="50px" height="50px" alt="{{asset('img/logo/cafeg-logo.png')}}"> </img>
|
||||
</span>
|
||||
</span>
|
||||
<img src="{{asset('assets/img/logo/cafeg-logo-h.png')}}" width="120px" height="50px" alt="{{asset('img/logo/cafeg-logo.png')}}"> </img>
|
||||
<span class="app-brand-text demo menu-text fw-semibold ms-2"></span>
|
||||
</a>
|
||||
|
||||
<a href="javascript:void(0);" class="layout-menu-toggle menu-link text-large ms-auto">
|
||||
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M8.47365 11.7183C8.11707 12.0749 8.11707 12.6531 8.47365 13.0097L12.071 16.607C12.4615 16.9975 12.4615 17.6305 12.071 18.021C11.6805 18.4115 11.0475 18.4115 10.657 18.021L5.83009 13.1941C5.37164 12.7356 5.37164 11.9924 5.83009 11.5339L10.657 6.707C11.0475 6.31653 11.6805 6.31653 12.071 6.707C12.4615 7.09747 12.4615 7.73053 12.071 8.121L8.47365 11.7183Z" fill-opacity="0.9" />
|
||||
<path d="M14.3584 11.8336C14.0654 12.1266 14.0654 12.6014 14.3584 12.8944L18.071 16.607C18.4615 16.9975 18.4615 17.6305 18.071 18.021C17.6805 18.4115 17.0475 18.4115 16.657 18.021L11.6819 13.0459C11.3053 12.6693 11.3053 12.0587 11.6819 11.6821L16.657 6.707C17.0475 6.31653 17.6805 6.31653 18.071 6.707C18.4615 7.09747 18.4615 7.73053 18.071 8.121L14.3584 11.8336Z" fill-opacity="0.4" />
|
||||
</svg>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="menu-inner-shadow"> </div>
|
||||
|
||||
<ul class="menu-inner py-1 ps ps--active-y">
|
||||
<li class="menu-header small fw-medium">Getting Started</li>
|
||||
|
||||
@foreach ($menuData[0] as $menu)
|
||||
@if(isset($menu->submenu[0]->url))
|
||||
<li class="menu-item">
|
||||
<a href="" class="menu-link menu-toggle">
|
||||
<i class="{{$menu->icon}}"> </i>
|
||||
<div>{{$menu->name}}</div>
|
||||
</a>
|
||||
@foreach ($menu->submenu as $sub)
|
||||
<ul class="menu-sub">
|
||||
<li class="menu-item">
|
||||
<a href="{{url($sub->url)}}" class="menu-link">
|
||||
<div>{{$sub->name}}</div>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
@endforeach
|
||||
</li>
|
||||
@else
|
||||
<li class="menu-item">
|
||||
<a href="{{url($menu->url)}}" class="menu-link">
|
||||
<i class="{{$menu->icon}}"> </i>
|
||||
<div>{{$menu->name}}</div>
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
|
||||
<div class="ps__rail-x" style="left: 0px; bottom: -427px;">
|
||||
<div class="ps__thumb-x" tabindex="0" style="left: 0px; width: 0px;"></div>
|
||||
</div>
|
||||
<div class="ps__rail-y" style="top: 427px; height: 571px; right: 4px;">
|
||||
<div class="ps__thumb-y" tabindex="0" style="top: 80px; height: 106px;"></div>
|
||||
</div>
|
||||
</ul>
|
||||
</aside>
|
||||
19
resources/views/layouts/admin_footer.blade.php
Normal file
19
resources/views/layouts/admin_footer.blade.php
Normal file
@ -0,0 +1,19 @@
|
||||
<!-- Footer -->
|
||||
<footer class="content-footer footer bg-footer-theme">
|
||||
<div class="container-xxl">
|
||||
<div
|
||||
class="footer-container d-flex align-items-center justify-content-between py-4 flex-md-row flex-column">
|
||||
<div class="text-body mb-2 mb-md-0">
|
||||
©
|
||||
<script>
|
||||
document.write(new Date().getFullYear());
|
||||
</script>
|
||||
, made with <span class="text-danger"><i class="tf-icons ri-heart-fill"></i></span>
|
||||
by
|
||||
<a href="#" target="_blank" class="footer-link">逸奔科技股份有限公司</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
<!-- / Footer -->
|
||||
159
resources/views/layouts/admin_navbar.blade.php
Normal file
159
resources/views/layouts/admin_navbar.blade.php
Normal file
@ -0,0 +1,159 @@
|
||||
<nav class="layout-navbar container-xxl navbar navbar-expand-xl navbar-detached align-items-center bg-navbar-theme" id="layout-navbar">
|
||||
<div class="layout-menu-toggle navbar-nav align-items-xl-center me-4 me-xl-0 d-xl-none">
|
||||
<a class="nav-item nav-link px-0 me-xl-6" href="javascript:void(0)">
|
||||
<i class="ri-menu-fill ri-22px"></i>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<div class="navbar-nav-right d-flex align-items-center" id="navbar-collapse">
|
||||
|
||||
|
||||
<ul class="navbar-nav flex-row align-items-center ms-auto">
|
||||
<!-- Language -->
|
||||
@if (!Auth::guard('member')->check())
|
||||
|
||||
<li class="nav-item dropdown-language dropdown">
|
||||
|
||||
<a class="nav-link btn btn-text-secondary rounded-pill btn-icon dropdown-toggle hide-arrow" href="javascript:void(0);" data-bs-toggle="dropdown">
|
||||
<i class="ri-translate-2 ri-22px"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li>
|
||||
<a class="dropdown-item" href="javascript:void(0);" data-language="en" data-text-direction="ltr">
|
||||
<span class="align-middle">Thai</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="javascript:void(0);" data-language="fr" data-text-direction="ltr">
|
||||
<span class="align-middle">English</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="javascript:void(0);" data-language="ar" data-text-direction="rtl">
|
||||
<span class="align-middle">Arabic</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="javascript:void(0);" data-language="de" data-text-direction="ltr">
|
||||
<span class="align-middle">German</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@endif
|
||||
<!--/ Language -->
|
||||
|
||||
<!-- Style Switcher -->
|
||||
<li class="nav-item dropdown-style-switcher dropdown me-1 me-xl-0">
|
||||
<a class="nav-link btn btn-text-secondary rounded-pill btn-icon dropdown-toggle hide-arrow" href="javascript:void(0);" data-bs-toggle="dropdown">
|
||||
<i class="ri-22px"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end dropdown-styles">
|
||||
<li>
|
||||
<a class="dropdown-item" href="javascript:void(0);" data-theme="light">
|
||||
<span class="align-middle"><i class="ri-sun-line ri-22px me-3"></i>Light</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="javascript:void(0);" data-theme="dark">
|
||||
<span class="align-middle"><i class="ri-moon-clear-line ri-22px me-3"></i>Dark</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="javascript:void(0);" data-theme="system">
|
||||
<span class="align-middle"><i class="ri-computer-line ri-22px me-3"></i>System</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<!-- / Style Switcher-->
|
||||
|
||||
<!-- User -->
|
||||
<li class="nav-item navbar-dropdown dropdown-user dropdown">
|
||||
<a class="nav-link dropdown-toggle hide-arrow" href="javascript:void(0);" data-bs-toggle="dropdown">
|
||||
<div class="avatar avatar-online">
|
||||
@if(isset(Auth::user()->avatar))
|
||||
<img src="{{Auth::user()->avatar}}" alt class="rounded-circle" />
|
||||
@else
|
||||
<img src="../../assets/img/avatars/1.png" alt class="rounded-circle" />
|
||||
@endif
|
||||
</div>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li>
|
||||
<a class="dropdown-item" href="#">
|
||||
<div class="d-flex">
|
||||
<div class="flex-shrink-0 me-2">
|
||||
<div class="avatar avatar-online">
|
||||
@if(isset(Auth::guard('web')->user()->avatar))
|
||||
<img src="{{ Auth::guard('web')->user()->avatar }}" alt class="rounded-circle" />
|
||||
@else
|
||||
<img src="../../assets/img/avatars/1.png" alt class="rounded-circle" />
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<span class="fw-medium d-block small">
|
||||
@if(Auth::guard('web')->check())
|
||||
{{Auth::user()->name}}
|
||||
@endif
|
||||
</span>
|
||||
<small class="text-muted">管理員</small>
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<div class="dropdown-divider"></div>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="{{ route('admin.page.profile') }}">
|
||||
<i class="ri-user-3-line ri-22px me-3"></i><span class="align-middle">
|
||||
個人資料</span>
|
||||
</a>
|
||||
</li>
|
||||
{{-- <li> --}}
|
||||
{{-- <a class="dropdown-item" href="pages-account-settings-account.html"> --}}
|
||||
{{-- <i class="ri-settings-4-line ri-22px me-3"></i><span class="align-middle">Settings</span> --}}
|
||||
{{-- </a> --}}
|
||||
{{-- </li> --}}
|
||||
<li>
|
||||
<a class="dropdown-item" href="#">
|
||||
<span class="d-flex align-items-center align-middle">
|
||||
<i class="flex-shrink-0 ri-file-text-line ri-22px me-3"></i>
|
||||
<span class="flex-grow-1 align-middle">交易紀錄</span>
|
||||
<span class="flex-shrink-0 badge badge-center rounded-pill bg-danger">0</span>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<div class="dropdown-divider"></div>
|
||||
</li>
|
||||
{{-- <li>
|
||||
<a class="dropdown-item" href="pages-pricing.html">
|
||||
<i class="ri-money-dollar-circle-line ri-22px me-3"></i><span
|
||||
class="align-middle">Pricing</span>
|
||||
</a>
|
||||
</li> --}}
|
||||
<li>
|
||||
<a class="dropdown-item" href="pages-faq.html">
|
||||
<i class="ri-question-line ri-22px me-3"></i><span class="align-middle">常見問題</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<div class="d-grid px-4 pt-2 pb-1">
|
||||
<a class="btn btn-sm btn-danger d-flex" href="{{route("admin.logout")}}" target="_blank">
|
||||
<small class="align-middle">登 出</small>
|
||||
<i class="ri-logout-box-r-line ms-2 ri-16px"></i>
|
||||
</a>
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
<!--/ User -->
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
|
||||
</nav>
|
||||
@ -1,13 +1,16 @@
|
||||
<html lang="en" class="light-style layout-navbar-fixed layout-menu-fixed layout-compact" dir="ltr"
|
||||
data-theme="theme-default" data-assets-path="{{ asset('assets') }}/" data-template="vertical-menu-template-starter"
|
||||
data-style="light">
|
||||
<html lang="en" class="light-style layout-navbar-fixed layout-menu-fixed layout-compact" dir="ltr" data-theme="theme-default" data-assets-path="{{ asset('assets') }}/" data-template="vertical-menu-template-starter" data-style="light">
|
||||
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<meta name="viewport"
|
||||
content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0" />
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
|
||||
@if (Auth::guard('member')->check())
|
||||
<title>卡菲姬APP</title>
|
||||
@else
|
||||
<title>卡菲姬後台管理</title>
|
||||
@endif
|
||||
|
||||
<title>ADMIN</title>
|
||||
|
||||
<meta name="description" content="" />
|
||||
|
||||
@ -17,8 +20,7 @@
|
||||
<!-- Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
||||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap"
|
||||
rel="stylesheet" />
|
||||
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet" />
|
||||
|
||||
<link rel="stylesheet" href="{{ asset('assets/vendor/fonts/remixicon/remixicon.css') }}" />
|
||||
|
||||
@ -28,8 +30,7 @@
|
||||
|
||||
<!-- Core CSS -->
|
||||
<link rel="stylesheet" href="{{ asset('assets/vendor/css/rtl/core.css') }}" class="template-customizer-core-css" />
|
||||
<link rel="stylesheet" href="{{ asset('assets/vendor/css/rtl/theme-default.css') }}"
|
||||
class="template-customizer-theme-css" />
|
||||
<link rel="stylesheet" href="{{ asset('assets/vendor/css/rtl/theme-default.css') }}" class="template-customizer-theme-css" />
|
||||
<link rel="stylesheet" href="{{ asset('assets/css/demo.css') }}" />
|
||||
|
||||
<!-- Vendors CSS -->
|
||||
@ -44,6 +45,8 @@ class="template-customizer-theme-css" />
|
||||
<script src="{{ asset('assets/vendor/js/template-customizer.js') }}"></script>
|
||||
<!--? Config: Mandatory theme config file contain global vars & default theme options, Set your preferred theme option in this file. -->
|
||||
<script src="{{ asset('assets/js/config.js') }}"></script>
|
||||
<!-- 在<head>中引入SweetAlert2 CDN -->
|
||||
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||
|
||||
@yield('header')
|
||||
</head>
|
||||
@ -117,6 +120,7 @@ class="template-customizer-theme-css" />
|
||||
$(document).ready(function() {
|
||||
console.log('Document ready');
|
||||
});
|
||||
|
||||
</script>
|
||||
</body>
|
||||
|
||||
|
||||
@ -3,11 +3,10 @@
|
||||
<a href="{{url('/')}}" class="app-brand-link">
|
||||
<span class="app-brand-logo demo">
|
||||
<span style="color: var(--bs-primary)">
|
||||
|
||||
<img src="{{asset('assets/img/logo/cafeg-logo.png')}}" width="50px" height="50px" alt="{{asset('img/logo/cafeg-logo.png')}}"> </img>
|
||||
<img src="{{asset('assets/img/logo/cafeg-logo.png')}}" width="50px" height="50px" alt="{{asset('img/logo/cafeg-logo.png')}}"> </img>
|
||||
</span>
|
||||
</span>
|
||||
<img src="{{asset('assets/img/logo/cafeg-logo-h.png')}}" width="120px" height="50px" alt="{{asset('img/logo/cafeg-logo.png')}}"> </img>
|
||||
<img src="{{asset('assets/img/logo/cafeg-logo-h.png')}}" width="120px" height="50px" alt="{{asset('img/logo/cafeg-logo.png')}}"> </img>
|
||||
<span class="app-brand-text demo menu-text fw-semibold ms-2"></span>
|
||||
</a>
|
||||
|
||||
@ -24,33 +23,34 @@
|
||||
<ul class="menu-inner py-1 ps ps--active-y">
|
||||
<li class="menu-header small fw-medium">Getting Started</li>
|
||||
|
||||
@foreach ($menuData[0] as $menu )
|
||||
@foreach ($menuData[1] as $menu)
|
||||
@if(isset($menu->submenu[0]->url))
|
||||
<li class="menu-item">
|
||||
<a href="" class="menu-link menu-toggle">
|
||||
<i class="{{$menu->icon}}"> </i>
|
||||
<div>{{$menu->name}}</div>
|
||||
<div>{{$menu->name}} </div>
|
||||
</a>
|
||||
@if( isset($menu->submenu) )
|
||||
@foreach ($menu->submenu as $sub)
|
||||
<ul class="menu-sub">
|
||||
<li class="menu-item">
|
||||
<a href="{{$sub->url}}" class="menu-link">
|
||||
<a href="{{route($sub->url)}}" class="menu-link">
|
||||
<div>{{$sub->name}}</div>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
@endforeach
|
||||
@endif
|
||||
</li>
|
||||
|
||||
@else
|
||||
<li class="menu-item">
|
||||
<a href="{{url($menu->url)}}" class="menu-link">
|
||||
<i class="{{$menu->icon}}"> </i>
|
||||
<div>{{$menu->name}}</div>
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<div class="ps__rail-x" style="left: 0px; bottom: -427px;">
|
||||
<div class="ps__thumb-x" tabindex="0" style="left: 0px; width: 0px;"></div>
|
||||
</div>
|
||||
@ -58,5 +58,4 @@
|
||||
<div class="ps__thumb-y" tabindex="0" style="top: 80px; height: 106px;"></div>
|
||||
</div>
|
||||
</ul>
|
||||
|
||||
</aside>
|
||||
|
||||
@ -10,12 +10,9 @@ class="footer-container d-flex align-items-center justify-content-between py-4 f
|
||||
</script>
|
||||
, made with <span class="text-danger"><i class="tf-icons ri-heart-fill"></i></span>
|
||||
by
|
||||
<a href="https://pixinvent.com" target="_blank" class="footer-link">Pixinvent</a>
|
||||
</div>
|
||||
<div class="d-none d-lg-inline-block">
|
||||
<a href="https://demos.pixinvent.com/materialize-html-admin-template/documentation/"
|
||||
target="_blank" class="footer-link me-4">Documentation</a>
|
||||
<a href="#" target="_blank" class="footer-link">逸奔科技股份有限公司</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
<nav class="layout-navbar container-xxl navbar navbar-expand-xl navbar-detached align-items-center bg-navbar-theme"
|
||||
id="layout-navbar">
|
||||
<nav class="layout-navbar container-xxl navbar navbar-expand-xl navbar-detached align-items-center bg-navbar-theme" id="layout-navbar">
|
||||
<div class="layout-menu-toggle navbar-nav align-items-xl-center me-4 me-xl-0 d-xl-none">
|
||||
<a class="nav-item nav-link px-0 me-xl-6" href="javascript:void(0)">
|
||||
<i class="ri-menu-fill ri-22px"></i>
|
||||
@ -11,45 +10,43 @@
|
||||
|
||||
<ul class="navbar-nav flex-row align-items-center ms-auto">
|
||||
<!-- Language -->
|
||||
@if (!Auth::guard('member')->check())
|
||||
|
||||
<li class="nav-item dropdown-language dropdown">
|
||||
|
||||
<a class="nav-link btn btn-text-secondary rounded-pill btn-icon dropdown-toggle hide-arrow"
|
||||
href="javascript:void(0);" data-bs-toggle="dropdown">
|
||||
<a class="nav-link btn btn-text-secondary rounded-pill btn-icon dropdown-toggle hide-arrow" href="javascript:void(0);" data-bs-toggle="dropdown">
|
||||
<i class="ri-translate-2 ri-22px"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
<li>
|
||||
<a class="dropdown-item" href="javascript:void(0);" data-language="en"
|
||||
data-text-direction="ltr">
|
||||
<a class="dropdown-item" href="javascript:void(0);" data-language="en" data-text-direction="ltr">
|
||||
<span class="align-middle">Thai</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="javascript:void(0);" data-language="fr"
|
||||
data-text-direction="ltr">
|
||||
<a class="dropdown-item" href="javascript:void(0);" data-language="fr" data-text-direction="ltr">
|
||||
<span class="align-middle">English</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="javascript:void(0);" data-language="ar"
|
||||
data-text-direction="rtl">
|
||||
<a class="dropdown-item" href="javascript:void(0);" data-language="ar" data-text-direction="rtl">
|
||||
<span class="align-middle">Arabic</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="javascript:void(0);" data-language="de"
|
||||
data-text-direction="ltr">
|
||||
<a class="dropdown-item" href="javascript:void(0);" data-language="de" data-text-direction="ltr">
|
||||
<span class="align-middle">German</span>
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
|
||||
@endif
|
||||
<!--/ Language -->
|
||||
|
||||
<!-- Style Switcher -->
|
||||
<li class="nav-item dropdown-style-switcher dropdown me-1 me-xl-0">
|
||||
<a class="nav-link btn btn-text-secondary rounded-pill btn-icon dropdown-toggle hide-arrow"
|
||||
href="javascript:void(0);" data-bs-toggle="dropdown">
|
||||
<a class="nav-link btn btn-text-secondary rounded-pill btn-icon dropdown-toggle hide-arrow" href="javascript:void(0);" data-bs-toggle="dropdown">
|
||||
<i class="ri-22px"></i>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end dropdown-styles">
|
||||
@ -76,7 +73,15 @@
|
||||
<li class="nav-item navbar-dropdown dropdown-user dropdown">
|
||||
<a class="nav-link dropdown-toggle hide-arrow" href="javascript:void(0);" data-bs-toggle="dropdown">
|
||||
<div class="avatar avatar-online">
|
||||
|
||||
|
||||
@if(isset(Auth::guard('member')->user()->avatar) && Auth::guard('member')->user()->avatar != null)
|
||||
<img src="{{Auth::guard('member')->user()->avatar}}" alt class="rounded-circle" />
|
||||
@else
|
||||
<img src="../../assets/img/avatars/1.png" alt class="rounded-circle" />
|
||||
@endif
|
||||
|
||||
|
||||
</div>
|
||||
</a>
|
||||
<ul class="dropdown-menu dropdown-menu-end">
|
||||
@ -89,8 +94,18 @@
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex-grow-1">
|
||||
<span class="fw-medium d-block small">John Doe</span>
|
||||
<small class="text-muted">Admin</small>
|
||||
<span class="fw-medium d-block small">
|
||||
@if (Auth::guard('member')->check())
|
||||
{{Auth::guard('member')->user()->name}}
|
||||
@else
|
||||
{{Auth::user()->name}}
|
||||
@endif
|
||||
</span>
|
||||
@if(Auth::guard('member')->check())
|
||||
<small class="text-muted">{{Auth::guard('member')->user()->Level_Name}}</small>
|
||||
@else
|
||||
<small class="text-muted">管理員</small>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</a>
|
||||
@ -99,45 +114,57 @@
|
||||
<div class="dropdown-divider"></div>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="pages-profile-user.html">
|
||||
<i class="ri-user-3-line ri-22px me-3"></i><span class="align-middle">My
|
||||
Profile</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a class="dropdown-item" href="pages-account-settings-account.html">
|
||||
<i class="ri-settings-4-line ri-22px me-3"></i><span class="align-middle">Settings</span>
|
||||
<a class="dropdown-item" href="{{ route('member.page-profile') }}">
|
||||
<i class="ri-user-3-line ri-22px me-3"></i><span class="align-middle">
|
||||
個人資料</span>
|
||||
</a>
|
||||
</li>
|
||||
{{-- <li> --}}
|
||||
{{-- <a class="dropdown-item" href="pages-account-settings-account.html"> --}}
|
||||
{{-- <i class="ri-settings-4-line ri-22px me-3"></i><span class="align-middle">Settings</span> --}}
|
||||
{{-- </a> --}}
|
||||
{{-- </li> --}}
|
||||
<li>
|
||||
<a class="dropdown-item" href="pages-account-settings-billing.html">
|
||||
<span class="d-flex align-items-center align-middle">
|
||||
<i class="flex-shrink-0 ri-file-text-line ri-22px me-3"></i>
|
||||
<span class="flex-grow-1 align-middle">Billing</span>
|
||||
<span class="flex-shrink-0 badge badge-center rounded-pill bg-danger">4</span>
|
||||
<span class="flex-grow-1 align-middle">交易紀錄</span>
|
||||
<span class="flex-shrink-0 badge badge-center rounded-pill bg-danger">0</span>
|
||||
</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<div class="dropdown-divider"></div>
|
||||
</li>
|
||||
<li>
|
||||
{{-- <li>
|
||||
<a class="dropdown-item" href="pages-pricing.html">
|
||||
<i class="ri-money-dollar-circle-line ri-22px me-3"></i><span
|
||||
class="align-middle">Pricing</span>
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
</li> --}}
|
||||
{{-- <li>
|
||||
<a class="dropdown-item" href="pages-faq.html">
|
||||
<i class="ri-question-line ri-22px me-3"></i><span class="align-middle">FAQ</span>
|
||||
<i class="ri-question-line ri-22px me-3"></i><span class="align-middle">常見問題</span>
|
||||
</a>
|
||||
</li>
|
||||
</li> --}}
|
||||
<li>
|
||||
<div class="d-grid px-4 pt-2 pb-1">
|
||||
<a class="btn btn-sm btn-danger d-flex" href="{{route("admin.logout")}}" target="_blank">
|
||||
<small class="align-middle">Logout</small>
|
||||
|
||||
@if (Auth::guard('member')->check())
|
||||
<a class="btn btn-sm btn-danger d-flex" href="{{route("member.logout")}}" target="_blank">
|
||||
<small class="align-middle">登 出</small>
|
||||
<i class="ri-logout-box-r-line ms-2 ri-16px"></i>
|
||||
</a>
|
||||
|
||||
@else
|
||||
<a class="btn btn-sm btn-danger d-flex" href="{{route("admin.logout")}}" target="_blank">
|
||||
<small class="align-middle">登 出</small>
|
||||
<i class="ri-logout-box-r-line ms-2 ri-16px"></i>
|
||||
</a>
|
||||
|
||||
@endif
|
||||
|
||||
|
||||
</div>
|
||||
</li>
|
||||
</ul>
|
||||
|
||||
46
resources/views/vendor/pagination/bootstrap-4.blade.php
vendored
Normal file
46
resources/views/vendor/pagination/bootstrap-4.blade.php
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
@if ($paginator->hasPages())
|
||||
<nav>
|
||||
<ul class="pagination">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')">
|
||||
<span class="page-link" aria-hidden="true">‹</span>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')">‹</a>
|
||||
</li>
|
||||
@endif
|
||||
|
||||
{{-- Pagination Elements --}}
|
||||
@foreach ($elements as $element)
|
||||
{{-- "Three Dots" Separator --}}
|
||||
@if (is_string($element))
|
||||
<li class="page-item disabled" aria-disabled="true"><span class="page-link">{{ $element }}</span></li>
|
||||
@endif
|
||||
|
||||
{{-- Array Of Links --}}
|
||||
@if (is_array($element))
|
||||
@foreach ($element as $page => $url)
|
||||
@if ($page == $paginator->currentPage())
|
||||
<li class="page-item active" aria-current="page"><span class="page-link">{{ $page }}</span></li>
|
||||
@else
|
||||
<li class="page-item"><a class="page-link" href="{{ $url }}">{{ $page }}</a></li>
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')">›</a>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.next')">
|
||||
<span class="page-link" aria-hidden="true">›</span>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
</nav>
|
||||
@endif
|
||||
88
resources/views/vendor/pagination/bootstrap-5.blade.php
vendored
Normal file
88
resources/views/vendor/pagination/bootstrap-5.blade.php
vendored
Normal file
@ -0,0 +1,88 @@
|
||||
@if ($paginator->hasPages())
|
||||
<nav class="d-flex justify-items-center justify-content-between">
|
||||
<div class="d-flex justify-content-between flex-fill d-sm-none">
|
||||
<ul class="pagination">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<li class="page-item disabled" aria-disabled="true">
|
||||
<span class="page-link">@lang('pagination.previous')</span>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev">@lang('pagination.previous')</a>
|
||||
</li>
|
||||
@endif
|
||||
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next">@lang('pagination.next')</a>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item disabled" aria-disabled="true">
|
||||
<span class="page-link">@lang('pagination.next')</span>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="d-none flex-sm-fill d-sm-flex align-items-sm-center justify-content-sm-between">
|
||||
<div>
|
||||
<p class="small text-muted">
|
||||
{!! __('Showing') !!}
|
||||
<span class="fw-semibold">{{ $paginator->firstItem() }}</span>
|
||||
{!! __('to') !!}
|
||||
<span class="fw-semibold">{{ $paginator->lastItem() }}</span>
|
||||
{!! __('of') !!}
|
||||
<span class="fw-semibold">{{ $paginator->total() }}</span>
|
||||
{!! __('results') !!}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<ul class="pagination">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')">
|
||||
<span class="page-link" aria-hidden="true">‹</span>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')">‹</a>
|
||||
</li>
|
||||
@endif
|
||||
|
||||
{{-- Pagination Elements --}}
|
||||
@foreach ($elements as $element)
|
||||
{{-- "Three Dots" Separator --}}
|
||||
@if (is_string($element))
|
||||
<li class="page-item disabled" aria-disabled="true"><span class="page-link">{{ $element }}</span></li>
|
||||
@endif
|
||||
|
||||
{{-- Array Of Links --}}
|
||||
@if (is_array($element))
|
||||
@foreach ($element as $page => $url)
|
||||
@if ($page == $paginator->currentPage())
|
||||
<li class="page-item active" aria-current="page"><span class="page-link">{{ $page }}</span></li>
|
||||
@else
|
||||
<li class="page-item"><a class="page-link" href="{{ $url }}">{{ $page }}</a></li>
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')">›</a>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.next')">
|
||||
<span class="page-link" aria-hidden="true">›</span>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
@endif
|
||||
46
resources/views/vendor/pagination/default.blade.php
vendored
Normal file
46
resources/views/vendor/pagination/default.blade.php
vendored
Normal file
@ -0,0 +1,46 @@
|
||||
@if ($paginator->hasPages())
|
||||
<nav>
|
||||
<ul class="pagination">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<li class="disabled" aria-disabled="true" aria-label="@lang('pagination.previous')">
|
||||
<span aria-hidden="true">‹</span>
|
||||
</li>
|
||||
@else
|
||||
<li>
|
||||
<a href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')">‹</a>
|
||||
</li>
|
||||
@endif
|
||||
|
||||
{{-- Pagination Elements --}}
|
||||
@foreach ($elements as $element)
|
||||
{{-- "Three Dots" Separator --}}
|
||||
@if (is_string($element))
|
||||
<li class="disabled" aria-disabled="true"><span>{{ $element }}</span></li>
|
||||
@endif
|
||||
|
||||
{{-- Array Of Links --}}
|
||||
@if (is_array($element))
|
||||
@foreach ($element as $page => $url)
|
||||
@if ($page == $paginator->currentPage())
|
||||
<li class="active" aria-current="page"><span>{{ $page }}</span></li>
|
||||
@else
|
||||
<li><a href="{{ $url }}">{{ $page }}</a></li>
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<li>
|
||||
<a href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')">›</a>
|
||||
</li>
|
||||
@else
|
||||
<li class="disabled" aria-disabled="true" aria-label="@lang('pagination.next')">
|
||||
<span aria-hidden="true">›</span>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
</nav>
|
||||
@endif
|
||||
89
resources/views/vendor/pagination/materialize.blade.php
vendored
Normal file
89
resources/views/vendor/pagination/materialize.blade.php
vendored
Normal file
@ -0,0 +1,89 @@
|
||||
<div style="margin-top: 20px;"></div>
|
||||
<nav aria-label="Page navigation" >
|
||||
<ul class="pagination pagination-info">
|
||||
{{-- First Page --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<li class="page-item first disabled">
|
||||
<a class="page-link" href="javascript:void(0);">
|
||||
<i class="tf-icon ri-skip-back-mini-line ri-20px"></i>
|
||||
</a>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item first">
|
||||
{{-- <a class="page-link" href="{{ $paginator->url(1) }}">
|
||||
<i class="tf-icon ri-skip-back-mini-line ri-20px"></i>
|
||||
</a> --}}
|
||||
</li>
|
||||
@endif
|
||||
|
||||
{{-- Previous Page --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<li class="page-item prev disabled">
|
||||
<a class="page-link" href="javascript:void(0);">
|
||||
<i class="tf-icon ri-arrow-left-s-line ri-20px"></i>
|
||||
</a>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item prev">
|
||||
<a class="page-link" href="{{ $paginator->previousPageUrl() }}">
|
||||
<i class="tf-icon ri-arrow-left-s-line ri-20px"></i>
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
|
||||
{{-- Pagination Links --}}
|
||||
@foreach ($elements as $element)
|
||||
{{-- "Three Dots" Separator --}}
|
||||
@if (is_string($element))
|
||||
<li class="page-item disabled">
|
||||
<a class="page-link" href="javascript:void(0);">{{ $element }}</a>
|
||||
</li>
|
||||
@endif
|
||||
|
||||
{{-- Array Of Links --}}
|
||||
@if (is_array($element))
|
||||
@foreach ($element as $page => $url)
|
||||
@if ($page == $paginator->currentPage())
|
||||
<li class="page-item active">
|
||||
<a class="page-link" href="javascript:void(0);">{{ $page }}</a>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="{{ $url }}">{{ $page }}</a>
|
||||
</li>
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- Next Page --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<li class="page-item next">
|
||||
<a class="page-link" href="{{ $paginator->nextPageUrl() }}">
|
||||
<i class="tf-icon ri-arrow-right-s-line ri-20px"></i>
|
||||
</a>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item next disabled">
|
||||
<a class="page-link" href="javascript:void(0);">
|
||||
<i class="tf-icon ri-arrow-right-s-line ri-20px"></i>
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
|
||||
{{-- Last Page --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<li class="page-item last">
|
||||
<a class="page-link" href="{{ $paginator->url($paginator->lastPage()) }}">
|
||||
<i class="tf-icon ri-skip-forward-mini-line ri-20px"></i>
|
||||
</a>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item last disabled">
|
||||
<a class="page-link" href="javascript:void(0);">
|
||||
<i class="tf-icon ri-skip-forward-mini-line ri-20px"></i>
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
</nav>
|
||||
36
resources/views/vendor/pagination/semantic-ui.blade.php
vendored
Normal file
36
resources/views/vendor/pagination/semantic-ui.blade.php
vendored
Normal file
@ -0,0 +1,36 @@
|
||||
@if ($paginator->hasPages())
|
||||
<div class="ui pagination menu" role="navigation">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<a class="icon item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')"> <i class="left chevron icon"></i> </a>
|
||||
@else
|
||||
<a class="icon item" href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')"> <i class="left chevron icon"></i> </a>
|
||||
@endif
|
||||
|
||||
{{-- Pagination Elements --}}
|
||||
@foreach ($elements as $element)
|
||||
{{-- "Three Dots" Separator --}}
|
||||
@if (is_string($element))
|
||||
<a class="icon item disabled" aria-disabled="true">{{ $element }}</a>
|
||||
@endif
|
||||
|
||||
{{-- Array Of Links --}}
|
||||
@if (is_array($element))
|
||||
@foreach ($element as $page => $url)
|
||||
@if ($page == $paginator->currentPage())
|
||||
<a class="item active" href="{{ $url }}" aria-current="page">{{ $page }}</a>
|
||||
@else
|
||||
<a class="item" href="{{ $url }}">{{ $page }}</a>
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<a class="icon item" href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')"> <i class="right chevron icon"></i> </a>
|
||||
@else
|
||||
<a class="icon item disabled" aria-disabled="true" aria-label="@lang('pagination.next')"> <i class="right chevron icon"></i> </a>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
27
resources/views/vendor/pagination/simple-bootstrap-4.blade.php
vendored
Normal file
27
resources/views/vendor/pagination/simple-bootstrap-4.blade.php
vendored
Normal file
@ -0,0 +1,27 @@
|
||||
@if ($paginator->hasPages())
|
||||
<nav>
|
||||
<ul class="pagination">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<li class="page-item disabled" aria-disabled="true">
|
||||
<span class="page-link">@lang('pagination.previous')</span>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev">@lang('pagination.previous')</a>
|
||||
</li>
|
||||
@endif
|
||||
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next">@lang('pagination.next')</a>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item disabled" aria-disabled="true">
|
||||
<span class="page-link">@lang('pagination.next')</span>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
</nav>
|
||||
@endif
|
||||
29
resources/views/vendor/pagination/simple-bootstrap-5.blade.php
vendored
Normal file
29
resources/views/vendor/pagination/simple-bootstrap-5.blade.php
vendored
Normal file
@ -0,0 +1,29 @@
|
||||
@if ($paginator->hasPages())
|
||||
<nav role="navigation" aria-label="Pagination Navigation">
|
||||
<ul class="pagination">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<li class="page-item disabled" aria-disabled="true">
|
||||
<span class="page-link">{!! __('pagination.previous') !!}</span>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev">
|
||||
{!! __('pagination.previous') !!}
|
||||
</a>
|
||||
</li>
|
||||
@endif
|
||||
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<li class="page-item">
|
||||
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next">{!! __('pagination.next') !!}</a>
|
||||
</li>
|
||||
@else
|
||||
<li class="page-item disabled" aria-disabled="true">
|
||||
<span class="page-link">{!! __('pagination.next') !!}</span>
|
||||
</li>
|
||||
@endif
|
||||
</ul>
|
||||
</nav>
|
||||
@endif
|
||||
19
resources/views/vendor/pagination/simple-default.blade.php
vendored
Normal file
19
resources/views/vendor/pagination/simple-default.blade.php
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
@if ($paginator->hasPages())
|
||||
<nav>
|
||||
<ul class="pagination">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<li class="disabled" aria-disabled="true"><span>@lang('pagination.previous')</span></li>
|
||||
@else
|
||||
<li><a href="{{ $paginator->previousPageUrl() }}" rel="prev">@lang('pagination.previous')</a></li>
|
||||
@endif
|
||||
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<li><a href="{{ $paginator->nextPageUrl() }}" rel="next">@lang('pagination.next')</a></li>
|
||||
@else
|
||||
<li class="disabled" aria-disabled="true"><span>@lang('pagination.next')</span></li>
|
||||
@endif
|
||||
</ul>
|
||||
</nav>
|
||||
@endif
|
||||
25
resources/views/vendor/pagination/simple-tailwind.blade.php
vendored
Normal file
25
resources/views/vendor/pagination/simple-tailwind.blade.php
vendored
Normal file
@ -0,0 +1,25 @@
|
||||
@if ($paginator->hasPages())
|
||||
<nav role="navigation" aria-label="Pagination Navigation" class="flex justify-between">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md dark:text-gray-600 dark:bg-gray-800 dark:border-gray-600">
|
||||
{!! __('pagination.previous') !!}
|
||||
</span>
|
||||
@else
|
||||
<a href="{{ $paginator->previousPageUrl() }}" rel="prev" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-300 dark:focus:border-blue-700 dark:active:bg-gray-700 dark:active:text-gray-300">
|
||||
{!! __('pagination.previous') !!}
|
||||
</a>
|
||||
@endif
|
||||
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<a href="{{ $paginator->nextPageUrl() }}" rel="next" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-300 dark:focus:border-blue-700 dark:active:bg-gray-700 dark:active:text-gray-300">
|
||||
{!! __('pagination.next') !!}
|
||||
</a>
|
||||
@else
|
||||
<span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md dark:text-gray-600 dark:bg-gray-800 dark:border-gray-600">
|
||||
{!! __('pagination.next') !!}
|
||||
</span>
|
||||
@endif
|
||||
</nav>
|
||||
@endif
|
||||
106
resources/views/vendor/pagination/tailwind.blade.php
vendored
Normal file
106
resources/views/vendor/pagination/tailwind.blade.php
vendored
Normal file
@ -0,0 +1,106 @@
|
||||
@if ($paginator->hasPages())
|
||||
<nav role="navigation" aria-label="{{ __('Pagination Navigation') }}" class="flex items-center justify-between">
|
||||
<div class="flex justify-between flex-1 sm:hidden">
|
||||
@if ($paginator->onFirstPage())
|
||||
<span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md dark:text-gray-600 dark:bg-gray-800 dark:border-gray-600">
|
||||
{!! __('pagination.previous') !!}
|
||||
</span>
|
||||
@else
|
||||
<a href="{{ $paginator->previousPageUrl() }}" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-300 dark:focus:border-blue-700 dark:active:bg-gray-700 dark:active:text-gray-300">
|
||||
{!! __('pagination.previous') !!}
|
||||
</a>
|
||||
@endif
|
||||
|
||||
@if ($paginator->hasMorePages())
|
||||
<a href="{{ $paginator->nextPageUrl() }}" class="relative inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-300 dark:focus:border-blue-700 dark:active:bg-gray-700 dark:active:text-gray-300">
|
||||
{!! __('pagination.next') !!}
|
||||
</a>
|
||||
@else
|
||||
<span class="relative inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md dark:text-gray-600 dark:bg-gray-800 dark:border-gray-600">
|
||||
{!! __('pagination.next') !!}
|
||||
</span>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
<div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
|
||||
<div>
|
||||
<p class="text-sm text-gray-700 leading-5 dark:text-gray-400">
|
||||
{!! __('Showing') !!}
|
||||
@if ($paginator->firstItem())
|
||||
<span class="font-medium">{{ $paginator->firstItem() }}</span>
|
||||
{!! __('to') !!}
|
||||
<span class="font-medium">{{ $paginator->lastItem() }}</span>
|
||||
@else
|
||||
{{ $paginator->count() }}
|
||||
@endif
|
||||
{!! __('of') !!}
|
||||
<span class="font-medium">{{ $paginator->total() }}</span>
|
||||
{!! __('results') !!}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<span class="relative z-0 inline-flex rtl:flex-row-reverse shadow-sm rounded-md">
|
||||
{{-- Previous Page Link --}}
|
||||
@if ($paginator->onFirstPage())
|
||||
<span aria-disabled="true" aria-label="{{ __('pagination.previous') }}">
|
||||
<span class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-l-md leading-5 dark:bg-gray-800 dark:border-gray-600" aria-hidden="true">
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
@else
|
||||
<a href="{{ $paginator->previousPageUrl() }}" rel="prev" class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-l-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150 dark:bg-gray-800 dark:border-gray-600 dark:active:bg-gray-700 dark:focus:border-blue-800" aria-label="{{ __('pagination.previous') }}">
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</a>
|
||||
@endif
|
||||
|
||||
{{-- Pagination Elements --}}
|
||||
@foreach ($elements as $element)
|
||||
{{-- "Three Dots" Separator --}}
|
||||
@if (is_string($element))
|
||||
<span aria-disabled="true">
|
||||
<span class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-white border border-gray-300 cursor-default leading-5 dark:bg-gray-800 dark:border-gray-600">{{ $element }}</span>
|
||||
</span>
|
||||
@endif
|
||||
|
||||
{{-- Array Of Links --}}
|
||||
@if (is_array($element))
|
||||
@foreach ($element as $page => $url)
|
||||
@if ($page == $paginator->currentPage())
|
||||
<span aria-current="page">
|
||||
<span class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 dark:bg-gray-800 dark:border-gray-600">{{ $page }}</span>
|
||||
</span>
|
||||
@else
|
||||
<a href="{{ $url }}" class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 hover:text-gray-500 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150 dark:bg-gray-800 dark:border-gray-600 dark:text-gray-400 dark:hover:text-gray-300 dark:active:bg-gray-700 dark:focus:border-blue-800" aria-label="{{ __('Go to page :page', ['page' => $page]) }}">
|
||||
{{ $page }}
|
||||
</a>
|
||||
@endif
|
||||
@endforeach
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
{{-- Next Page Link --}}
|
||||
@if ($paginator->hasMorePages())
|
||||
<a href="{{ $paginator->nextPageUrl() }}" rel="next" class="relative inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-r-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150 dark:bg-gray-800 dark:border-gray-600 dark:active:bg-gray-700 dark:focus:border-blue-800" aria-label="{{ __('pagination.next') }}">
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</a>
|
||||
@else
|
||||
<span aria-disabled="true" aria-label="{{ __('pagination.next') }}">
|
||||
<span class="relative inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-r-md leading-5 dark:bg-gray-800 dark:border-gray-600" aria-hidden="true">
|
||||
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
|
||||
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
|
||||
</svg>
|
||||
</span>
|
||||
</span>
|
||||
@endif
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</nav>
|
||||
@endif
|
||||
43
routes/admin.php
Normal file
43
routes/admin.php
Normal file
@ -0,0 +1,43 @@
|
||||
<?php
|
||||
use App\Http\Controllers\LoginController;
|
||||
use App\Http\Middleware\AdminRedirect;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
/***********************************************
|
||||
***************後台首頁 route *******************
|
||||
* url 前綴字 admin ,
|
||||
* route name 前綴字 admin 已設定
|
||||
****************************************************/
|
||||
Route::get('/phpinfo', function () {
|
||||
return phpinfo();
|
||||
});
|
||||
|
||||
Route::
|
||||
namespace('App\Http\Controllers\Admin') // 設置命名空間
|
||||
->middleware(AdminRedirect::class)
|
||||
->group(function () {
|
||||
Route::get('/', 'IndexController@index')->name('index');
|
||||
Route::get('register', 'RegisterController@index')->name('register');
|
||||
Route::post('register/create', 'RegisterController@registerCreate')->name('register.create');
|
||||
Route::get('profile', 'IndexController@profile')->name('profile');
|
||||
Route::get('page-profile', 'IndexController@pageProfile')->name('page.profile');
|
||||
|
||||
Route::put('profile/update', 'IndexController@profileUpdate')->name('profile.update');
|
||||
Route::get('memberlist', 'MemberController@index')->name('member.index');
|
||||
Route::get('logout', [LoginController::class, 'adminLogout'])->name(name: 'logout');
|
||||
Route::prefix('setting')->group(function () {
|
||||
Route::get('/', 'SettingController@index')->name('setting');
|
||||
Route::get('promocode', 'SettingController@promoCode')->name('promocode');
|
||||
Route::get('promocode/used', 'SettingController@promoCode')->name('promocode.status');
|
||||
Route::post('promocode', 'SettingController@promoCodeCreate')->name('promocode.create');
|
||||
|
||||
|
||||
|
||||
});
|
||||
});
|
||||
// line 登入後查詢;
|
||||
Route::get('login/line/callback', [LoginController::class, 'handleProviderCallback'])->name('login.line.callback');
|
||||
Route::get('login', [LoginController::class, 'adminIndex'])->name('login');
|
||||
Route::post('login/process', [LoginController::class, 'adminNormalLogin'])->name('login.post');
|
||||
//後台 line 登入;
|
||||
Route::get('login/line', [LoginController::class, 'redirectToProvider'])->name('login.line');
|
||||
@ -1,14 +1,25 @@
|
||||
<?php
|
||||
|
||||
use App\Http\Controllers\front\LoginController as frontLoginController;
|
||||
use App\Http\Controllers\EmailController;
|
||||
use App\Http\Controllers\front\MemberController;
|
||||
use App\Http\Controllers\front\PromoCodeController;
|
||||
use App\Http\Controllers\front\RegisterController;
|
||||
use App\Http\Controllers\LoginController;
|
||||
use App\Http\Middleware\GuestRedirect;
|
||||
use App\Http\Middleware\memberAuth;
|
||||
use App\Http\Middleware\MemberRedirect;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
//
|
||||
//guest
|
||||
Route::get('/', function () {
|
||||
return view('welcome');
|
||||
|
||||
})->middleware(GuestRedirect::class);
|
||||
|
||||
Route::get('/phpinfo', function () {
|
||||
return phpinfo();
|
||||
});
|
||||
|
||||
Route::get('profile', function () {
|
||||
|
||||
return view('profile.index');
|
||||
@ -16,29 +27,42 @@
|
||||
});
|
||||
|
||||
//前台 login 畫面;
|
||||
Route::get("login", [frontLoginController::class, 'index'])->middleware(memberAuth::class)->name('front.login.view');
|
||||
|
||||
Route::get("login", [LoginController::class, 'index'])->name('front.login.view')->middleware(MemberRedirect::class);
|
||||
//前台 line 登入;
|
||||
Route::get('login/line', [frontLoginController::class, 'redirectToProvider'])->name('front.login.line');
|
||||
Route::post('login/process', [LoginController::class, 'memberNormalLogin'])->name('member.login.post');
|
||||
Route::get('login/line', [LoginController::class, 'redirectToProvider'])->name('front.login.line');
|
||||
//前台 line 登入後查詢;
|
||||
Route::get('login/line/callback', [frontLoginController::class, 'handleProviderCallback'])->name('front.login.line.callback');
|
||||
|
||||
Route::get('login/line/callback', [LoginController::class, 'handleProviderCallback'])->name('front.login.line.callback');
|
||||
Route::get('register', [RegisterController::class, 'index'])->name('member.register');
|
||||
Route::post('register/create', [RegisterController::class, 'create'])->name('member.register.create');
|
||||
//前台route 登入後;
|
||||
|
||||
Route::get('email/verify', [EmailController::class, 'index'])->name('email.verify');
|
||||
Route::any('checkphone', [MemberController::class, 'checkPhone'])->name('member.checkphone');
|
||||
|
||||
Route::prefix('member')
|
||||
->middleware(memberAuth::class) // 使用自定义守卫的中间件
|
||||
->as('member.')
|
||||
->group(function () {
|
||||
Route::get('/', [MemberController::class, 'index'])->name('member.index');
|
||||
Route::get('profile', [MemberController::class, 'profile'])->name('member.profile');
|
||||
Route::get('/', [MemberController::class, 'index'])->name('index');
|
||||
Route::post('getpromocode', [PromoCodeController::class, 'create'])->name('getpromocode');
|
||||
Route::get('logout', [LoginController::class, 'memberLogout'])->name('logout');
|
||||
Route::get('profile', [MemberController::class, 'profile'])->name('profile');
|
||||
Route::put('profile/update', [MemberController::class, 'profileUpdate'])->name('profile.update');
|
||||
Route::get('validemail', [EmailController::class, 'validemail'])->name('validemail');
|
||||
Route::post('sendemail', [EmailController::class, 'sendemail'])->name('sendemail');
|
||||
Route::get('page-profile', [MemberController::class, 'pageProfile'])->name('page-profile');
|
||||
|
||||
});
|
||||
|
||||
//後台route;
|
||||
/*
|
||||
*********************************************************************************************
|
||||
* 後台route
|
||||
**********************************************************************************************
|
||||
*/
|
||||
// Web 路由...
|
||||
//設定路由路徑
|
||||
Route::prefix('admin')
|
||||
->middleware('auth:web') // 使用自定义守卫的中间件
|
||||
->group(function () {
|
||||
|
||||
Route::get('/logout', [LogController::class, 'Logout'])->name('admin.logout');
|
||||
Route::get('crm', [AnalyticsController::class, 'crm'])->name('admin-dashboard-crm');
|
||||
Route::get('analytics', [AnalyticsController::class, 'analytics'])->name('admin-dashboard-crm');
|
||||
|
||||
});
|
||||
->as('admin.')
|
||||
->group(base_path('routes/admin.php'));
|
||||
//
|
||||
|
||||
Loading…
Reference in New Issue
Block a user