Initial Commit

This commit is contained in:
2026-01-07 15:46:00 +01:00
commit 7133af82e3
1454 changed files with 362274 additions and 0 deletions

View File

@@ -0,0 +1,63 @@
<!DOCTYPE html>
<html>
<head>
<!-- Basic Page Info -->
<meta charset="utf-8" />
<title>@yield('pageTitle')</title>
<!-- Site favicon -->
<link rel="apple-touch-icon" sizes="180x180" href="/back/vendors/images/apple-touch-icon.png" />
<link rel="icon" type="image/png" sizes="32x32" href="/back/vendors/images/favicon-32x32.png" />
<link rel="icon" type="image/png" sizes="16x16" href="/back/vendors/images/favicon-16x16.png" />
<!-- Mobile Specific Metas -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<!-- Google Font -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap"
rel="stylesheet" />
<!-- CSS -->
<link rel="stylesheet" type="text/css" href="/back/vendors/styles/core.css" />
<link rel="stylesheet" type="text/css" href="/back/vendors/styles/icon-font.min.css" />
<link rel="stylesheet" type="text/css" href="/back/vendors/styles/style.css" />
@yield('stylesheets')
</head>
<body class="login-page">
<div class="login-header box-shadow">
<div class="container-fluid d-flex justify-content-between align-items-center">
<div class="brand-logo">
<a href="/">
<img src="/images/site/{{ isset(settings()->site_logo) ? settings()->site_logo : '' }}"
alt="logo" />
</a>
</div>
<!-- <div class="login-menu">
<ul>
<li><a href="register.html">Register</a></li>
</ul>
</div> -->
</div>
</div>
<div class="login-wrap d-flex align-items-center flex-wrap justify-content-center">
<div class="container">
<div class="row align-items-center">
<div class="col-md-6 col-lg-7">
<img src="/back/vendors/images/login-page-img.png" alt="bg_image" />
</div>
<div class="col-md-6 col-lg-5">
@yield('content')
</div>
</div>
</div>
</div>
<!-- js -->
<script src="/back/vendors/scripts/core.js"></script>
<script src="/back/vendors/scripts/script.min.js"></script>
<script src="/back/vendors/scripts/process.js"></script>
<script src="/back/vendors/scripts/layout-settings.js"></script>
@yield('scripts')
</body>
</html>

View File

@@ -0,0 +1,296 @@
<!DOCTYPE html>
<html>
<head>
<!-- Basic Page Info -->
<meta charset="utf-8" />
<title>@yield('pageTitle')</title>
<meta name="csrf-token" content="{{ csrf_token() }}">
<!-- Site favicon -->
<link rel="icon" type="image/png" sizes="16x16"
whref="/images/site/{{ isset(settings()->site_favicon) ? settings()->site_favicon : '' }}" />
<!-- Mobile Specific Metas -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1" />
<!-- Google Font -->
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700;800&display=swap"
rel="stylesheet" />
<!-- CSS -->
<link rel="stylesheet" type="text/css" href="{{ asset('/back/vendors/styles/core.css') }}" />
<link rel="stylesheet" type="text/css" href="{{ asset('/back/vendors/styles/icon-font.min.css') }}" />
<link rel="stylesheet" type="text/css" href="{{ asset('/back/vendors/styles/style.css') }}" />
<link rel="stylesheet" href="{{ asset('/extra-assets/jquery-ui/jquery-ui.min.css') }}" />
<link rel="stylesheet" href="{{ asset('/extra-assets/jquery-ui/jquery-ui.structure.min.css') }}" />
<link rel="stylesheet" href="{{ asset('/extra-assets/jquery-ui/jquery-ui.theme.min.css') }}" />
<link rel="stylesheet" type="text/css"
href="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.css" />
@stack('stylesheets')
@kropifyStyles
</head>
<body>
<div class="header">
<div class="header-left">
<div class="menu-icon bi bi-list"></div>
<div class="search-toggle-icon bi bi-search" data-toggle="header_search"></div>
</div>
<div class="header-right">
<div class="dashboard-setting user-notification">
<div class="dropdown">
<a class="dropdown-toggle no-arrow" href="javascript:;" data-toggle="right-sidebar">
<i class="dw dw-settings2"></i>
</a>
</div>
</div>
@livewire('admin.top-user-info')
</div>
</div>
<div class="right-sidebar">
<div class="sidebar-title">
<h3 class="weight-600 font-16 text-blue">
Layout Einstellungen
<span class="btn-block font-weight-400 font-12">User Interface Einstellungen</span>
</h3>
<div class="close-sidebar" data-toggle="right-sidebar-close">
<i class="icon-copy ion-close-round"></i>
</div>
</div>
<div class="right-sidebar-body customscroll">
<div class="right-sidebar-body-content">
<h4 class="weight-600 font-18 pb-10">Header Hintergrund</h4>
<div class="sidebar-btn-group pb-30 mb-10">
<a href="javascript:void(0);" class="btn btn-outline-primary header-white active">White</a>
<a href="javascript:void(0);" class="btn btn-outline-primary header-dark">Dark</a>
</div>
<h4 class="weight-600 font-18 pb-10">Sidebar Hintergrund</h4>
<div class="sidebar-btn-group pb-30 mb-10">
<a href="javascript:void(0);" class="btn btn-outline-primary sidebar-light active">White</a>
<a href="javascript:void(0);" class="btn btn-outline-primary sidebar-dark">Dark</a>
</div>
<h4 class="weight-600 font-18 pb-10">Menu Dropdown Icon</h4>
<div class="sidebar-radio-group pb-10 mb-10">
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" id="sidebaricon-1" name="menu-dropdown-icon" class="custom-control-input"
value="icon-style-1" checked="" />
<label class="custom-control-label" for="sidebaricon-1"><i class="fa fa-angle-down"></i></label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" id="sidebaricon-2" name="menu-dropdown-icon" class="custom-control-input"
value="icon-style-2" />
<label class="custom-control-label" for="sidebaricon-2"><i class="ion-plus-round"></i></label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" id="sidebaricon-3" name="menu-dropdown-icon" class="custom-control-input"
value="icon-style-3" />
<label class="custom-control-label" for="sidebaricon-3"><i
class="fa fa-angle-double-right"></i></label>
</div>
</div>
<h4 class="weight-600 font-18 pb-10">Menu List Icon</h4>
<div class="sidebar-radio-group pb-30 mb-10">
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" id="sidebariconlist-1" name="menu-list-icon" class="custom-control-input"
value="icon-list-style-1" checked="" />
<label class="custom-control-label" for="sidebariconlist-1"><i
class="ion-minus-round"></i></label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" id="sidebariconlist-2" name="menu-list-icon"
class="custom-control-input" value="icon-list-style-2" />
<label class="custom-control-label" for="sidebariconlist-2"><i class="fa fa-circle-o"
aria-hidden="true"></i></label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" id="sidebariconlist-3" name="menu-list-icon"
class="custom-control-input" value="icon-list-style-3" />
<label class="custom-control-label" for="sidebariconlist-3"><i
class="dw dw-check"></i></label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" id="sidebariconlist-4" name="menu-list-icon"
class="custom-control-input" value="icon-list-style-4" checked="" />
<label class="custom-control-label" for="sidebariconlist-4"><i
class="icon-copy dw dw-next-2"></i></label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" id="sidebariconlist-5" name="menu-list-icon"
class="custom-control-input" value="icon-list-style-5" />
<label class="custom-control-label" for="sidebariconlist-5"><i
class="dw dw-fast-forward-1"></i></label>
</div>
<div class="custom-control custom-radio custom-control-inline">
<input type="radio" id="sidebariconlist-6" name="menu-list-icon"
class="custom-control-input" value="icon-list-style-6" />
<label class="custom-control-label" for="sidebariconlist-6"><i
class="dw dw-next"></i></label>
</div>
</div>
<div class="reset-options pt-30 text-center">
<button class="btn btn-danger" id="reset-settings">
Einstellungen zurücksetzen
</button>
</div>
</div>
</div>
</div>
<div class="left-side-bar">
<div class="brand-logo">
<a href="/">
<img src="/images/site/{{ isset(settings()->site_logo) ? settings()->site_logo : '' }}"
alt="brand-logo" class="dark-logo" />
<img src="/images/site/{{ isset(settings()->site_logo) ? settings()->site_logo : '' }}"
alt="brand-logo" class="light-logo" />
</a>
<div class="close-sidebar" data-toggle="left-sidebar-close">
<i class="ion-close-round"></i>
</div>
</div>
<div class="menu-block customscroll">
<div class="sidebar-menu">
<ul id="accordion-menu">
<li>
<a href="{{ route('admin.dashboard') }}"
class="dropdown-toggle no-arrow {{ Route::is('admin.dashboard') ? 'active' : '' }}">
<span class="micon bi bi-house"></span><span class="mtext">Home</span>
</a>
</li>
@if (auth()->user()->type == 'superAdmin')
<li>
<a href="{{ route('admin.categories') }}"
class="dropdown-toggle no-arrow {{ Route::is('admin.categories') ? 'active' : '' }}">
<span class="micon fa fa-th-list"></span><span class="mtext">Kategorien</span>
</a>
</li>
@endif
<li class="dropdown">
<a href="javascript:;"
class="dropdown-toggle {{ Route::is('admin.add_posts') || Route::is('admin.posts') || Route::is('admin.edit_post') ? 'active' : '' }}">
<span class="micon fa fa-newspaper-o"></span><span class="mtext"> Posts </span>
</a>
<ul class="submenu">
<li><a href="{{ route('admin.add_post') }}"
class="{{ Route::is('admin.add_post') ? 'active' : '' }}">Neuen
Post</a></li>
<li><a href="{{ route('admin.posts') }}"
class="{{ Route::is('admin.posts') ? 'active' : '' }}">Posts</a>
</li>
</ul>
</li>
<li>
<div class="dropdown-divider"></div>
</li>
<li>
<div class="sidebar-small-cap">Einstellungen</div>
</li>
<li>
<a href="{{ route('admin.profile') }}"
class="dropdown-toggle no-arrow {{ Route::is('admin.profile') ? 'active' : '' }}">
<span class="micon fa fa-user-circle"></span>
<span class="mtext">Profile</span>
</a>
</li>
@if (auth()->user()->type == 'superAdmin')
<li>
<a href="{{ route('admin.settings') }}"
class="dropdown-toggle no-arrow {{ Route::is('admin.settings') ? 'active' : '' }}">
<span class="micon fa fa-cogs"></span>
<span class="mtext">Allgemein</span>
</a>
</li>
<li>
<a href="{{ route('admin.slider') }}"
class="dropdown-toggle no-arrow {{ Route::is('admin.slider') ? 'active' : '' }}">
<span class="micon dw dw-image"></span>
<span class="mtext">Manage Slider</span>
</a>
</li>
@endif
</ul>
</div>
</div>
</div>
<div class="mobile-menu-overlay"></div>
<div class="main-container">
<div class="pd-ltr-20 xs-pd-20-10">
<div class="min-height-200px">
<div class="">
@yield('content')
</div>
</div>
<div class="footer-wrap pd-20 mb-20 card-box">
DeskApp - Bootstrap 4 Admin Template By
<a href="https://github.com/dropways" target="_blank">Ankit Hingarajiya</a>
</div>
</div>
</div>
<!-- js -->
<script src="{{ asset('/back/vendors/scripts/core.js') }}"></script>
<script src="{{ asset('/back/vendors/scripts/script.min.js') }}"></script>
<script src="{{ asset('/back/vendors/scripts/process.js') }}"></script>
<script src="{{ asset('/back/vendors/scripts/layout-settings.js') }}"></script>
<script src="{{ asset('/extra-assets/jquery-ui/jquery-ui.min.js') }}"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/toastr.js/latest/toastr.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/sweetalert2@11"></script>
<script>
toastr.options = {
"closeButton": true,
"newestOnTop": false,
"progressBar": true,
"positionClass": "toast-bottom-right",
"preventDuplicates": false,
"onclick": null,
"showDuration": "300",
"hideDuration": "1000",
"timeOut": "5000",
"extendedTimeOut": "1000",
"showEasing": "swing",
"hideEasing": "linear",
"showMethod": "fadeIn",
"hideMethod": "fadeOut"
};
window.addEventListener("showToastr", function(event) {
const type = event.detail[0].type; // z.B. 'success', 'error', 'info', 'warning'
const message = event.detail[0].message; // Text der Meldung
const Toast = Swal.mixin({
toast: true,
position: "bottom-end",
showConfirmButton: false,
timer: 3000,
timerProgressBar: true,
didOpen: (toast) => {
toast.onmouseenter = Swal.stopTimer;
toast.onmouseleave = Swal.resumeTimer;
}
});
Toast.fire({
icon: type,
title: message
});
// Dynamischer Aufruf: toastr.success(message), toastr.error(message) etc.
/* if (typeof toastr[type] === 'function') {
toastr[type](message);
} else {
// Fallback, falls ein unbekannter Typ kommt
toastr.info(message);
} */
});
</script>
@kropifyScripts
@stack('scripts')
</body>
</html>

View File

@@ -0,0 +1,269 @@
@extends('back.layout.pages-layout')
@section('pageTitle', isset($pageTitle) ? $pageTitle : 'Page Title here')
@section('content')
<div class="page-header">
<div class="row">
<div class="col-md-6 col-sm-12">
<div class="title">
<h4>Post hinzufügen</h4>
</div>
<nav aria-label="breadcrumb" role="navigation">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="{{ route('admin.dashboard') }}">Home</a>
</li>
<li class="breadcrumb-item active" aria-current="page">
Post erstellen
</li>
</ol>
</nav>
</div>
<div class="col-md-6 col-sm-12 text-right">
<a href="{{ route('admin.posts') }}" class="btn btn-primary">View all posts</a>
</div>
</div>
</div>
<form action="{{ route('admin.create_post') }}" method="POST" autocomplete="off" enctype="multipart/form-data"
id="addPostForm">
@csrf
<div class="row">
<div class="col-md-9">
<div class="card card-box mb-2">
<div class="card-body">
<div class="form-group">
<label for=""><b>Title:</b></label>
<input type="text" class="form-control" name="title" placeholder="Titel angeben" />
<span class="text-danger error-text title_error"></span>
</div>
<div class="form-group">
<label for=""><b>Content:</b></label>
<textarea name="content" id="content" cols="30" rows="10" class="ckeditor form-control"
placeholder="Content eingeben"></textarea>
<span class="text-danger error-text content_error"></span>
</div>
<div class="form-group">
<label for=""><b>JSON FAQ:</b></label>
<textarea name="structured_data" id="structured_data" cols="30" rows="10" class="form-control"
placeholder="JSON FAQ eingeben"></textarea>
</div>
</div>
</div>
<div class="card card-box mb-2">
<div class="card-header weight-500">SEO</div>
<div class="card-body">
<div class="form-group">
<label for=""><b>Post Meta Keywords:</b>: <small>(Separated by Komma)</small></label>
<input type="text" class="form-control" name="meta_keywords"
placeholder="Meta Keywords angeben" />
</div>
<div class="form-group">
<label for=""><b>Post Meta Beschreibung:</b></label>
<textarea name="meta_description" id="" cols="30" rows="10" class="form-control"
placeholder="Meta Beschreibung eingeben"></textarea>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card card-box mb-2">
<div class="card-body">
<div class="form-group">
<label for=""><b>Post Kategorie:</b></label>
<select name="category" id="" class="custom-select form-control">
<option value="">Auswählen..</option>
{!! $categories_html !!}
</select>
<span class="text-danger error-text category_error"></span>
</div>
<div class="form-group">
<label for=""><b>Post Featured Foto:</b></label>
<input type="file" class="form-control-file form-control" name="featured_image"
id="featured_image_input" height="auto" accept="image/png,image/jpeg, image/jpg" />
<span class="text-danger error-text featured_image_error"></span>
</div>
<div class="d-block mb-3" style="max-width:250px;">
<img src="" alt="featured_image" class="img-thumbnail" id="featured_image_preview" />
</div>
<div class="form-group">
<label for=""><b>Tags:</b></label>
<input type="text" class="form-control" name="tags" data-role="tagsinput" />
</div>
<hr>
<div class="form-group">
<label for=""><b>Sichtbar:</b></label>
<div class="custom-control custom-radio mb-5">
<input type="radio" name="visibility" id="customRadio1" class="custom-control-input"
value="1" checked />
<label for="customRadio1" class="custom-control-label">Öffentlich</label>
</div>
<div class="custom-control custom-radio mb-5">
<input type="radio" name="visibility" id="customRadio2" class="custom-control-input"
value="0" />
<label for="customRadio2" class="custom-control-label">Privat</label>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="mb-3">
<button type="submit" class="btn btn-primary">Post erstellen</button>
</div>
</form>
@endsection
@push('stylesheets')
<style>
/* Schlichter Container */
.bootstrap-tagsinput {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 4px;
/* Abstand zwischen Tags/Eingabe */
width: 100%;
min-height: 40px;
padding: 6px 8px;
background-color: #ffffff;
border: 1px solid #d1d5db;
border-radius: 6px;
/* keine Ei-Form mehr */
box-shadow: none;
font-size: 14px;
line-height: 1.4;
cursor: text;
}
/* Eingabefeld */
.bootstrap-tagsinput input {
border: none;
box-shadow: none;
outline: none;
background: transparent;
padding: 2px 0;
margin: 0;
min-width: 80px;
max-width: 100%;
font-size: 14px;
color: #111827;
}
/* Placeholder */
.bootstrap-tagsinput.form-control input::-moz-placeholder {
color: #9ca3af;
opacity: 1;
}
.bootstrap-tagsinput.form-control input:-ms-input-placeholder {
color: #9ca3af;
}
.bootstrap-tagsinput.form-control input::-webkit-input-placeholder {
color: #9ca3af;
}
/* Tags */
.bootstrap-tagsinput .tag {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 2px 10px;
border-radius: 999px;
background: #2563eb;
color: #ffffff;
font-size: 13px;
font-weight: 500;
white-space: nowrap;
margin: 0;
/* Abstand kommt über gap */
}
/* Remove-Icon */
.bootstrap-tagsinput .tag [data-role="remove"] {
display: inline-flex;
align-items: center;
justify-content: center;
width: 14px;
height: 14px;
border-radius: 999px;
cursor: pointer;
font-size: 11px;
line-height: 1;
background-color: rgba(15, 23, 42, 0.25);
margin-left: 0;
}
.bootstrap-tagsinput .tag [data-role="remove"]:after {
content: "×";
}
/* leichtes Hover nur auf dem Icon */
.bootstrap-tagsinput .tag [data-role="remove"]:hover {
background-color: rgba(15, 23, 42, 0.4);
}
</style>
@endpush
@push('scripts')
<script src="/back/src/plugins/bootstrap-tagsinput/bootstrap-tagsinput.js"></script>
<script src="/ckeditor/ckeditor.js"></script>
// Image Preview
<script>
document.getElementById("featured_image_input").addEventListener("change", function(e) {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = function(event) {
document.getElementById("featured_image_preview").src = event.target.result;
};
reader.readAsDataURL(file);
});
</script>
// Create Post
<script>
$('#addPostForm').on('submit', function(e) {
e.preventDefault();
var form = this;
var content = CKEDITOR.instances.content.getData();
var formdata = new FormData(form);
formdata.append('content', content);
$.ajax({
url: $(form).attr('action'),
method: $(form).attr('method'),
data: formdata,
processData: false,
dataType: 'json',
contentType: false,
beforeSend: function() {
$(form).find('span.error-text').text('');
},
success: function(data) {
if (data.status == 1) {
$(form)[0].reset();
CKEDITOR.instances.content.setData('');
$('img#featured_image_preview').attr('src', '');
$('input[name="tags"]').tagsinput('removeAll');
toastr.success(data.message);
} else {
toastr.error(data.message);
}
},
error: function(jqXHR, textStatus, errorThrown) {
console.log('AJAX error', textStatus, errorThrown);
console.log('Response:', jqXHR);
if (jqXHR.responseJSON && jqXHR.responseJSON.errors) {
$.each(jqXHR.responseJSON.errors, function(prefix, val) {
$(form).find('span.' + prefix + '_error').text(val[0]);
});
} else {
toastr.error('Es ist ein unerwarteter Fehler aufgetreten.');
}
}
});
});
</script>
@endpush

View File

@@ -0,0 +1,41 @@
@extends('back.layout.auth-layout')
@section('pageTitle', isset($pageTitle) ? $pageTitle : 'Page Title here')
@section('content')
<div class="login-box bg-white box-shadow border-radius-10">
<div class="login-title">
<h2 class="text-center text-primary">Passwort vergessen</h2>
</div>
<form action="{{ route('admin.send_password_reset_link') }}" method="POST">
<x-form-alerts></x-form-alerts>
@csrf
<div class="input-group custom mb-1">
<input type="text" class="form-control form-control-lg" placeholder="Email" name="email"
value="{{ old('email') }}" />
<div class="input-group-append custom">
<span class="input-group-text"><i class="fa fa-envelope-o" aria-hidden="true"></i></span>
</div>
</div>
@error('email')
<span class="text-danger ml-1">{{ $message }}</span>
@enderror
<div class="row align-items-center mb-1 mt-2">
<div class="col-5">
<div class="input-group mb-0">
<input class="btn btn-primary btn-lg btn-block" type="submit" value="Absenden">
</div>
</div>
<div class="col-2">
<div class="font-16 weight-600 text-center" data-color="#707373">
ODER
</div>
</div>
<div class="col-5">
<div class="input-group mb-0">
<a class="btn btn-outline-primary btn-lg btn-block" href="{{ route('admin.login') }}">Einloggen</a>
</div>
</div>
</div>
</form>
</div>
@endsection

View File

@@ -0,0 +1,54 @@
@extends('back.layout.auth-layout')
@section('pageTitle', isset($pageTitle) ? $pageTitle : 'Page Title here')
@section('content')
<div class="login-box bg-white box-shadow border-radius-10">
<div class="login-title">
<h2 class="text-center text-primary">Login</h2>
</div>
<form action="{{ route('admin.login_handler') }}" method="POST">
<x-form-alerts></x-form-alerts>
@csrf
<div class="input-group custom mb-1">
<input type="text" class="form-control form-control-lg" placeholder="Benutzername / Email" name="login_id"
value="{{ old('login_id') }}" />
<div class="input-group-append custom">
<span class="input-group-text"><i class="icon-copy dw dw-user1"></i></span>
</div>
</div>
@error('login_id')
<span class="text-danger ml-1">{{ $message }}</span>
@enderror
<div class="input-group custom mb-1 mt-2">
<input type="password" class="form-control form-control-lg" placeholder="**********" name="password" />
<div class="input-group-append custom">
<span class="input-group-text"><i class="dw dw-padlock1"></i></span>
</div>
</div>
@error('password')
<span class="text-danger ml-1">{{ $message }}</span>
@enderror
<div class="row pb-30">
<div class="col-6">
<div class="custom-control custom-checkbox">
<input type="checkbox" class="custom-control-input" id="customCheck1" />
<label class="custom-control-label" for="customCheck1">Eingeloggt bleiben</label>
</div>
</div>
<div class="col-6">
<div class="forgot-password">
<a href="{{ route('admin.forgot') }}">Password vergessen</a>
</div>
</div>
</div>
<div class="row">
<div class="col-sm-12">
<div class="input-group mb-0">
<input class="btn btn-primary btn-lg btn-block" type="submit" value="Einloggen">
</div>
</div>
</div>
</form>
</div>
@endsection

View File

@@ -0,0 +1,41 @@
@extends('back.layout.auth-layout')
@section('pageTitle', isset($pageTitle) ? $pageTitle : 'Page Title here')
@section('content')
<div class="login-box bg-white box-shadow border-radius-10">
<div class="login-title">
<h2 class="text-center text-primary">Passwort zurücksetzen</h2>
</div>
<h6 class="mb-20">Geben Sie Ihr neues Passwort ein, bestätigen Sie es und senden Sie es ab.</h6>
<form method="POST" action="{{ route('admin.reset_password_handler', ['token' => $token]) }}">
<x-form-alerts></x-form-alerts>
@csrf
<div class="input-group custom mb-1">
<input type="text" class="form-control form-control-lg" placeholder="Neues Passwort" name="new_password" />
<div class="input-group-append custom">
<span class="input-group-text"><i class="dw dw-padlock1"></i></span>
</div>
</div>
@error('new_password')
<span class="text-danger ml-1">{{ $message }}</span>
@enderror
<div class="input-group custom mb-1 mt-2">
<input type="text" class="form-control form-control-lg" placeholder="Neues Passwort bestätigen"
name="new_password_confirm" />
<div class="input-group-append custom">
<span class="input-group-text"><i class="dw dw-padlock1"></i></span>
</div>
</div>
@error('new_password_confirm')
<span class="text-danger ml-1">{{ $message }}</span>
@enderror
<div class="row align-items-center">
<div class="col-5">
<div class="input-group mb-0">
<input class="btn btn-primary btn-lg btn-block" type="submit" value="Absenden">
</div>
</div>
</div>
</form>
</div>
@endsection

View File

@@ -0,0 +1,94 @@
@extends('back.layout.pages-layout')
@section('pageTitle', isset($pageTitle) ? $pageTitle : 'Page Title here')
@section('content')
@livewire('admin.categories')
@endsection
@push('scripts')
<script>
window.addEventListener("showParentCategoryModalForm", function() {
$('#pcategory_modal').modal("show");
});
window.addEventListener("hideParentCategoryModalForm", function() {
$('#pcategory_modal').modal("hide");
});
window.addEventListener("showCategoryModalForm", function() {
$('#category_modal').modal("show");
});
window.addEventListener("hideCategoryModalForm", function() {
$('#category_modal').modal("hide");
});
$('table tbody#sortable_parent_categories').sortable({
cursor: "move",
update: function(event, ui) {
$(this).children().each(function(index) {
if ($(this).attr('data-ordering') != (index + 1)) {
$(this).attr('data-ordering', (index + 1)).addClass('updated');
}
});
var positions = [];
$('.updated').each(function() {
positions.push([$(this).attr('data-index'), $(this).attr('data-ordering')]);
$(this).removeClass('updated');
});
Livewire.dispatch('updateParentCategoryOrdering', [positions]);
}
});
$('table tbody#sortable_categories').sortable({
cursor: "move",
update: function(event, ui) {
$(this).children().each(function(index) {
if ($(this).attr('data-ordering') != (index + 1)) {
$(this).attr('data-ordering', (index + 1)).addClass('updated');
}
});
var positions = [];
$('.updated').each(function() {
positions.push([$(this).attr('data-index'), $(this).attr('data-ordering')]);
$(this).removeClass('updated');
});
Livewire.dispatch('updateCategoryOrdering', [positions]);
}
});
window.addEventListener('deleteParentCategory', function(event) {
var id = event.detail[0].id;
Swal.fire({
title: "Bist du dir sicher?",
text: "Das du die Haupt Kategorie löschen möchtest!",
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#3085d6",
cancelButtonColor: "#d33",
confirmButtonText: "Ja, löschen!"
}).then((result) => {
if (result.isConfirmed) {
Livewire.dispatch('deleteParentCategoryAction', [id]);
}
});
});
window.addEventListener('deleteCategory', function(event) {
var id = event.detail[0].id;
Swal.fire({
title: "Bist du dir sicher?",
text: "Das du die Kategorie löschen möchtest!",
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#3085d6",
cancelButtonColor: "#d33",
confirmButtonText: "Ja, löschen!"
}).then((result) => {
if (result.isConfirmed) {
Livewire.dispatch('deleteCategoryAction', [id]);
}
});
});
</script>
@endpush

View File

@@ -0,0 +1,342 @@
@extends('back.layout.pages-layout')
@section('pageTitle', isset($pageTitle) ? $pageTitle : 'Page Title here')
@section('content')
<div class="container-fluid py-4">
{{-- Überschrift, falls du sie brauchst --}}
<div class="mb-4">
<h1 class="h3 mb-0">{{ $pageTitle ?? 'Dashboard' }}</h1>
</div>
{{-- KPI-Karten: Tags / Posts / Subscriber --}}
<div class="row g-3 mb-4">
{{-- Tags (deine Zähl-Logik) --}}
<div class="col-12 col-md-4">
<div class="card h-100 shadow-sm">
<div class="card-body">
<div class="d-flex justify-content-between align-items-start mb-2">
<small class="text-muted text-uppercase fw-semibold">Tags</small>
<span class="badge bg-primary-subtle text-primary border border-primary-subtle">
Stückanzahl
</span>
</div>
<h3 class="fw-semibold mb-1">
{{ $tagsCount ?? 0 }}
</h3>
<small class="text-muted">Gesamtzahl (laut Feld <code>tags</code>)</small>
</div>
</div>
</div>
{{-- Posts --}}
<div class="col-12 col-md-4">
<div class="card h-100 shadow-sm">
<div class="card-body">
<div class="d-flex justify-content-between align-items-start mb-2">
<small class="text-muted text-uppercase fw-semibold">Posts</small>
<span class="badge bg-success-subtle text-success border border-success-subtle">
Stückanzahl
</span>
</div>
<h3 class="fw-semibold mb-1">
{{ $postsCount ?? 0 }}
</h3>
<small class="text-muted">Gesamtzahl der Posts</small>
</div>
</div>
</div>
{{-- Subscriber --}}
<div class="col-12 col-md-4">
<div class="card h-100 shadow-sm">
<div class="card-body">
<div class="d-flex justify-content-between align-items-start mb-2">
<small class="text-muted text-uppercase fw-semibold">Subscriber</small>
<span class="badge bg-info-subtle text-info border border-info-subtle">
Stückanzahl
</span>
</div>
<h3 class="fw-semibold mb-1">
{{ $subscribersCount ?? 0 }}
</h3>
<small class="text-muted">Gesamtzahl der Abonnenten</small>
</div>
</div>
</div>
</div>
{{-- SEO / Content-Checks: KPIs --}}
<div class="row g-3 mb-4">
{{-- Posts ohne Meta-Beschreibung --}}
<div class="col-12 col-md-4">
<div class="card h-100 shadow-sm border-warning-subtle">
<div class="card-body">
<div class="d-flex justify-content-between align-items-start mb-2">
<small class="text-muted text-uppercase fw-semibold">
Posts ohne Meta-Beschreibung
</small>
<span
class="badge
{{ ($postsWithoutMetaDescriptionCount ?? 0) > 0
? 'bg-warning-subtle text-warning border border-warning-subtle'
: 'bg-success-subtle text-success border border-success-subtle' }}">
{{ ($postsWithoutMetaDescriptionCount ?? 0) > 0 ? 'Optimieren' : 'OK' }}
</span>
</div>
<h3 class="fw-semibold mb-1">
{{ $postsWithoutMetaDescriptionCount ?? 0 }}
</h3>
<small class="text-muted">Anzahl Beiträge ohne Meta-Description</small>
</div>
</div>
</div>
{{-- Posts ohne Meta-Keywords --}}
<div class="col-12 col-md-4">
<div class="card h-100 shadow-sm border-warning-subtle">
<div class="card-body">
<div class="d-flex justify-content-between align-items-start mb-2">
<small class="text-muted text-uppercase fw-semibold">
Posts ohne Meta-Keywords
</small>
<span
class="badge
{{ ($postsWithoutMetaKeywordsCount ?? 0) > 0
? 'bg-warning-subtle text-warning border border-warning-subtle'
: 'bg-success-subtle text-success border border-success-subtle' }}">
{{ ($postsWithoutMetaKeywordsCount ?? 0) > 0 ? 'Optimieren' : 'OK' }}
</span>
</div>
<h3 class="fw-semibold mb-1">
{{ $postsWithoutMetaKeywordsCount ?? 0 }}
</h3>
<small class="text-muted">Anzahl Beiträge ohne Meta-Keywords</small>
</div>
</div>
</div>
{{-- Posts ohne Tags --}}
<div class="col-12 col-md-4">
<div class="card h-100 shadow-sm border-warning-subtle">
<div class="card-body">
<div class="d-flex justify-content-between align-items-start mb-2">
<small class="text-muted text-uppercase fw-semibold">
Posts ohne Tags
</small>
<span
class="badge
{{ ($postsWithoutTagsCount ?? 0) > 0
? 'bg-warning-subtle text-warning border border-warning-subtle'
: 'bg-success-subtle text-success border border-success-subtle' }}">
{{ ($postsWithoutTagsCount ?? 0) > 0 ? 'Optimieren' : 'OK' }}
</span>
</div>
<h3 class="fw-semibold mb-1">
{{ $postsWithoutTagsCount ?? 0 }}
</h3>
<small class="text-muted">Beiträge ohne Eintrag im Feld <code>tags</code></small>
</div>
</div>
</div>
</div>
{{-- Letzte 5 Beiträge --}}
<div class="card shadow-sm mb-4">
<div class="card-header d-flex justify-content-between align-items-center">
<h6 class="card-title mb-0">Letzte 5 Beiträge</h6>
@if (Route::has('posts.index'))
<a href="{{ route('posts.index') }}" class="small text-decoration-none">
Alle anzeigen
</a>
@endif
</div>
<div class="table-responsive">
<table class="table table-sm align-middle mb-0">
<thead class="table-light">
<tr>
<th>Titel</th>
<th>Status</th>
<th>SEO</th>
<th>Erstellt am</th>
<th class="text-end">Aktionen</th>
</tr>
</thead>
<tbody>
@forelse($latestPosts as $post)
@php
$needsOptimization =
empty($post->meta_keywords) || empty($post->tags) || empty($post->meta_description); // ggf. Feldname anpassen (z.B. meta_title)
@endphp
<tr>
<td>
@if (Route::has('posts.edit'))
<a href="{{ route('posts.edit', $post) }}" class="text-decoration-none">
{{ $post->title }}
</a>
@else
{{ $post->title }}
@endif
</td>
<td>
@if ($post->visibility == 1)
<span class="badge bg-success-subtle text-success border border-success-subtle">
Veröffentlicht
</span>
@else
<span
class="badge bg-secondary-subtle text-secondary border border-secondary-subtle">
Entwurf
</span>
@endif
</td>
<td>
@if ($needsOptimization)
<span class="badge bg-warning-subtle text-warning border border-warning-subtle">
Optimieren
</span>
@else
<span class="badge bg-success-subtle text-success border border-success-subtle">
OK
</span>
@endif
</td>
<td>
<small class="text-muted">
{{ $post->created_at->format('d.m.Y H:i') }}
</small>
</td>
<td class="text-end">
{{-- Anschauen --}}
@if (Route::has('read_post'))
<a href="{{ route('read_post', $post->slug) }}"
class="btn btn-sm btn-outline-secondary">
Anschauen
</a>
@endif
{{-- Bearbeiten --}}
@if (Route::has('admin.edit_post'))
<a href="{{ route('admin.edit_post', $post) }}"
class="btn btn-sm btn-primary ms-1">
Bearbeiten
</a>
@endif
</td>
</tr>
@empty
<tr>
<td colspan="3" class="text-center text-muted py-4">
Keine Beiträge vorhanden.
</td>
</tr>
@endforelse
</tbody>
</table>
</div>
</div>
{{-- Detail-Listen: Posts ohne Meta / Tags --}}
<div class="card shadow-sm">
<div class="card-header">
<h6 class="card-title mb-0">Beiträge mit Optimierungsbedarf</h6>
</div>
<div class="card-body">
<div class="row g-3">
{{-- Ohne Meta-Beschreibung --}}
<div class="col-12 col-md-4">
<h6 class="small text-uppercase text-muted mb-2">
Ohne Meta-Beschreibung
</h6>
<ul class="list-unstyled mb-0 small">
@forelse($postsWithoutMetaDescription as $post)
<li class="mb-2">
@if (Route::has('posts.edit'))
<a href="{{ route('posts.edit', $post) }}" class="text-decoration-none">
{{ $post->title }}
</a>
@else
{{ $post->title }}
@endif
<br>
<span class="text-muted">
{{ $post->created_at->format('d.m.Y') }}
</span>
</li>
@empty
<li class="text-muted">Alles erledigt.</li>
@endforelse
</ul>
</div>
{{-- Ohne Meta-Keywords --}}
<div class="col-12 col-md-4">
<h6 class="small text-uppercase text-muted mb-2">
Ohne Meta-Keywords
</h6>
<ul class="list-unstyled mb-0 small">
@forelse($postsWithoutMetaKeywords as $post)
<li class="mb-2">
@if (Route::has('posts.edit'))
<a href="{{ route('posts.edit', $post) }}" class="text-decoration-none">
{{ $post->title }}
</a>
@else
{{ $post->title }}
@endif
<br>
<span class="text-muted">
{{ $post->created_at->format('d.m.Y') }}
</span>
</li>
@empty
<li class="text-muted">Alles erledigt.</li>
@endforelse
</ul>
</div>
{{-- Ohne Tags --}}
<div class="col-12 col-md-4">
<h6 class="small text-uppercase text-muted mb-2">
Ohne Tags
</h6>
<ul class="list-unstyled mb-0 small">
@forelse($postsWithoutTags as $post)
<li class="mb-2">
@if (Route::has('posts.edit'))
<a href="{{ route('posts.edit', $post) }}" class="text-decoration-none">
{{ $post->title }}
</a>
@else
{{ $post->title }}
@endif
<br>
<span class="text-muted">
{{ $post->created_at->format('d.m.Y') }}
</span>
</li>
@empty
<li class="text-muted">Alles erledigt.</li>
@endforelse
</ul>
</div>
</div>
</div>
</div>
</div>
@endsection

View File

@@ -0,0 +1,268 @@
@extends('back.layout.pages-layout')
@section('pageTitle', isset($pageTitle) ? $pageTitle : 'Page Title here')
@section('content')
<div class="page-header">
<div class="row">
<div class="col-md-6 col-sm-12">
<div class="title">
<h4>Post bearbeiten</h4>
</div>
<nav aria-label="breadcrumb" role="navigation">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="{{ route('admin.dashboard') }}">Home</a>
</li>
<li class="breadcrumb-item active" aria-current="page">
Post bearbeiten
</li>
</ol>
</nav>
</div>
<div class="col-md-6 col-sm-12 text-right">
<a href="{{ route('admin.posts') }}" class="btn btn-primary">View all posts</a>
</div>
</div>
</div>
<form action="{{ route('admin.update_post', ['post_id' => $post->id]) }}" method="POST" autocomplete="off"
enctype="multipart/form-data" id="updatePostForm">
@csrf
<div class="row">
<div class="col-md-9">
<div class="card card-box mb-2">
<div class="card-body">
<div class="form-group">
<label for=""><b>Title:</b></label>
<input type="text" class="form-control" name="title" placeholder="Titel angeben"
value="{{ $post->title }}" />
<span class="text-danger error-text title_error"></span>
</div>
<div class="form-group">
<label for=""><b>Content:</b></label>
<textarea name="content" id="content" cols="30" rows="10" class="ckeditor form-control"
placeholder="Content eingeben">{!! $post->content !!}</textarea>
<span class="text-danger error-text content_error"></span>
</div>
<div class="form-group">
<label for=""><b>JSON FAQ:</b></label>
<textarea name="structured_data" id="structured_data" cols="30" rows="10" class="form-control"
placeholder="JSON FAQ eingeben">{!! $post->structured_data !!}</textarea>
</div>
</div>
</div>
<div class="card card-box mb-2">
<div class="card-header weight-500">SEO</div>
<div class="card-body">
<div class="form-group">
<label for=""><b>Post Meta Keywords:</b>: <small>(Separated by Komma)</small></label>
<input type="text" class="form-control" name="meta_keywords"
value="{{ $post->meta_keywords }}" placeholder="Meta Keywords angeben" />
</div>
<div class="form-group">
<label for=""><b>Post Meta Beschreibung:</b></label>
<textarea name="meta_description" id="" cols="30" rows="10" class="form-control"
placeholder="Meta Beschreibung eingeben">{{ $post->meta_description }}</textarea>
</div>
</div>
</div>
</div>
<div class="col-md-3">
<div class="card card-box mb-2">
<div class="card-body">
<div class="form-group">
<label for=""><b>Post Kategorie:</b></label>
<select name="category" id="" class="custom-select form-control">
{!! $categories_html !!}
</select>
<span class="text-danger error-text category_error"></span>
</div>
<div class="form-group">
<label for=""><b>Post Featured Foto:</b></label>
<input type="file" class="form-control-file form-control" name="featured_image"
id="featured_image_input" height="auto" accept="image/png,image/jpeg, image/jpg" />
<span class="text-danger error-text featured_image_error"></span>
</div>
<div class="d-block mb-3" style="max-width:250px;">
<img src="/images/posts/resized/resized_{{ $post->featured_image }}" alt="featured_image"
class="img-thumbnail" id="featured_image_preview" />
</div>
<div class="form-group">
<label for=""><b>Tags:</b></label>
<input type="text" class="form-control" name="tags" data-role="tagsinput"
value="{{ $post->tags }}" />
</div>
<hr>
<div class="form-group">
<label for=""><b>Sichtbar:</b></label>
<div class="custom-control custom-radio mb-5">
<input type="radio" name="visibility" id="customRadio1" class="custom-control-input"
value="1" {{ $post->visibility == 1 ? 'checked' : '' }} />
<label for="customRadio1" class="custom-control-label">Öffentlich</label>
</div>
<div class="custom-control custom-radio mb-5">
<input type="radio" name="visibility" id="customRadio2" class="custom-control-input"
value="0" {{ $post->visibility == 0 ? 'checked' : '' }} />
<label for="customRadio2" class="custom-control-label">Privat</label>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="mb-3">
<button type="submit" class="btn btn-primary">Post bearbeiten</button>
</div>
</form>
@endsection
@push('stylesheets')
<style>
/* Schlichter Container */
.bootstrap-tagsinput {
display: flex;
flex-wrap: wrap;
align-items: center;
gap: 4px;
/* Abstand zwischen Tags/Eingabe */
width: 100%;
min-height: 40px;
padding: 6px 8px;
background-color: #ffffff;
border: 1px solid #d1d5db;
border-radius: 6px;
/* keine Ei-Form mehr */
box-shadow: none;
font-size: 14px;
line-height: 1.4;
cursor: text;
}
/* Eingabefeld */
.bootstrap-tagsinput input {
border: none;
box-shadow: none;
outline: none;
background: transparent;
padding: 2px 0;
margin: 0;
min-width: 80px;
max-width: 100%;
font-size: 14px;
color: #111827;
}
/* Placeholder */
.bootstrap-tagsinput.form-control input::-moz-placeholder {
color: #9ca3af;
opacity: 1;
}
.bootstrap-tagsinput.form-control input:-ms-input-placeholder {
color: #9ca3af;
}
.bootstrap-tagsinput.form-control input::-webkit-input-placeholder {
color: #9ca3af;
}
/* Tags */
.bootstrap-tagsinput .tag {
display: inline-flex;
align-items: center;
gap: 4px;
padding: 2px 10px;
border-radius: 999px;
background: #2563eb;
color: #ffffff;
font-size: 13px;
font-weight: 500;
white-space: nowrap;
margin: 0;
/* Abstand kommt über gap */
}
/* Remove-Icon */
.bootstrap-tagsinput .tag [data-role="remove"] {
display: inline-flex;
align-items: center;
justify-content: center;
width: 14px;
height: 14px;
border-radius: 999px;
cursor: pointer;
font-size: 11px;
line-height: 1;
background-color: rgba(15, 23, 42, 0.25);
margin-left: 0;
}
.bootstrap-tagsinput .tag [data-role="remove"]:after {
content: "×";
}
/* leichtes Hover nur auf dem Icon */
.bootstrap-tagsinput .tag [data-role="remove"]:hover {
background-color: rgba(15, 23, 42, 0.4);
}
</style>
@endpush
@push('scripts')
<script src="/back/src/plugins/bootstrap-tagsinput/bootstrap-tagsinput.js"></script>
<script src="/ckeditor/ckeditor.js"></script>
// Image Preview
<script>
document.getElementById("featured_image_input").addEventListener("change", function(e) {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = function(event) {
document.getElementById("featured_image_preview").src = event.target.result;
};
reader.readAsDataURL(file);
});
</script>
// Create Post
<script>
$('#updatePostForm').on('submit', function(e) {
e.preventDefault();
var form = this;
var content = CKEDITOR.instances.content.getData();
var formdata = new FormData(form);
formdata.append('content', content);
$.ajax({
url: $(form).attr('action'),
method: $(form).attr('method'),
data: formdata,
processData: false,
dataType: 'json',
contentType: false,
beforeSend: function() {
$(form).find('span.error-text').text('');
},
success: function(data) {
if (data.status == 1) {
$(form)[0].reset();
toastr.success(data.message);
} else {
toastr.error(data.message);
}
},
error: function(jqXHR, textStatus, errorThrown) {
console.log('AJAX error', textStatus, errorThrown);
console.log('Response:', jqXHR);
if (jqXHR.responseJSON && jqXHR.responseJSON.errors) {
$.each(jqXHR.responseJSON.errors, function(prefix, val) {
$(form).find('span.' + prefix + '_error').text(val[0]);
});
} else {
toastr.error('Es ist ein unerwarteter Fehler aufgetreten.');
}
}
});
});
</script>
@endpush

View File

@@ -0,0 +1,179 @@
@extends('back.layout.pages-layout')
@section('pageTitle', isset($pageTitle) ? $pageTitle : 'Page Title here')
@section('content')
<div class="page-header">
<div class="row">
<div class="col-md-12 col-sm-12">
<div class="title">
<h4>Einstellungen</h4>
</div>
<nav aria-label="breadcrumb" role="navigation">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="{{ route('admin.dashboard') }}">Home</a>
</li>
<li class="breadcrumb-item active" aria-current="page">
Allgemeine Einstellungen
</li>
</ol>
</nav>
</div>
</div>
</div>
<div class="pd-20 card-box mb-4">
@livewire('admin.settings')
</div>
@endsection
@push('scripts')
<script>
document.getElementById("profileLogoFile").addEventListener("change", function(e) {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = function(event) {
document.getElementById("preview_site_logo").src = event.target.result;
};
reader.readAsDataURL(file);
});
$("#updateLogoForm").submit(function(e) {
e.preventDefault();
var form = this;
var inputVal = $(form).find('input[type="file"]').val();
var errorElement = $(form).find('span.text-danger');
errorElement.text('');
if (inputVal.length > 0) {
$.ajax({
url: $(form).attr('action'),
method: $(form).attr('method'),
data: new FormData(form),
processData: false,
dataType: 'json',
contentType: false,
success: function(data) {
toastr.options = {
closeButton: true,
newestOnTop: false,
progressBar: true,
positionClass: "toast-bottom-right",
preventDuplicates: false,
onclick: null,
showDuration: "300",
hideDuration: "1000",
timeOut: "5000",
extendedTimeOut: "1000",
showEasing: "swing",
hideEasing: "linear",
showMethod: "fadeIn",
hideMethod: "fadeOut"
};
if (data.status == 1) {
// Erfolgsnachricht aus RESPONSE
toastr.success(data.message);
$(form)[0].reset();
// Alle Logos aktualisieren
$('img.site_logo').each(function() {
$(this).attr('src', '/' + data.image_path);
});
} else {
toastr.error(data.message || "Es ist ein Fehler aufgetreten.");
}
}
});
} else {
errorElement.text('Bitte, wähle ein Foto');
}
});
</script>
<script>
document.getElementById("profileFaviconFile").addEventListener("change", function(e) {
const file = e.target.files[0];
if (!file) return;
const reader = new FileReader();
reader.onload = function(event) {
document.getElementById("preview_site_favicon").src = event.target.result;
};
reader.readAsDataURL(file);
});
$("#updateFaviconForm").submit(function(e) {
e.preventDefault();
var form = this;
var inputVal = $(form).find('input[type="file"]').val();
var errorElement = $(form).find('span.text-danger');
errorElement.text('');
if (inputVal.length > 0) {
$.ajax({
url: $(form).attr('action'),
method: $(form).attr('method'),
data: new FormData(form),
processData: false,
dataType: 'json',
contentType: false,
success: function(data) {
toastr.options = {
closeButton: true,
newestOnTop: false,
progressBar: true,
positionClass: "toast-bottom-right",
preventDuplicates: false,
onclick: null,
showDuration: "300",
hideDuration: "1000",
timeOut: "5000",
extendedTimeOut: "1000",
showEasing: "swing",
hideEasing: "linear",
showMethod: "fadeIn",
hideMethod: "fadeOut"
};
if (data.status == 1) {
// Erfolgsnachricht aus RESPONSE
toastr.success(data.message);
$(form)[0].reset();
// Alle Logos aktualisieren
$('img.site_favicon').each(function() {
$(this).attr('src', '/' + data.image_path);
});
} else {
toastr.error(data.message || "Es ist ein Fehler aufgetreten.");
}
}
});
} else {
errorElement.text('Bitte, wähle ein Foto');
}
});
</script>
@endpush
@push('stylesheets')

View File

@@ -0,0 +1,49 @@
@extends('back.layout.pages-layout')
@section('pageTitle', isset($pageTitle) ? $pageTitle : 'Page Title here')
@section('content')
<div class="page-header">
<div class="row">
<div class="col-md-6 col-sm-12">
<div class="title">
<h4>Alle Posts</h4>
</div>
<nav aria-label="breadcrumb" role="navigation">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="{{ route('admin.dashboard') }}">Home</a>
</li>
<li class="breadcrumb-item active" aria-current="page">
Posts
</li>
</ol>
</nav>
</div>
<div class="col-md-6 col-sm-12 text-right">
<a href="{{ route('admin.add_post') }}" class="btn btn-primary">
<i class="icon-copy bi bi-plus-circle"></i> Post hinzufügen</a>
</div>
</div>
</div>
@livewire('admin.posts')
@endsection
@push('scripts')
<script>
window.addEventListener('deletePost', function(event) {
var id = event.detail[0].id;
Swal.fire({
title: "Bist du dir sicher?",
text: "Das du den Post löschen möchtest!",
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#3085d6",
cancelButtonColor: "#d33",
confirmButtonText: "Ja, löschen!"
}).then((result) => {
if (result.isConfirmed) {
Livewire.dispatch('deletePostAction', [id]);
}
});
});
</script>
@endpush

View File

@@ -0,0 +1,99 @@
@extends('back.layout.pages-layout')
@section('pageTitle', isset($pageTitle) ? $pageTitle : 'Page Title here')
@section('content')
<div class="page-header">
<div class="row">
<div class="col-md-12 col-sm-12">
<div class="title">
<h4>Profile</h4>
</div>
<nav aria-label="breadcrumb" role="navigation">
<ol class="breadcrumb">
<li class="breadcrumb-item">
<a href="{{ route('admin.dashboard') }}">Home</a>
</li>
<li class="breadcrumb-item active" aria-current="page">
Profile
</li>
</ol>
</nav>
</div>
</div>
</div>
@livewire('admin.profile')
@push('scripts')
<script>
const cropper = new Kropify('input[type="file"][id="profilePictureFile"]', {
aspectRatio: 1,
viewMode: 1,
preview: 'img#profilePicturePreview',
processURL: '{{ route('admin.update_profile_picture') }}', // or processURL:'/crop'
maxSize: 2 * 1024 * 1024, // 2MB
allowedExtensions: ['jpg', 'jpeg', 'png'],
showLoader: true,
animationClass: 'pulse',
cancelButtonText: 'Cancel',
resetButtonText: 'Reset',
cropButtonText: 'Crop & Upload',
maxWoH: 255,
onError: function(response) {
toastr.options = {
closeButton: true,
newestOnTop: false,
progressBar: true,
positionClass: "toast-bottom-right",
preventDuplicates: false,
onclick: null,
showDuration: "300",
hideDuration: "1000",
timeOut: "5000",
extendedTimeOut: "1000",
showEasing: "swing",
hideEasing: "linear",
showMethod: "fadeIn",
hideMethod: "fadeOut"
};
// Je nach Antwortstruktur anpassen:
const message = response.message || "Es ist ein Fehler aufgetreten.";
if (response.status === 0 || response.status === false) {
toastr.error(message);
} else {
toastr.error(message);
}
},
onDone: function(response) {
toastr.options = {
closeButton: true,
newestOnTop: false,
progressBar: true,
positionClass: "toast-bottom-right",
preventDuplicates: false,
onclick: null,
showDuration: "300",
hideDuration: "1000",
timeOut: "5000",
extendedTimeOut: "1000",
showEasing: "swing",
hideEasing: "linear",
showMethod: "fadeIn",
hideMethod: "fadeOut"
};
if (response.status === 1) {
toastr.success(response.message || "Erfolgreich gespeichert.");
Livewire.dispatch('updateTopUserInfo', []);
Livewire.dispatch('updateProfile', []);
} else {
toastr.error(response.message || "Etwas ist schiefgelaufen.");
}
}
});
</script>
@endpush
@endsection

View File

@@ -0,0 +1,53 @@
@extends('back.layout.pages-layout')
@section('pageTitle', isset($pageTitle) ? $pageTitle : 'Page Title here')
@section('content')
@livewire('admin.slides')
@endsection
@push('scripts')
<script>
var modal = $('#slide_modal');
window.addEventListener('showSlideModalForm', function(e) {
modal.modal("show");
});
window.addEventListener('hideSlideModalForm', function(e) {
modal.modal("hide");
});
$('table tbody#sortable_slides').sortable({
cursor: "move",
update: function(event, ui) {
$(this).children().each(function(index) {
if ($(this).attr('data-ordering') != (index + 1)) {
$(this).attr('data-ordering', (index + 1)).addClass('updated');
}
});
var positions = [];
$('.updated').each(function() {
positions.push([$(this).attr('data-index'), $(this).attr('data-ordering')]);
$(this).removeClass('updated');
});
Livewire.dispatch('updateSlidesOrdering', [positions]);
}
});
window.addEventListener('deleteSlide', function(event) {
var id = event.detail.id;
Swal.fire({
title: "Bist du dir sicher?",
text: "Das du den Slide löschen möchtest!",
icon: "warning",
showCancelButton: true,
confirmButtonColor: "#3085d6",
cancelButtonColor: "#d33",
confirmButtonText: "Ja, löschen!"
}).then((result) => {
if (result.isConfirmed) {
Livewire.dispatch('deleteSlideAction', [id]);
}
});
});
</script>
@endpush