註冊 ,重設密碼
This commit is contained in:
parent
17c9d487b2
commit
87a0ddf7bd
@ -11,7 +11,6 @@ class MemberController extends Controller
|
|||||||
public function index()
|
public function index()
|
||||||
{
|
{
|
||||||
$data = Member::paginate(20);
|
$data = Member::paginate(20);
|
||||||
|
|
||||||
return view('admin.member.index', ['data' => $data]);
|
return view('admin.member.index', ['data' => $data]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,6 +4,9 @@
|
|||||||
use App\Http\Controllers\Controller;
|
use App\Http\Controllers\Controller;
|
||||||
use App\Models\Member;
|
use App\Models\Member;
|
||||||
use Illuminate\Http\Request;
|
use Illuminate\Http\Request;
|
||||||
|
use Exception;
|
||||||
|
use App\Models\EmailVerifications;
|
||||||
|
use Mail;
|
||||||
|
|
||||||
class RegisterController extends Controller
|
class RegisterController extends Controller
|
||||||
{
|
{
|
||||||
@ -41,6 +44,111 @@ public function create(Request $request)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public function forgotPassword(Request $request)
|
||||||
|
{
|
||||||
|
|
||||||
|
return view('front.auth.forgot-password');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function sendForgotPassword(Request $request)
|
||||||
|
{
|
||||||
|
\Log::info('sendForgotPassword', []);
|
||||||
|
$subject = "卡菲姬系統-密碼重新設定";
|
||||||
|
$token = \Str::random(32);
|
||||||
|
$result = Member::where('email', $request->email)->first();
|
||||||
|
|
||||||
|
try {
|
||||||
|
if (!isset($result)) {
|
||||||
|
throw new Exception("找不到帳號", 404);
|
||||||
|
} else {
|
||||||
|
$verificationLink = route('reset.password.token', ['token' => $token, 'id' => $result->id]);
|
||||||
|
|
||||||
|
\Log::info('sendForgotPassword go EmailVerifications', []);
|
||||||
|
$res = EmailVerifications::where('email', $request->email)->first();
|
||||||
|
if ($res) {
|
||||||
|
|
||||||
|
$res->email = $request->email;
|
||||||
|
$res->token = $token;
|
||||||
|
$res->save();
|
||||||
|
|
||||||
|
} else {
|
||||||
|
EmailVerifications::create([
|
||||||
|
'email' => $request->email,
|
||||||
|
'token' => $token,
|
||||||
|
]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
// 郵件內容
|
||||||
|
$message = "您好,\n\n請點擊以下鏈更換您的電子郵件地址:\n\n" . $verificationLink . "\n\n如果您未請求此操作,請忽略此郵件。\n\n感謝您!";
|
||||||
|
// 發送電子郵件
|
||||||
|
Mail::to($request->input('email'))->send(new \App\Mail\CustomMail($subject, $message));
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function resetPassword(Request $request)
|
||||||
|
{
|
||||||
|
$valid = true;
|
||||||
|
$request->validate([
|
||||||
|
'token' => 'required',
|
||||||
|
]);
|
||||||
|
|
||||||
|
$emailVerification = EmailVerifications::where('token', $request->token)->first();
|
||||||
|
|
||||||
|
if (!$emailVerification) {
|
||||||
|
$valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$member = Member::where('email', $emailVerification->email)->firstOrFail();
|
||||||
|
|
||||||
|
if (!$member) {
|
||||||
|
$valid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// 刪除使用過的令牌
|
||||||
|
$emailVerification->delete();
|
||||||
|
|
||||||
|
if ($valid == true) {
|
||||||
|
|
||||||
|
return redirect()->route('change.password', ['id', $member->id]);
|
||||||
|
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
return redirect()->route('front.login.view')->with('error', '驗證密碼token 失敗');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function changePassword(Request $request)
|
||||||
|
{
|
||||||
|
|
||||||
|
return view('front.auth.confirmpassword');
|
||||||
|
}
|
||||||
|
|
||||||
|
public function confrimPassword(Request $request)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
return view('front.auth.confirmpassword');
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function resetPasswordProcess($id, Request $request)
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Store a newly created resource in storage.
|
* Store a newly created resource in storage.
|
||||||
*/
|
*/
|
||||||
|
|||||||
@ -2,9 +2,11 @@
|
|||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
|
use App;
|
||||||
use Illuminate\Foundation\Auth\User as Authenticatable;
|
use Illuminate\Foundation\Auth\User as Authenticatable;
|
||||||
use Illuminate\Notifications\Notifiable;
|
use Illuminate\Notifications\Notifiable;
|
||||||
use Laravel\Sanctum\HasApiTokens;
|
use Laravel\Sanctum\HasApiTokens;
|
||||||
|
use App\Models\Promocode;
|
||||||
|
|
||||||
class Member extends Authenticatable
|
class Member extends Authenticatable
|
||||||
{
|
{
|
||||||
@ -58,4 +60,11 @@ public function getLevelNameAttribute()
|
|||||||
protected $casts = [
|
protected $casts = [
|
||||||
'email_verified_at' => 'datetime',
|
'email_verified_at' => 'datetime',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
|
||||||
|
public function getPromoCode()
|
||||||
|
{
|
||||||
|
return $this->hasOne(Promocode::class, 'used_count', 'id');
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@ -144,7 +144,8 @@
|
|||||||
<div class="d-flex justify-content-start align-items-center user-name">
|
<div class="d-flex justify-content-start align-items-center user-name">
|
||||||
<div class="avatar-wrapper">
|
<div class="avatar-wrapper">
|
||||||
<div class="avatar avatar-sm me-3">
|
<div class="avatar avatar-sm me-3">
|
||||||
<img src="{{$item->avatar??""}}" alt="Avatar" class="rounded-circle">
|
<img src="{{ $item->avatar ?? '' }}" alt="Avatar"
|
||||||
|
class="rounded-circle">
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="d-flex flex-column">
|
<div class="d-flex flex-column">
|
||||||
@ -157,7 +158,6 @@
|
|||||||
|
|
||||||
<td>{{ $item->phone }}</td>
|
<td>{{ $item->phone }}</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
||||||
<span class="text-truncate d-flex align-items-center text-heading">
|
<span class="text-truncate d-flex align-items-center text-heading">
|
||||||
@if ($item->level == 0)
|
@if ($item->level == 0)
|
||||||
<i class="ri-user-line ri-22px text-danger me-2"></i>
|
<i class="ri-user-line ri-22px text-danger me-2"></i>
|
||||||
@ -165,15 +165,13 @@
|
|||||||
<i class="ri-user-line ri-22px text-info me-2"></i>
|
<i class="ri-user-line ri-22px text-info me-2"></i>
|
||||||
@elseif($item->level == 2)
|
@elseif($item->level == 2)
|
||||||
<i class="ri-user-line ri-22px text-sucess me-2"></i>
|
<i class="ri-user-line ri-22px text-sucess me-2"></i>
|
||||||
|
|
||||||
@endif
|
@endif
|
||||||
|
|
||||||
{{ $item->Level_Name }}
|
{{ $item->Level_Name }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
|
|
||||||
</td>
|
</td>
|
||||||
<td>未實作</td>
|
<td> <span class="text-danger" style="font-size:20px">{{ $item->getPromoCode->code }} </span>
|
||||||
|
</td>
|
||||||
<td></td>
|
<td></td>
|
||||||
</tr>
|
</tr>
|
||||||
@endforeach
|
@endforeach
|
||||||
|
|||||||
173
resources/views/front/auth/confirmpassword.blade.php
Normal file
173
resources/views/front/auth/confirmpassword.blade.php
Normal file
@ -0,0 +1,173 @@
|
|||||||
|
<!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>Reset Password Basic - Pages | Materialize - Material Design HTML 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">
|
||||||
|
<!-- Canonical SEO -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ? 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">
|
||||||
|
|
||||||
|
<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 -->
|
||||||
|
<!-- Reset Password -->
|
||||||
|
<div class="card-body">
|
||||||
|
<h4 class="mb-1"> 重新設定密碼 🔒</h4>
|
||||||
|
<p class="mb-5">請設定新密碼</p>
|
||||||
|
<form id="formAuthentication" class="mb-5" action="{{ route('change.password.put') }}" method="POST">
|
||||||
|
@csrf
|
||||||
|
@method('PUT')
|
||||||
|
<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="············" aria-describedby="password" />
|
||||||
|
<label for="password">新密碼</label>
|
||||||
|
</div>
|
||||||
|
<span class="input-group-text cursor-pointer"><i class="ri-eye-off-line"></i></span>
|
||||||
|
</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="confirm-password" class="form-control" name="confirm-password" placeholder="············" aria-describedby="password" />
|
||||||
|
<label for="confirm-password">確認密碼</label>
|
||||||
|
</div>
|
||||||
|
<span class="input-group-text cursor-pointer"><i class="ri-eye-off-line"></i></span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary d-grid w-100 mb-5">
|
||||||
|
Set new password
|
||||||
|
</button>
|
||||||
|
<div class="text-center">
|
||||||
|
<a href="auth-login-basic.html" class="d-flex align-items-center justify-content-center">
|
||||||
|
<i class="ri-arrow-left-s-line scaleX-n1-rtl ri-20px me-1_5"></i>
|
||||||
|
Back to login
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /Reset Password -->
|
||||||
|
<img alt="mask" src="{{asset('assets')}}/img/illustrations/auth-basic-reset-password-mask-light.png" class="authentication-image d-none d-lg-block" data-app-light-img="illustrations/auth-basic-reset-password-mask-light.png" data-app-dark-img="illustrations/auth-basic-reset-password-mask-dark.png" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- / Content -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 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 -->
|
||||||
|
<script src="{{asset('assets')}}/js/pages-auth.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
||||||
|
<!-- beautify ignore:end -->
|
||||||
|
|
||||||
227
resources/views/front/auth/forgot-password.blade.php
Normal file
227
resources/views/front/auth/forgot-password.blade.php
Normal file
@ -0,0 +1,227 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<!-- beautify ignore:start -->
|
||||||
|
|
||||||
|
|
||||||
|
<html lang="en" class="dark-style layout-wide dark customizer-hide" dir="ltr" data-theme="theme-bordered" data-assets-path="../../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" />
|
||||||
|
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||||
|
<title>忘記密碼</title>
|
||||||
|
|
||||||
|
|
||||||
|
<meta name="description" content="Materialize – is the most developer friendly & highly customizable Admin Dashboard Template." />
|
||||||
|
<meta name="keywords" content="cafeg coffee">
|
||||||
|
<!-- Canonical SEO -->
|
||||||
|
|
||||||
|
|
||||||
|
<!-- ? 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="../../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="../../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="../../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">
|
||||||
|
|
||||||
|
<!-- 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" style="padding-top:5%">
|
||||||
|
<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="email" name="email" placeholder="輸入您的電子郵件" autofocus>
|
||||||
|
<label>電子郵件</label>
|
||||||
|
</div>
|
||||||
|
<button class="btn btn-primary d-grid w-100" id="confirm">發送連結</button>
|
||||||
|
</form>
|
||||||
|
<div class="text-center">
|
||||||
|
<a href="{{ route('front.login.view') }}" class="d-flex align-items-center justify-content-center">
|
||||||
|
<i class="ri-arrow-left-s-line scaleX-n1-rtl ri-20px me-1_5"></i>
|
||||||
|
回到登入
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- /Forgot Password -->
|
||||||
|
<img alt="mask" src="../../assets/img/illustrations/auth-basic-forgot-password-mask-light.png" class="authentication-image d-none d-lg-block" data-app-light-img="illustrations/auth-basic-forgot-password-mask-light.png" data-app-dark-img="illustrations/auth-basic-forgot-password-mask-dark.png" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<!-- / Content -->
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<!-- 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 -->
|
||||||
|
<script src="{{ asset('assets/') }}/js/pages-auth.js"></script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
|
||||||
|
|
||||||
|
</html>
|
||||||
|
|
||||||
|
<!-- beautify ignore:end -->
|
||||||
|
|
||||||
|
<script>
|
||||||
|
$("#confirm").on('click', function(event) {
|
||||||
|
event.preventDefault(); // 阻止表单提交
|
||||||
|
|
||||||
|
var email = $("#email").val();
|
||||||
|
if (!email) {
|
||||||
|
Swal.fire({
|
||||||
|
title: '錯誤',
|
||||||
|
text: "請輸入電子郵件",
|
||||||
|
icon: 'warning',
|
||||||
|
confirmButtonText: '确定'
|
||||||
|
});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log('email confirm');
|
||||||
|
$.ajax({
|
||||||
|
type: "post",
|
||||||
|
url: "{{ route('email.password.post') }}",
|
||||||
|
data: {
|
||||||
|
email: email
|
||||||
|
},
|
||||||
|
headers: {
|
||||||
|
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
|
||||||
|
},
|
||||||
|
dataType: "json",
|
||||||
|
success: function(response) {
|
||||||
|
console.log('Server response:', response);
|
||||||
|
if (response.status == 'success') {
|
||||||
|
Swal.fire({
|
||||||
|
title: '成功',
|
||||||
|
text: "重新設定密碼連結已發送",
|
||||||
|
icon: 'success',
|
||||||
|
confirmButtonText: '确定'
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
Swal.fire({
|
||||||
|
title: '失敗',
|
||||||
|
text: "未找到有效的帳號",
|
||||||
|
icon: 'error',
|
||||||
|
confirmButtonText: '确定'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function(xhr, status, error) {
|
||||||
|
console.log('Error:', error);
|
||||||
|
Swal.fire({
|
||||||
|
title: '錯誤',
|
||||||
|
text: "系統錯誤,請稍後再試",
|
||||||
|
icon: 'error',
|
||||||
|
confirmButtonText: '确定'
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
</script>
|
||||||
@ -8,7 +8,7 @@
|
|||||||
|
|
||||||
<title>卡菲姬登入</title>
|
<title>卡菲姬登入</title>
|
||||||
<meta name="description" content="Materialize – is the most developer friendly & highly customizable Admin Dashboard Template." />
|
<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">
|
<meta name="keywords" content="cafeg 卡菲姬">
|
||||||
<!-- laravel CRUD token -->
|
<!-- laravel CRUD token -->
|
||||||
<meta name="csrf-token" content="6fa8KEfKxuHo22PqMwHmCoxMDArqCNYyqRXJNZSE">
|
<meta name="csrf-token" content="6fa8KEfKxuHo22PqMwHmCoxMDArqCNYyqRXJNZSE">
|
||||||
<!-- Canonical SEO -->
|
<!-- Canonical SEO -->
|
||||||
@ -145,7 +145,7 @@
|
|||||||
記住 我
|
記住 我
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
<a href="forgot-password-basic.html" class="float-end mb-1 mt-2">
|
<a href="{{ route('email.password') }}" class="float-end mb-1 mt-2">
|
||||||
<span>忘記密碼?</span>
|
<span>忘記密碼?</span>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
<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">
|
<html lang="en" class="dark-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>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<meta name="description" content="卡菲姬 cafeg 是一個自助咖啡機 " />
|
<meta name="description" content="卡菲姬 cafeg 是一個自助咖啡機 " />
|
||||||
<meta name="keywords" content="smart-cafe-g smart-cafe smart-coffee">
|
<meta name="keywords" content="smart-cafe-g smart-cafe smart-coffee">
|
||||||
<!-- laravel CRUD token -->
|
<!-- laravel CRUD token -->
|
||||||
<meta name="csrf-token" content="6fa8KEfKxuHo22PqMwHmCoxMDArqCNYyqRXJNZSE">
|
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||||
<!-- Canonical SEO -->
|
<!-- Canonical SEO -->
|
||||||
<!-- Favicon -->
|
<!-- Favicon -->
|
||||||
<link rel="icon" type="image/x-icon" href="../../demo/assets/img/favicon/favicon.ico" />
|
<link rel="icon" type="image/x-icon" href="../../demo/assets/img/favicon/favicon.ico" />
|
||||||
|
|||||||
@ -125,7 +125,7 @@
|
|||||||
{{-- </a> --}}
|
{{-- </a> --}}
|
||||||
{{-- </li> --}}
|
{{-- </li> --}}
|
||||||
<li>
|
<li>
|
||||||
<a class="dropdown-item" href="pages-account-settings-billing.html">
|
<a class="dropdown-item" href="#">
|
||||||
<span class="d-flex align-items-center align-middle">
|
<span class="d-flex align-items-center align-middle">
|
||||||
<i class="flex-shrink-0 ri-file-text-line ri-22px me-3"></i>
|
<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-grow-1 align-middle">交易紀錄</span>
|
||||||
|
|||||||
@ -35,11 +35,18 @@
|
|||||||
Route::get('login/line/callback', [LoginController::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::get('register', [RegisterController::class, 'index'])->name('member.register');
|
||||||
Route::post('register/create', [RegisterController::class, 'create'])->name('member.register.create');
|
Route::post('register/create', [RegisterController::class, 'create'])->name('member.register.create');
|
||||||
//前台route 登入後;
|
|
||||||
|
|
||||||
Route::get('email/verify', [EmailController::class, 'index'])->name('email.verify');
|
Route::get('email/verify', [EmailController::class, 'index'])->name('email.verify');
|
||||||
|
Route::get('email/password', [RegisterController::class, 'forgotPassword'])->name('email.password');
|
||||||
|
Route::post('email/password', [RegisterController::class, 'sendForgotPassword'])->name('email.password.post');
|
||||||
|
Route::get('resetpassword', [RegisterController::class, 'resetPassword'])->name('reset.password.token');
|
||||||
|
Route::get('changepassword/{id}', [RegisterController::class, 'changePassword'])->name('change.password');
|
||||||
|
Route::put('changepassword/{id}', [RegisterController::class, 'resetPasswordProcess'])->name('change.password.put');
|
||||||
|
|
||||||
Route::any('checkphone', [MemberController::class, 'checkPhone'])->name('member.checkphone');
|
Route::any('checkphone', [MemberController::class, 'checkPhone'])->name('member.checkphone');
|
||||||
|
|
||||||
|
|
||||||
|
//前台route 登入後;
|
||||||
Route::prefix('member')
|
Route::prefix('member')
|
||||||
->middleware(memberAuth::class) // 使用自定义守卫的中间件
|
->middleware(memberAuth::class) // 使用自定义守卫的中间件
|
||||||
->as('member.')
|
->as('member.')
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user