feat : halaman login,install reCaptcha & laravel notify,membuat traits,login validasi dan membuat templating untuk auth

This commit is contained in:
Yoga Pangestu 2024-11-17 19:38:04 +07:00
parent 8aedc00e27
commit c9bdef47f8
25 changed files with 11224 additions and 8830 deletions

View File

@ -0,0 +1,43 @@
<?php
namespace App\Http\Controllers\Admin\Auth;
use App\Http\Controllers\Controller;
use App\Http\Requests\Auth\LoginRequest;
use Illuminate\Contracts\View\View;
use Illuminate\Http\RedirectResponse;
use Illuminate\Support\Facades\Auth;
class LoginController extends Controller
{
public function index(): View
{
return view('pages.auth.login', [
'pageTitle' => 'Masuk Akun',
'metaDesc' => 'Masuk akun untuk mengakses admin panel',
]);
}
public function auth(LoginRequest $request): RedirectResponse
{
$validatedData = $request->validated();
$identifier = filter_var($validatedData['login'], FILTER_VALIDATE_EMAIL) ? 'email' : 'username';
if (Auth::attempt([
$identifier => $validatedData['login'],
'password' => $validatedData['password'],
])) {
$user = Auth::user();
if ($user->is_active == 1) {
notify()->success("Selamat datang ' . $user->full_name", 'Berhasil');
return redirect('dashboard/overview');
} else {
Auth::logout();
notify()->success('Akun Anda saat ini tidak aktif. Silakan hubungi administrator untuk informasi lebih lanjut', 'Berhasil');
return redirect('auth/login');
}
}
}
}

View File

@ -0,0 +1,31 @@
<?php
namespace App\Http\Requests\Auth;
use App\Traits\NotificationTrait;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Foundation\Http\FormRequest;
class LoginRequest extends FormRequest
{
use NotificationTrait;
public function authorize(): bool
{
return true;
}
public function rules(): array
{
return [
'login' => ['required', 'string', 'email'],
'password' => ['required', 'string'],
'g-recaptcha-response' => 'recaptcha',
];
}
protected function failedValidation(Validator $validator): void
{
$this->handleValidationFailure($validator);
}
}

View File

@ -0,0 +1,20 @@
<?php
namespace App\Traits;
use Illuminate\Contracts\Validation\Validator;
use Illuminate\Validation\ValidationException;
trait NotificationTrait
{
public function handleValidationFailure(Validator $validator): void
{
notify()->warning('Silakan periksa data yang Anda masukkan', 'Peringatan');
$response = redirect()
->back()
->withInput()
->withErrors($validator);
throw new ValidationException($validator, $response);
}
}

View File

@ -6,8 +6,10 @@
"license": "MIT",
"require": {
"php": "^8.2",
"biscolab/laravel-recaptcha": "^6.1",
"laravel/framework": "^11.9",
"laravel/tinker": "^2.9"
"laravel/tinker": "^2.9",
"mckenziearts/laravel-notify": "^2.5"
},
"require-dev": {
"fakerphp/faker": "^1.23",

144
composer.lock generated
View File

@ -4,8 +4,80 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "589cc0f65c3aaa7d4e9024d545bc1974",
"content-hash": "69b4211969f0ad57380a0caf4b963f20",
"packages": [
{
"name": "biscolab/laravel-recaptcha",
"version": "v6.1.0",
"source": {
"type": "git",
"url": "https://github.com/biscolab/laravel-recaptcha.git",
"reference": "440fc617cba9f39aab7fda5d7697b76a55286e31"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/biscolab/laravel-recaptcha/zipball/440fc617cba9f39aab7fda5d7697b76a55286e31",
"reference": "440fc617cba9f39aab7fda5d7697b76a55286e31",
"shasum": ""
},
"require": {
"illuminate/routing": "^7.0|^8.0|^9.0|^10.0|^11.0",
"illuminate/support": "^7.0|^8.0|^9.0|^10.0|^11.0",
"php": "^7.3|^8.0"
},
"require-dev": {
"orchestra/testbench": "5.*|6.*|^7.0|^8.0|^9.0",
"phpunit/phpunit": "^9.1|^10.5"
},
"suggest": {
"biscolab/laravel-authlog": "It allows to handle logged-in users and force log-out if needed"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Biscolab\\ReCaptcha\\ReCaptchaServiceProvider"
],
"aliases": {
"ReCaptcha": "Biscolab\\ReCaptcha\\Facades\\ReCaptcha"
}
}
},
"autoload": {
"files": [
"src/helpers.php"
],
"psr-4": {
"Biscolab\\ReCaptcha\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roberto Belotti",
"email": "roby.belotti@gmail.com",
"homepage": "https://biscolab.com",
"role": "Developer"
}
],
"description": "Simple and painless Google reCAPTCHA package for Laravel framework",
"homepage": "https://biscolab.com/laravel-recaptcha",
"keywords": [
"captcha",
"laravel",
"recaptcha",
"validation"
],
"support": {
"issues": "https://github.com/biscolab/laravel-recaptcha/issues",
"source": "https://github.com/biscolab/laravel-recaptcha/tree/v6.1.0"
},
"abandoned": true,
"time": "2024-03-27T11:06:21+00:00"
},
{
"name": "brick/math",
"version": "0.12.1",
@ -1825,6 +1897,76 @@
],
"time": "2024-09-21T08:32:55+00:00"
},
{
"name": "mckenziearts/laravel-notify",
"version": "v2.5",
"source": {
"type": "git",
"url": "https://github.com/mckenziearts/laravel-notify.git",
"reference": "eafcd81abd0afd780176b7a09a87f7dae87c994f"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/mckenziearts/laravel-notify/zipball/eafcd81abd0afd780176b7a09a87f7dae87c994f",
"reference": "eafcd81abd0afd780176b7a09a87f7dae87c994f",
"shasum": ""
},
"require": {
"illuminate/support": "^8.0|^9.0|^10.0|^11.0",
"php": "~8.0"
},
"require-dev": {
"laravel/pint": "^1.6",
"mockery/mockery": "^1.0",
"phpunit/phpunit": "^8.0|^9.0|^10.5"
},
"type": "library",
"extra": {
"laravel": {
"providers": [
"Mckenziearts\\Notify\\LaravelNotifyServiceProvider"
],
"aliases": {
"Notify": "Mckenziearts\\Notify\\Facades\\LaravelNotify"
}
}
},
"autoload": {
"files": [
"src/helpers.php"
],
"psr-4": {
"Mckenziearts\\Notify\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Arthur Monney",
"email": "monneylobe@gmail.com"
}
],
"description": "Flexible flash notifications for Laravel",
"keywords": [
"laravel",
"laravel-notify",
"notification"
],
"support": {
"issues": "https://github.com/mckenziearts/laravel-notify/issues",
"source": "https://github.com/mckenziearts/laravel-notify"
},
"funding": [
{
"url": "https://paypal.me/jvquilichini?locale.x=fr_FR",
"type": "custom"
}
],
"time": "2024-05-23T17:16:27+00:00"
},
{
"name": "monolog/monolog",
"version": "3.8.0",

49
config/notify.php Normal file
View File

@ -0,0 +1,49 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Notify Theme
|--------------------------------------------------------------------------
|
| You can change the theme of notifications by specifying the desired theme.
| By default the theme light is activated, but you can change it by
| specifying the dark mode. To change theme, update the global variable to `dark`
|
*/
'theme' => env('NOTIFY_THEME', 'light'),
/*
|--------------------------------------------------------------------------
| Notification timeout
|--------------------------------------------------------------------------
|
| Defines the number of seconds during which the notification will be visible.
|
*/
'timeout' => 5000,
/*
|--------------------------------------------------------------------------
| Preset Messages
|--------------------------------------------------------------------------
|
| Define any preset messages here that can be reused.
| Available model: connect, drake, emotify, smiley, toast
|
*/
'preset-messages' => [
// An example preset 'user updated' Connectify notification.
'user-updated' => [
'message' => 'The user has been updated successfully.',
'type' => 'success',
'model' => 'connect',
'title' => 'User Updated',
],
],
];

162
config/recaptcha.php Normal file
View File

@ -0,0 +1,162 @@
<?php
/**
* Copyright (c) 2017 - present
* LaravelGoogleRecaptcha - recaptcha.php
* author: Roberto Belotti - roby.belotti@gmail.com
* web : robertobelotti.com, github.com/biscolab
* Initial version created on: 12/9/2018
* MIT license: https://github.com/biscolab/laravel-recaptcha/blob/master/LICENSE
*/
/**
* To configure correctly please visit https://developers.google.com/recaptcha/docs/start
*/
return [
/**
* The site key
* get site key @ www.google.com/recaptcha/admin
*/
'api_site_key' => env('RECAPTCHA_SITE_KEY', ''),
/**
* The secret key
* get secret key @ www.google.com/recaptcha/admin
*/
'api_secret_key' => env('RECAPTCHA_SECRET_KEY', ''),
/**
* ReCATCHA version
* Supported: "v2", "invisible", "v3",
*
* get more info @ https://developers.google.com/recaptcha/docs/versions
*/
'version' => 'v2',
/**
* The curl timout in seconds to validate a recaptcha token
*
* @since v3.5.0
*/
'curl_timeout' => 10,
/**
* IP addresses for which validation will be skipped
* IP/CIDR netmask eg. 127.0.0.0/24, also 127.0.0.1 is accepted and /32 assumed
*/
'skip_ip' => env('RECAPTCHA_SKIP_IP', []),
/**
* Default route called to check the Google reCAPTCHA token
*
* @since v3.2.0
*/
'default_validation_route' => 'biscolab-recaptcha/validate',
/**
* The name of the parameter used to send Google reCAPTCHA token to verify route
*
* @since v3.2.0
*/
'default_token_parameter_name' => 'token',
/**
* The default Google reCAPTCHA language code
* It has no effect with v3
*
* @see https://developers.google.com/recaptcha/docs/language
* @since v3.6.0
*/
'default_language' => null,
/**
* The default form ID. Only for "invisible" reCAPTCHA
*
* @since v4.0.0
*/
'default_form_id' => 'biscolab-recaptcha-invisible-form',
/**
* Deferring the render can be achieved by specifying your onload callback function and adding parameters to the JavaScript resource.
* It has no effect with v3 and invisible
*
* @see https://developers.google.com/recaptcha/docs/display#explicit_render
* @since v4.0.0
* Supported true, false
*/
'explicit' => false,
/**
* Set API domain. You can use "www.recaptcha.net" in case "www.google.com" is not accessible.
* (no check will be made on the entered value)
*
* @see https://developers.google.com/recaptcha/docs/faq#can-i-use-recaptcha-globally
* @since v4.3.0
* Default 'www.google.com' (ReCaptchaBuilder::DEFAULT_RECAPTCHA_API_DOMAIN)
*/
'api_domain' => 'www.google.com',
/**
* Set `true` when the error message must be null
*
* @since v5.1.0
* Default false
*/
'empty_message' => false,
/**
* Set either the error message or the errom message translation key
*
* @since v5.1.0
* Default 'validation.recaptcha'
*/
'error_message_key' => 'validation.recaptcha',
/**
* g-recaptcha tag attributes and grecaptcha.render parameters (v2 only)
*
* @see https://developers.google.com/recaptcha/docs/display#render_param
* @since v4.0.0
*/
'tag_attributes' => [
/**
* The color theme of the widget.
* Supported "light", "dark"
*/
'theme' => 'light',
/**
* The size of the widget.
* Supported "normal", "compact"
*/
'size' => 'normal',
/**
* The tabindex of the widget and challenge.
* If other elements in your page use tabindex, it should be set to make user navigation easier.
*/
'tabindex' => 0,
/**
* The name of your callback function, executed when the user submits a successful response.
* The g-recaptcha-response token is passed to your callback.
* DO NOT SET "biscolabOnloadCallback"
*/
'callback' => null,
/**
* The name of your callback function, executed when the reCAPTCHA response expires and the user needs to re-verify.
* DO NOT SET "biscolabOnloadCallback"
*/
'expired-callback' => null,
/**
* The name of your callback function, executed when reCAPTCHA encounters an error (usually network connectivity) and cannot continue until connectivity is restored.
* If you specify a function here, you are responsible for informing the user that they should retry.
* DO NOT SET "biscolabOnloadCallback"
*/
'error-callback' => null,
],
];

View File

@ -28334,7 +28334,6 @@ .login-card .login-main .theme-form .or:before {
right: 0;
}
.login-card .login-main .theme-form input {
background-color: #f3f3ff;
transition: all 0.3s ease;
}
.login-card .login-main .theme-form input::-webkit-input-placeholder {

File diff suppressed because it is too large Load Diff

View File

@ -1,374 +1,356 @@
/*! -----------------------------------------------------------------------------------
Template Name: Cuba Admin
Template URI: http://admin.pixelstrap.com/cuba/theme
Description: This is Admin theme
Author: Pixelstrap
Author URI: https://themeforest.net/user/pixelstrap
-----------------------------------------------------------------------------------
01. password show hide
02. Background Image js
03. sidebar filter
04. Language js
05. Translate js
--------------------------------------------------------------------------------- */
(function ($) {
"use strict";
$(document).on("click", function (e) {
var outside_space = $(".outside");
if (
!outside_space.is(e.target) &&
outside_space.has(e.target).length === 0
) {
$(".menu-to-be-close").removeClass("d-block");
$(".menu-to-be-close").css("display", "none");
}
});
$(".prooduct-details-box .close").on("click", function (e) {
var tets = $(this).parent().parent().parent().parent().addClass("d-none");
console.log(tets);
});
if ($(".page-wrapper").hasClass("horizontal-wrapper")) {
$(".sidebar-list").hover(
function () {
$(this).addClass("hoverd");
},
function () {
$(this).removeClass("hoverd");
}
);
$(window).on("scroll", function () {
if ($(this).scrollTop() < 600) {
$(".sidebar-list").removeClass("hoverd");
}
});
}
/*----------------------------------------
password show hide
----------------------------------------*/
$(".show-hide").show();
$(".show-hide span").addClass("show");
$(".show-hide span").click(function () {
if ($(this).hasClass("show")) {
$('input[name="login[password]"]').attr("type", "text");
$(this).removeClass("show");
} else {
$('input[name="login[password]"]').attr("type", "password");
$(this).addClass("show");
}
});
$('form button[type="submit"]').on("click", function () {
$(".show-hide span").addClass("show");
$(".show-hide")
.parent()
.find('input[name="login[password]"]')
.attr("type", "password");
});
/*=====================
02. Background Image js
==========================*/
$(".bg-center").parent().addClass("b-center");
$(".bg-img-cover").parent().addClass("bg-size");
$(".bg-img-cover").each(function () {
var el = $(this),
src = el.attr("src"),
parent = el.parent();
parent.css({
"background-image": "url(" + src + ")",
"background-size": "cover",
"background-position": "center",
display: "block",
});
el.hide();
});
$(".mega-menu-container").css("display", "none");
$(".header-search").click(function () {
$(".search-full").addClass("open");
});
$(".close-search").click(function () {
$(".search-full").removeClass("open");
$("body").removeClass("offcanvas");
});
$(".mobile-toggle").click(function () {
$(".nav-menus").toggleClass("open");
});
$(".mobile-toggle-left").click(function () {
$(".left-header").toggleClass("open");
});
$(".bookmark-search").click(function () {
$(".form-control-search").toggleClass("open");
});
$(".filter-toggle").click(function () {
$(".product-sidebar").toggleClass("open");
});
$(".toggle-data").click(function () {
$(".product-wrapper").toggleClass("sidebaron");
});
$(".form-control-search input").keyup(function (e) {
if (e.target.value) {
$(".page-wrapper").addClass("offcanvas-bookmark");
} else {
$(".page-wrapper").removeClass("offcanvas-bookmark");
}
});
$(".search-full input").keyup(function (e) {
console.log(e.target.value);
if (e.target.value) {
$("body").addClass("offcanvas");
} else {
$("body").removeClass("offcanvas");
}
});
$("body").keydown(function (e) {
if (e.keyCode == 27) {
$(".search-full input").val("");
$(".form-control-search input").val("");
$(".page-wrapper").removeClass("offcanvas-bookmark");
$(".search-full").removeClass("open");
$(".search-form .form-control-search").removeClass("open");
$("body").removeClass("offcanvas");
}
});
$(".mode").on("click", function () {
const bodyModeDark = $("body").hasClass("dark-only");
if (!bodyModeDark) {
$(".mode").addClass("active");
localStorage.setItem("mode-cuba", "dark-only");
$("body").addClass("dark-only");
$("body").removeClass("light");
}
if (bodyModeDark) {
$(".mode").removeClass("active");
localStorage.setItem("mode-cuba", "light");
$("body").removeClass("dark-only");
$("body").addClass("light");
}
});
$("body").addClass(
localStorage.getItem("mode-cuba")
? localStorage.getItem("mode-cuba")
: "light"
);
$(".mode").addClass(
localStorage.getItem("mode-cuba") === "dark-only" ? "active" : " "
);
// sidebar filter
$(".md-sidebar .md-sidebar-toggle ").on("click", function (e) {
$(".md-sidebar .md-sidebar-aside ").toggleClass("open");
});
$(".loader-wrapper").fadeOut("slow", function () {
$(this).remove();
});
$(window).on("scroll", function () {
if ($(this).scrollTop() > 600) {
$(".tap-top").fadeIn();
} else {
$(".tap-top").fadeOut();
}
});
$(".tap-top").click(function () {
$("html, body").animate(
{
scrollTop: 0,
},
600
);
return false;
});
(function ($, window, document, undefined) {
"use strict";
var $ripple = $(".js-ripple");
$ripple.on("click.ui.ripple", function (e) {
var $this = $(this);
var $offset = $this.parent().offset();
var $circle = $this.find(".c-ripple__circle");
var x = e.pageX - $offset.left;
var y = e.pageY - $offset.top;
$circle.css({
top: y + "px",
left: x + "px",
});
$this.addClass("is-active");
$(document).on("click", function (e) {
var outside_space = $(".outside");
if (
!outside_space.is(e.target) &&
outside_space.has(e.target).length === 0
) {
$(".menu-to-be-close").removeClass("d-block");
$(".menu-to-be-close").css("display", "none");
}
});
$ripple.on(
"animationend webkitAnimationEnd oanimationend MSAnimationEnd",
function (e) {
$(this).removeClass("is-active");
}
);
})(jQuery, window, document);
// active link
$(".prooduct-details-box .close").on("click", function (e) {
var tets = $(this).parent().parent().parent().parent().addClass("d-none");
console.log(tets);
});
$(".chat-menu-icons .toogle-bar").click(function () {
$(".chat-menu").toggleClass("show");
});
// Language
var tnum = "en";
$(document).ready(function () {
if (localStorage.getItem("primary") != null) {
var primary_val = localStorage.getItem("primary");
$("#ColorPicker1").val(primary_val);
var secondary_val = localStorage.getItem("secondary");
$("#ColorPicker2").val(secondary_val);
if ($(".page-wrapper").hasClass("horizontal-wrapper")) {
$(".sidebar-list").hover(
function () {
$(this).addClass("hoverd");
},
function () {
$(this).removeClass("hoverd");
}
);
$(window).on("scroll", function () {
if ($(this).scrollTop() < 600) {
$(".sidebar-list").removeClass("hoverd");
}
});
}
$(document).click(function (e) {
$(".translate_wrapper, .more_lang").removeClass("active");
});
$(".translate_wrapper .current_lang").click(function (e) {
e.stopPropagation();
$(this).parent().toggleClass("active");
/*----------------------------------------
password show hide
----------------------------------------*/
$(".show-hide").show();
$(".show-hide span").addClass("show");
setTimeout(function () {
$(".more_lang").toggleClass("active");
}, 5);
$(".show-hide span").click(function () {
if ($(this).hasClass("show")) {
$('#password').attr("type", "text");
$(this).removeClass("show");
} else {
$('#password').attr("type", "password");
$(this).addClass("show");
}
});
$('form button[type="submit"]').on("click", function () {
$(".show-hide span").addClass("show");
$(".show-hide")
.parent()
.find('#password')
.attr("type", "password");
});
/*TRANSLATE*/
translate(tnum);
$(".more_lang .lang").click(function () {
$(this).addClass("selected").siblings().removeClass("selected");
$(".more_lang").removeClass("active");
var i = $(this).find("i").attr("class");
var lang = $(this).attr("data-value");
var tnum = lang;
translate(tnum);
$(".current_lang .lang-txt").text(lang);
$(".current_lang i").attr("class", i);
/*=====================
02. Background Image js
==========================*/
$(".bg-center").parent().addClass("b-center");
$(".bg-img-cover").parent().addClass("bg-size");
$(".bg-img-cover").each(function () {
var el = $(this),
src = el.attr("src"),
parent = el.parent();
parent.css({
"background-image": "url(" + src + ")",
"background-size": "cover",
"background-position": "center",
display: "block",
});
el.hide();
});
});
function translate(tnum) {
$(".lan-1").text(trans[0][tnum]);
$(".lan-2").text(trans[1][tnum]);
$(".lan-3").text(trans[2][tnum]);
$(".lan-4").text(trans[3][tnum]);
$(".lan-5").text(trans[4][tnum]);
$(".lan-6").text(trans[5][tnum]);
$(".lan-7").text(trans[6][tnum]);
$(".lan-8").text(trans[7][tnum]);
$(".lan-9").text(trans[8][tnum]);
}
$(".mega-menu-container").css("display", "none");
$(".header-search").click(function () {
$(".search-full").addClass("open");
});
$(".close-search").click(function () {
$(".search-full").removeClass("open");
$("body").removeClass("offcanvas");
});
$(".mobile-toggle").click(function () {
$(".nav-menus").toggleClass("open");
});
$(".mobile-toggle-left").click(function () {
$(".left-header").toggleClass("open");
});
$(".bookmark-search").click(function () {
$(".form-control-search").toggleClass("open");
});
$(".filter-toggle").click(function () {
$(".product-sidebar").toggleClass("open");
});
$(".toggle-data").click(function () {
$(".product-wrapper").toggleClass("sidebaron");
});
$(".form-control-search input").keyup(function (e) {
if (e.target.value) {
$(".page-wrapper").addClass("offcanvas-bookmark");
} else {
$(".page-wrapper").removeClass("offcanvas-bookmark");
}
});
$(".search-full input").keyup(function (e) {
console.log(e.target.value);
if (e.target.value) {
$("body").addClass("offcanvas");
} else {
$("body").removeClass("offcanvas");
}
});
var trans = [
{
en: "General",
pt: "Geral",
es: "Generalo",
fr: "Générale",
de: "Generel",
cn: "一般",
ae: "حجنرال لواء",
},
{
en: "Dashboards,widgets & layout.",
pt: "Painéis, widgets e layout.",
es: "Paneloj, fenestraĵoj kaj aranĝo.",
fr: "Tableaux de bord, widgets et mise en page.",
de: "Dashboards, widgets en lay-out.",
cn: "仪表板,小工具和布局。",
ae: "لوحات المعلومات والأدوات والتخطيط.",
},
{
en: "Dashboards",
pt: "Painéis",
es: "Paneloj",
fr: "Tableaux",
de: "Dashboards",
cn: " 仪表板 ",
ae: "وحات القيادة ",
},
{
en: "Default",
pt: "Padrão",
es: "Vaikimisi",
fr: "Défaut",
de: "Standaard",
cn: "電子商務",
ae: "وإفتراضي",
},
{
en: "Ecommerce",
pt: "Comércio eletrônico",
es: "Komerco",
fr: "Commerce électronique",
de: "E-commerce",
cn: "電子商務",
ae: "والتجارة الإلكترونية",
},
{
en: "Widgets",
pt: "Ferramenta",
es: "Vidin",
fr: "Widgets",
de: "Widgets",
cn: "小部件",
ae: "والحاجيات",
},
{
en: "Page layout",
pt: "Layout da página",
es: "Paĝa aranĝo",
fr: "Tableaux",
de: "Mise en page",
cn: "é é¢ä½ˆå±€",
ae: "وتخطيط الصفحة",
},
{
en: "Applications",
pt: "Formulários",
es: "Aplikoj",
fr: "Applications",
de: "Toepassingen",
cn: "æ‡‰ç”¨é ˜åŸŸ",
ae: "والتطبيقات",
},
{
en: "Ready to use Apps",
pt: "Pronto para usar aplicativos",
es: "Preta uzi Apps",
fr: " Applications prêtes à lemploi ",
de: "Klaar om apps te gebruiken",
cn: "仪表板",
ae: "جاهز لاستخدام التطبيقات",
},
];
$("body").keydown(function (e) {
if (e.keyCode == 27) {
$(".search-full input").val("");
$(".form-control-search input").val("");
$(".page-wrapper").removeClass("offcanvas-bookmark");
$(".search-full").removeClass("open");
$(".search-form .form-control-search").removeClass("open");
$("body").removeClass("offcanvas");
}
});
$(".mode").on("click", function () {
const bodyModeDark = $("body").hasClass("dark-only");
$(".mobile-title svg").click(function () {
$(".header-mega").toggleClass("d-block");
});
if (!bodyModeDark) {
$(".mode").addClass("active");
localStorage.setItem("mode-cuba", "dark-only");
$("body").addClass("dark-only");
$("body").removeClass("light");
}
if (bodyModeDark) {
$(".mode").removeClass("active");
localStorage.setItem("mode-cuba", "light");
$("body").removeClass("dark-only");
$("body").addClass("light");
}
});
$("body").addClass(
localStorage.getItem("mode-cuba")
? localStorage.getItem("mode-cuba")
: "light"
);
$(".mode").addClass(
localStorage.getItem("mode-cuba") === "dark-only" ? "active" : " "
);
$(".onhover-dropdown").on("click", function () {
$(this).children(".onhover-show-div").toggleClass("active");
});
// sidebar filter
$(".md-sidebar .md-sidebar-toggle ").on("click", function (e) {
$(".md-sidebar .md-sidebar-aside ").toggleClass("open");
});
$("#flip-btn").click(function () {
$(".flip-card-inner").addClass("flipped");
});
$(".loader-wrapper").fadeOut("slow", function () {
$(this).remove();
});
$("#flip-back").click(function () {
$(".flip-card-inner").removeClass("flipped");
});
$(window).on("scroll", function () {
if ($(this).scrollTop() > 600) {
$(".tap-top").fadeIn();
} else {
$(".tap-top").fadeOut();
}
});
$(".tap-top").click(function () {
$("html, body").animate(
{
scrollTop: 0,
},
600
);
return false;
});
(function ($, window, document, undefined) {
"use strict";
var $ripple = $(".js-ripple");
$ripple.on("click.ui.ripple", function (e) {
var $this = $(this);
var $offset = $this.parent().offset();
var $circle = $this.find(".c-ripple__circle");
var x = e.pageX - $offset.left;
var y = e.pageY - $offset.top;
$circle.css({
top: y + "px",
left: x + "px",
});
$this.addClass("is-active");
});
$ripple.on(
"animationend webkitAnimationEnd oanimationend MSAnimationEnd",
function (e) {
$(this).removeClass("is-active");
}
);
})(jQuery, window, document);
// active link
$(".chat-menu-icons .toogle-bar").click(function () {
$(".chat-menu").toggleClass("show");
});
// Language
var tnum = "en";
$(document).ready(function () {
if (localStorage.getItem("primary") != null) {
var primary_val = localStorage.getItem("primary");
$("#ColorPicker1").val(primary_val);
var secondary_val = localStorage.getItem("secondary");
$("#ColorPicker2").val(secondary_val);
}
$(document).click(function (e) {
$(".translate_wrapper, .more_lang").removeClass("active");
});
$(".translate_wrapper .current_lang").click(function (e) {
e.stopPropagation();
$(this).parent().toggleClass("active");
setTimeout(function () {
$(".more_lang").toggleClass("active");
}, 5);
});
/*TRANSLATE*/
translate(tnum);
$(".more_lang .lang").click(function () {
$(this).addClass("selected").siblings().removeClass("selected");
$(".more_lang").removeClass("active");
var i = $(this).find("i").attr("class");
var lang = $(this).attr("data-value");
var tnum = lang;
translate(tnum);
$(".current_lang .lang-txt").text(lang);
$(".current_lang i").attr("class", i);
});
});
function translate(tnum) {
$(".lan-1").text(trans[0][tnum]);
$(".lan-2").text(trans[1][tnum]);
$(".lan-3").text(trans[2][tnum]);
$(".lan-4").text(trans[3][tnum]);
$(".lan-5").text(trans[4][tnum]);
$(".lan-6").text(trans[5][tnum]);
$(".lan-7").text(trans[6][tnum]);
$(".lan-8").text(trans[7][tnum]);
$(".lan-9").text(trans[8][tnum]);
}
var trans = [
{
en: "General",
pt: "Geral",
es: "Generalo",
fr: "Générale",
de: "Generel",
cn: "一般",
ae: "حجنرال لواء",
},
{
en: "Dashboards,widgets & layout.",
pt: "Painéis, widgets e layout.",
es: "Paneloj, fenestraĵoj kaj aranĝo.",
fr: "Tableaux de bord, widgets et mise en page.",
de: "Dashboards, widgets en lay-out.",
cn: "仪表板,小工具和布局。",
ae: "لوحات المعلومات والأدوات والتخطيط.",
},
{
en: "Dashboards",
pt: "Painéis",
es: "Paneloj",
fr: "Tableaux",
de: "Dashboards",
cn: " 仪表板 ",
ae: "وحات القيادة ",
},
{
en: "Default",
pt: "Padrão",
es: "Vaikimisi",
fr: "Défaut",
de: "Standaard",
cn: "電子商務",
ae: "وإفتراضي",
},
{
en: "Ecommerce",
pt: "Comércio eletrônico",
es: "Komerco",
fr: "Commerce électronique",
de: "E-commerce",
cn: "電子商務",
ae: "والتجارة الإلكترونية",
},
{
en: "Widgets",
pt: "Ferramenta",
es: "Vidin",
fr: "Widgets",
de: "Widgets",
cn: "小部件",
ae: "والحاجيات",
},
{
en: "Page layout",
pt: "Layout da página",
es: "Paĝa aranĝo",
fr: "Tableaux",
de: "Mise en page",
cn: "é é¢ä½ˆå±€",
ae: "وتخطيط الصفحة",
},
{
en: "Applications",
pt: "Formulários",
es: "Aplikoj",
fr: "Applications",
de: "Toepassingen",
cn: "æ‡‰ç”¨é ˜åŸŸ",
ae: "والتطبيقات",
},
{
en: "Ready to use Apps",
pt: "Pronto para usar aplicativos",
es: "Preta uzi Apps",
fr: " Applications prêtes à lemploi ",
de: "Klaar om apps te gebruiken",
cn: "仪表板",
ae: "جاهز لاستخدام التطبيقات",
},
];
$(".mobile-title svg").click(function () {
$(".header-mega").toggleClass("d-block");
});
$(".onhover-dropdown").on("click", function () {
$(this).children(".onhover-show-div").toggleClass("active");
});
$("#flip-btn").click(function () {
$(".flip-card-inner").addClass("flipped");
});
$("#flip-back").click(function () {
$(".flip-card-inner").removeClass("flipped");
});
})(jQuery);

View File

@ -8,3 +8,7 @@ .profile-media img {
.mode-active i {
fill: #fff !important;
}
.notify {
z-index: 9999;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 359 KiB

View File

Before

Width:  |  Height:  |  Size: 3.2 KiB

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 3.6 KiB

After

Width:  |  Height:  |  Size: 3.6 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,4 @@
{
"/js/notify.js": "/js/notify.js?id=5a845f5a6d0b474b4f5e63bf941b6e1c",
"/dist/notify.css": "/dist/notify.css?id=098f683f0112ba9a3f65c8fa4f7b6056"
}

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html lang="en">
<head>
@include('partials._meta')
@include('partials.admin._css')
{!! ReCaptcha::htmlScriptTagJsApi() !!}
@notifyCss
</head>
<body>
@include('notify::components.notify')
@yield('app')
@include('partials.auth._js')
@notifyJs
</body>
</html>

View File

@ -0,0 +1,74 @@
@extends('layouts.auth')
@section('styles')
@endsection
@section('app')
<div class="container-fluid">
<div class="row">
<div class="col-xl-7 order-1">
<img class="bg-img-cover bg-center" src="{{ asset('assets/images/login-cover.jpeg') }}" alt="looginpage">
</div>
<div class="col-xl-5 p-0">
<div class="login-card login-dark">
<div>
<div>
<img class="img-fluid for-light" src="{{ asset('assets/images/logo/logo.png') }}"
alt="looginpage">
<img class="img-fluid for-dark" src="{{ asset('assets/images/logo/logo_dark.png') }}"
alt="looginpage">
</div>
<div class="login-main">
<form class="theme-form" action="{{ route('auth.login') }}" method="post">
@csrf
<h4>Masuk Akun</h4>
<p>Akses admin panel menggunakan <b>email</b> atau <b>nama pengguna</b> dan <b>kata
sandi</b>.</p>
<div class="form-group">
<label class="col-form-label">Email Atau Nama Pengguna</label>
<input name="login" class="form-control @error('login') is-invalid @enderror"
type="text" placeholder="Masukan email atau nama pengguna" autocomplete="off">
@error('login')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
</div>
<div class="form-group">
<label class="col-form-label">Kata Sandi</label>
<div class="form-input position-relative">
<input name="password" class="form-control @error('password') is-invalid @enderror"
type="password" placeholder="Masukan kata sandi" autocomplete="off"
id="password">
<div class="show-hide"><span class="show"> </span></div>
</div>
@error('password')
<div class="invalid-feedback">
{{ $message }}
</div>
@enderror
<a class="link" href="{{ route('auth.forgot-password') }}">Lupa kata sandi?</a>
</div>
<div
class="col-12 d-flex justify-content-center @error('g-recaptcha-response') is-invalid
@enderror">
<div> {!! htmlFormSnippet() !!} </div>
</div>
@error('g-recaptcha-response')
<div class="invalid-feedback d-flex justify-content-center">
{{ $message }}
</div>
@enderror
<div class="form-group mb-0">
<div class="text-end mt-3">
<button class="btn btn-lg btn-primary btn-block w-100" type="submit">Masuk</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
@section('scripts')
@endsection

View File

@ -0,0 +1,8 @@
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="title" content="Barbershop - Pesan Mudah dan Cepat">
<meta name="description" content="{{ $metaDesc }}">
<meta name="keywords" content="barbershop, potong rambut, cukur rambut, booking barbershop, layanan grooming">
<meta name="author" content="Barbershop">
<title>{{ $pageTitle }} - Barbershop</title>

View File

@ -2,8 +2,8 @@
<div>
<div class="logo-wrapper">
<a href="{{ route('dashboard.overview') }}">
<img class="img-fluid for-light" src="{{ asset('assets/admin/images/logo/logo.png') }}" alt="image">
<img class="img-fluid for-dark" src="{{ asset('assets/admin/images/logo/logo-dark.png') }}" alt="image">
<img class="img-fluid for-light" src="{{ asset('assets/images/logo/logo.png') }}" alt="image">
<img class="img-fluid for-dark" src="{{ asset('assets/images/logo/logo-dark.png') }}" alt="image">
</a>
<div class="back-btn">
<i class="fa fa-angle-left"></i>
@ -14,7 +14,7 @@
</div>
<div class="logo-icon-wrapper">
<a href="{{ route('dashboard.overview') }}">
<img class="img-fluid" src="{{ asset('assets/admin/images/logo/logo-icon.png') }}" alt="image">
<img class="img-fluid" src="{{ asset('assets/images/logo/logo-icon.png') }}" alt="image">
</a>
</div>
<nav class="sidebar-main">

View File

@ -0,0 +1,6 @@
<script src="{{ asset('assets/admin/js/jquery.min.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/bootstrap.bundle.min.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/icons/feather-icon/feather.min.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/icons/feather-icon/feather-icon.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/config.js?ver=1.0.0') }}"></script>
<script src="{{ asset('assets/admin/js/script.js?ver=1.0.0') }}"></script>

View File

@ -1,13 +1,16 @@
<?php
use App\Http\Controllers\Admin\Auth\LoginController;
use App\Http\Controllers\Admin\Dashboard\OverviewController;
use Illuminate\Support\Facades\Route;
// Route::group([
// 'middleware' => 'auth',
// 'prefix' => 'dashboard',
// ], function () {
// });
Route::prefix('auth')->group(function () {
Route::get('login', [LoginController::class, 'index'])->name('login');
Route::post('login', [LoginController::class, 'auth'])->name('auth.login');
Route::post('logout', [LoginController::class, 'logout'])->name('auth.logout');
Route::get('forgot-password', [LoginController::class, 'forgotPassword'])->name('auth.forgot-password');
});
Route::prefix('dashboard')->group(function () {
Route::get('overview', [OverviewController::class, 'index'])->name('dashboard.overview');