feat: Implement VM restart, auto-renew invoice functionality, and client invoice detail API, alongside admin UI improvements.

This commit is contained in:
pbao9
2026-03-02 10:26:01 +07:00
parent 2c8c3d14cd
commit 0c260a7e1c
9 changed files with 842 additions and 44 deletions
@@ -0,0 +1,96 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<meta name="author" content="Administrator">
<title>Administrator</title>
<!-- color-modes:js -->
@vite(['resources/js/pages/color-modes.js'])
<script>
(function () {
const theme = localStorage.getItem('theme') || (window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light');
document.documentElement.setAttribute('data-bs-theme', theme);
})();
</script>
<!-- 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=Roboto:wght@300;400;500;700;900&display=swap" rel="stylesheet">
<!-- End fonts -->
<!-- CSRF Token -->
<meta name="_token" content="{{ csrf_token() }}">
<link rel="shortcut icon" href="{{ asset('/favicon.ico') }}">
<!-- Splash Screen -->
<link href="{{ asset('splash-screen.css') }}" rel="stylesheet" />
<!-- plugin css -->
<link href="{{ asset('build/plugins/perfect-scrollbar/perfect-scrollbar.css') }}" rel="stylesheet" />
@stack('plugin-styles')
<!-- CSS for LTR layout-->
@vite(['resources/sass/app.scss', 'resources/css/custom.css'])
<!-- CSS for RTL layout-->
<!-- @vite(['resources/rtl-css/app-rtl.css', 'resources/rtl-css/custom-rtl.css']) -->
@stack('style')
</head>
<body data-base-url="{{url('/')}}">
<script>
// Create splash screen container
var splash = document.createElement("div");
splash.innerHTML = `
<div class="splash-screen">
<div class="logo"></div>
<div class="spinner"></div>
</div>`;
// Insert splash screen as the first child of the body
document.body.insertBefore(splash, document.body.firstChild);
// Add 'loaded' class to body once DOM is fully loaded
document.addEventListener("DOMContentLoaded", function () {
document.body.classList.add("loaded");
});
</script>
<div class="main-wrapper" id="app">
<div class="page-wrapper full-page">
<div class="page-content container-xxl d-flex align-items-center justify-content-center">
<div id="fui-toast"></div>
@yield('content')
</div>
</div>
</div>
<!-- base js -->
@vite(['resources/js/app-vite.js'])
<script src="{{ asset('build/plugins/lucide/lucide.min.js') }}"></script>
<!-- end base js -->
<!-- plugin js -->
@stack('plugin-scripts')
<!-- end plugin js -->
<!-- common js -->
@vite(['resources/js/pages/template.js'])
<!-- end common js -->
@include('administrator.layout.partials.toast')
@stack('custom-scripts')
</body>
</html>
@@ -1,4 +1,4 @@
@extends('administrator.layout.master')
@extends('administrator.layout.master2')
@section('content')
<div class="row w-100 mx-0 auth-page">
@@ -7,9 +7,9 @@
<div class="row">
<div class="col-md-4 pe-md-0">
<div class="auth-side-wrapper" style="background-image: url('https://picsum.photos/220/450?random=1');"></div>
</div>
<div class="col-md-8 ps-md-0">
<div class="auth-form-wrapper px-4 py-5">
</div>
<div class="col-md-8 ps-md-0">
<div class="auth-form-wrapper px-4 py-5">
<img src="{{ setting('setting.logo') }}" alt="{{ setting('setting.company') }}" width="100%" class="mb-5" />
<form class="forms-sample" method="post" action="{{ route('login.store') }}">
@@ -17,22 +17,22 @@
<div class="mb-3">
<label for="userEmail" class="form-label fw-bold">Tên đăng nhập</label>
<input type="text" class="form-control" id="userEmail" name="username" placeholder="Tên đăng nhập">
</div>
<div class="mb-3">
</div>
<div class="mb-3">
<label for="userPassword" class="form-label fw-bold">Mật khẩu</label>
<input type="password" class="form-control" id="userPassword" name="password" autocomplete="current-password"
placeholder="Mật khẩu">
</div>
<input type="password" class="form-control" id="userPassword" name="password"
autocomplete="current-password" placeholder="Mật khẩu">
</div>
<div class="d-flex justify-content-center">
<button type="submit" class="btn btn-primary me-2 mb-2 mb-md-0">Đăng nhập</button>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
@endsection
@push('plugin-scripts')
@endpush