migrate to gtea from bistbucket

This commit is contained in:
2026-03-15 17:08:23 +07:00
commit 129ca2260c
3716 changed files with 566316 additions and 0 deletions

View File

@@ -0,0 +1,11 @@
@import 'tailwindcss';
@source '../../vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php';
@source '../../storage/framework/views/*.php';
@source '../**/*.blade.php';
@source '../**/*.js';
@theme {
--font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
'Segoe UI Symbol', 'Noto Color Emoji';
}

View File

@@ -0,0 +1 @@
import './bootstrap';

View File

@@ -0,0 +1,4 @@
import axios from 'axios';
window.axios = axios;
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';

View File

@@ -0,0 +1,20 @@
<?php
namespace DummyNamespace;
use App\Models\DummyModel;
class DummyClass
{
protected $model;
public function __construct(DummyModel $model)
{
$this->model = $model;
}
public function handle($request)
{
// Action implementation for DummyAction
}
}

View File

@@ -0,0 +1,101 @@
<?php
namespace DummyNamespace;
use App\Http\Controllers\Controller;
use App\Http\Requests\DummyModel\DummyModelStoreRequest;
use App\Http\Requests\DummyModel\DummyModelUpdateRequest;
use App\Services\DummyModel\DummyModelService;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Traits\ResponseTrait;
class DummyClass extends Controller
{
use ResponseTrait;
public function __construct(
private DummyModelService $service
) {}
public function all(Request $request)
{
$models = $this->service->getAll($request);
$metadata['count'] = count($models);
if(!$models){
return $this->ResponseError([], null, 'No Data Found!');
}
return $this->ResponseSuccess($models, $metadata, 'DummyModel has been fetch successfully.');
}
public function index(Request $request)
{
$perPage = request('per_page') ?? env('PER_PAGE');
$models = $this->service->index($request, $perPage);
if(!$models){
return $this->ResponseError([], null, 'No Data Found!');
}
return $this->ResponseSuccess($models, null, 'DummyModel has been fetch successfully.');
}
public function store(DummyModelStoreRequest $request)
{
DB::beginTransaction();
try {
$data = $this->service->create($request->validated());
DB::commit();
return $this->ResponseSuccess($data, [], 'DummyModel has been create successfully.');
} catch (\Exception $e) {
DB::rollBack();
return $this->ResponseError($e->getMessage(). " in " . $e->getFile() . " on line " . $e->getLine(), null, 'Data Process Error!');
}
}
public function show(int $id)
{
$model = $this->service->getById($id);
if(!$model){
return $this->ResponseError([], null, 'No Data Found!');
}
return $this->ResponseSuccess($model, null, 'DummyModel has been show successfully.');
}
public function update(DummyModelUpdateRequest $request, int $id)
{
DB::beginTransaction();
try {
$data = $this->service->update($id, $request->validated());
DB::commit();
return $this->ResponseSuccess($data, null, 'DummyModel has been update successfully.');
} catch (\Exception $e) {
DB::rollBack();
return $this->ResponseError($e->getMessage(). " in " . $e->getFile() . " on line " . $e->getLine(), null, 'Data Process Error!');
}
}
public function destroy(int $id)
{
DB::beginTransaction();
try {
$data = $this->service->delete($id);
if(!$data){
return $this->ResponseError([], null, 'Data Not Found!', 204);
}
DB::commit();
return $this->ResponseSuccess($data, null, 'DummyModel has been delete successfully.', 200);
} catch (\Exception $e) {
DB::rollBack();
return $this->ResponseError($e->getMessage(). " in " . $e->getFile() . " on line " . $e->getLine(), null, 'Data Not Found!');
}
}
}

View File

@@ -0,0 +1,100 @@
<?php
namespace DummyNamespace;
use App\Http\Controllers\Controller;
use App\Http\Requests\DummyModel\DummyModelStoreRequest;
use App\Http\Requests\DummyModel\DummyModelUpdateRequest;
use App\Services\DummyModel\DummyModelService;
use App\DataTables\DummyModel\DummyModelDataTable;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Contracts\View\View;
use RealRashid\SweetAlert\Facades\Alert;
class DummyClass extends Controller
{
public function __construct(
private DummyModelService $service
){}
public function all(Request $request): View
{
$models = $this->service->getAll($request);
return view('backend.model.index', compact('models'));
}
public function index(DummyModelDataTable $dataTable)
{
return $dataTable->render('backend.model.index');
}
public function create(): View
{
return view('backend.model.create');
}
public function store(DummyModelStoreRequest $request)
{
DB::beginTransaction();
try {
$this->service->create($request->validated());
DB::commit();
Alert::toast('DummyModel has been create successfully.','success');
return redirect()->route('models.index');
} catch (\Exception $e) {
DB::rollBack();
Alert::error('Error', $e->getMessage());
return redirect()->route('models.index');
}
}
public function edit(int $id)
{
$model = $this->service->getById($id);
return view('backend.model.edit', compact('model'));
}
public function update(DummyModelUpdateRequest $request, int $id)
{
DB::beginTransaction();
try {
$this->service->update($id, $request->validated());
DB::commit();
Alert::toast('DummyModel has been update successfully.','success');
return redirect()->route('models.index');
} catch (\Exception $e) {
DB::rollBack();
Alert::error('Error', $e->getMessage());
return redirect()->route('models.index');
}
}
public function destroy(int $id)
{
DB::beginTransaction();
try {
$this->service->delete($id);
DB::commit();
Alert::toast('DummyModel has been delete successfully.','success');
return redirect()->route('models.index');
} catch (\Exception $e) {
DB::rollBack();
Alert::error('Error', $e->getMessage());
return redirect()->route('models.index');
}
}
}

View File

@@ -0,0 +1,104 @@
@extends('layouts.backend')
@section('title', ucfirst('Model') . ' Form')
@section('page_title', ucfirst('Model') . ' Form')
@section('content')
<!-- Page Header -->
<div class="row mb-4">
<div class="col-12 d-flex justify-content-between align-items-center">
<h1 class="h3 mb-0">{{ ucfirst('Model') }} Management</h1>
<a href="{{ route('models.index') }}" class="btn btn-outline-secondary">
<i class="bi bi-arrow-left"></i> Back to List
</a>
</div>
</div>
<!-- Form Card -->
<div class="card">
<div class="card-body">
<form action="{{ route('models.store') }}" enctype="multipart/form-data" method="POST">
@csrf
<div class="row">
<!-- Name -->
<div class="col-md-6 mb-3">
<label for="name" class="form-label">{{ _lang('Name') }}</label>
<input type="text" class="form-control" id="name" name="name"
value="{{ old('name') }}" placeholder="Enter name" required>
@error('name')
<small class="text-danger">{{ $message }}</small>
@enderror
</div>
<!-- Code -->
<div class="col-md-6 mb-3">
<label for="code" class="form-label">{{ _lang('Code') }}</label>
<input type="text" class="form-control" id="code" name="code"
value="{{ old('code') }}" placeholder="Enter code">
@error('code')
<small class="text-danger">{{ $message }}</small>
@enderror
</div>
</div>
<!-- Image Upload -->
<div class="mb-4">
<label class="form-label d-block mb-2">Image</label>
<div class="card card-flush py-3">
<div class="card-body text-center">
<style>
.image-input-placeholder {
background-image: url('{{ asset('assets/media/svg/files/blank-image.svg') }}');
}
[data-theme="dark"] .image-input-placeholder {
background-image: url('{{ asset('assets/media/svg/files/blank-image-dark.svg') }}');
}
</style>
<div class="image-input image-input-empty image-input-outline image-input-placeholder mb-3"
data-kt-image-input="true">
<div class="image-input-wrapper w-150px h-150px"></div>
<!-- Upload -->
<label class="btn btn-icon btn-circle btn-active-color-primary w-25px h-25px bg-body shadow"
data-kt-image-input-action="change" data-bs-toggle="tooltip" title="Change image">
<i class="bi bi-pencil-fill fs-7"></i>
<input type="file" name="image" accept=".png, .jpg, .jpeg" />
<input type="hidden" name="image_remove" />
</label>
<!-- Cancel -->
<span class="btn btn-icon btn-circle btn-active-color-primary w-25px h-25px bg-body shadow"
data-kt-image-input-action="cancel" data-bs-toggle="tooltip" title="Cancel image">
<i class="bi bi-x fs-2"></i>
</span>
<!-- Remove -->
<span class="btn btn-icon btn-circle btn-active-color-primary w-25px h-25px bg-body shadow"
data-kt-image-input-action="remove" data-bs-toggle="tooltip" title="Remove image">
<i class="bi bi-x fs-2"></i>
</span>
</div>
<div class="text-muted fs-7">
Set the product thumbnail image. Only *.png, *.jpg, and *.jpeg files are accepted.
</div>
</div>
</div>
</div>
<!-- Submit Button -->
<div class="d-flex gap-2">
<button type="submit" class="btn btn-primary">
<i class="bi bi-check"></i> {{ _lang('Create') }}
</button>
<a href="{{ route('models.index') }}" class="btn btn-secondary">
Cancel
</a>
</div>
</form>
</div>
</div>
@endsection

View File

@@ -0,0 +1,112 @@
<?php
namespace DummyNamespace;
use App\Models\DummyModel;
use App\Services\DummyModel\DummyModelService;
use Illuminate\Database\Eloquent\Builder as QueryBuilder;
use Yajra\DataTables\EloquentDataTable;
use Yajra\DataTables\Html\Builder as HtmlBuilder;
use Yajra\DataTables\Html\Column;
use Yajra\DataTables\Services\DataTable;
class DummyClass extends DataTable
{
public function __construct(
private DummyModelService $service
) {}
public function dataTable(QueryBuilder $query): EloquentDataTable
{
return (new EloquentDataTable($query))
->addIndexColumn()
->addColumn('action', function (DummyModel $model) {
$html = '<a class="btn btn-icon btn-bg-light btn-active-color-primary btn-sm me-1 edit-icon" href="' . route('models.edit', $model->id) . '">
<span class="svg-icon svg-icon-3">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.3" d="M21.4 8.35303L19.241 10.511L13.485 4.755L15.643 2.59595C16.0248 2.21423 16.5426 1.99988 17.0825 1.99988C17.6224 1.99988 18.1402 2.21423 18.522 2.59595L21.4 5.474C21.7817 5.85581 21.9962 6.37355 21.9962 6.91345C21.9962 7.45335 21.7817 7.97122 21.4 8.35303ZM3.68699 21.932L9.88699 19.865L4.13099 14.109L2.06399 20.309C1.98815 20.5354 1.97703 20.7787 2.03189 21.0111C2.08674 21.2436 2.2054 21.4561 2.37449 21.6248C2.54359 21.7934 2.75641 21.9115 2.989 21.9658C3.22158 22.0201 3.4647 22.0084 3.69099 21.932H3.68699Z" fill="currentColor"></path>
<path d="M5.574 21.3L3.692 21.928C3.46591 22.0032 3.22334 22.0141 2.99144 21.9594C2.75954 21.9046 2.54744 21.7864 2.3789 21.6179C2.21036 21.4495 2.09202 21.2375 2.03711 21.0056C1.9822 20.7737 1.99289 20.5312 2.06799 20.3051L2.696 18.422L5.574 21.3ZM4.13499 14.105L9.891 19.861L19.245 10.507L13.489 4.75098L4.13499 14.105Z" fill="currentColor"></path>
</svg>
</span>
</a>';
$html .= '<button type="button" class="btn btn-icon btn-bg-light btn-active-color-primary btn-sm delete-icon" data-bs-toggle="modal" data-bs-target="#deleteDummyModel' . $model->id . '">
<span class="svg-icon svg-icon-3">
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M5 9C5 8.44772 5.44772 8 6 8H18C18.5523 8 19 8.44772 19 9V18C19 19.6569 17.6569 21 16 21H8C6.34315 21 5 19.6569 5 18V9Z" fill="currentColor"></path>
<path opacity="0.5" d="M5 5C5 4.44772 5.44772 4 6 4H18C18.5523 4 19 4.44772 19 5V5C19 5.55228 18.5523 6 18 6H6C5.44772 6 5 5.55228 5 5V5Z" fill="currentColor"></path>
<path opacity="0.5" d="M9 4C9 3.44772 9.44772 3 10 3H14C14.5523 3 15 3.44772 15 4V4H9V4Z" fill="currentColor"></path>
</svg>
</span>
</button>';
$html .= '
<div class="modal fade" id="deleteDummyModel' . $model->id . '" data-bs-backdrop="static" data-bs-keyboard="false" tabindex="-1" aria-labelledby="staticBackdropLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h5 class="modal-title" id="staticBackdropLabel">Are you sure?</h5>
<button type="button" class="btn-close" data-bs-dismiss="modal" aria-label="Close"></button>
</div>
<div class="modal-body">
<p>
Are you sure you want to delete the DummyModel - <b>' . $model->name . '</b>?
</p>
<form action="' . route('models.destroy', $model->id) . '" method="POST">
' . csrf_field() . method_field('DELETE') . '
<button type="submit" class="btn btn-danger">Confirm Delete</button>
</form>
</div>
</div>
</div>
</div>
';
return $html;
})
->rawColumns(['action']);
}
public function query(DummyModel $model): QueryBuilder
{
return $this->service->get(['is_query' => true]);
}
public function html(): HtmlBuilder
{
return $this->builder()
->setTableId('DummyModel-table')
->columns($this->getColumns())
->minifiedAjax()
->orderBy(1)
->selectStyleSingle()
->buttons([
// Button::make('add'),
// Button::make('excel'),
// Button::make('csv'),
// Button::make('pdf'),
// Button::make('print'),
// Button::make('reset'),
// Button::make('reload'),
]);
}
public function getColumns(): array
{
return [
Column::make('DT_RowIndex')->title('Sl no')->searchable(false)->orderable(false),
Column::make('name')->title('Name'),
Column::make('code')->title('Code'),
Column::make('action')
->title('Action')
->searchable(false)
->orderable(false)
->printable(false),
];
}
protected function filename(): string
{
return 'DummyModel-'.date('YmdHis');
}
}

View File

@@ -0,0 +1,107 @@
@extends('layouts.backend')
@section('title', ucfirst('Food') . ' Form')
@section('page_title', ucfirst('Food') . ' Form')
@section('content')
<!-- Page Header -->
<div class="row mb-4">
<div class="col-12 d-flex justify-content-between align-items-center">
<h1 class="h3 mb-0">{{ ucfirst('Food') }} Management</h1>
<a href="{{ route('products.index') }}" class="btn btn-outline-secondary">
<i class="bi bi-arrow-left"></i> Back to List
</a>
</div>
</div>
<!-- Edit Form Card -->
<div class="card">
<div class="card-body">
<form action="{{ route('products.update', $product->id) }}" enctype="multipart/form-data" method="POST">
@csrf
@method('PATCH')
<div class="row">
<!-- Name -->
<div class="col-md-6 mb-3">
<label for="name" class="form-label">{{ _lang('Name') }}</label>
<input type="text" class="form-control" id="name" name="name"
value="{{ old('name', $product->name) }}" placeholder="Enter name" required>
@error('name')
<small class="text-danger">{{ $message }}</small>
@enderror
</div>
<!-- Code -->
<div class="col-md-6 mb-3">
<label for="code" class="form-label">{{ _lang('Code') }}</label>
<input type="text" class="form-control" id="code" name="code"
value="{{ old('code', $product->code) }}" placeholder="Enter code">
@error('code')
<small class="text-danger">{{ $message }}</small>
@enderror
</div>
</div>
<!-- Image Upload -->
<div class="mb-4">
<label class="form-label d-block mb-2">Image</label>
<div class="card card-flush py-3">
<div class="card-body text-center">
<style>
.image-input-placeholder {
background-image: url('{{ asset('assets/media/svg/files/blank-image.svg') }}');
}
[data-theme="dark"] .image-input-placeholder {
background-image: url('{{ asset('assets/media/svg/files/blank-image-dark.svg') }}');
}
</style>
<div class="image-input image-input-outline image-input-placeholder mb-3"
data-kt-image-input="true"
style="background-image: url('{{ $product->image ? asset($product->image) : asset('assets/media/svg/files/blank-image.svg') }}');">
<!-- Existing Image Preview -->
<div class="image-input-wrapper w-150px h-150px"
style="background-image: url('{{ $product->image ? asset($product->image) : asset('assets/media/svg/files/blank-image.svg') }}');">
</div>
<!-- Upload -->
<label class="btn btn-icon btn-circle btn-active-color-primary w-25px h-25px bg-body shadow"
data-kt-image-input-action="change" data-bs-toggle="tooltip" title="Change image">
<i class="bi bi-pencil-fill fs-7"></i>
<input type="file" name="image" accept=".png, .jpg, .jpeg" />
<input type="hidden" name="image_remove" />
</label>
<!-- Cancel -->
<span class="btn btn-icon btn-circle btn-active-color-primary w-25px h-25px bg-body shadow"
data-kt-image-input-action="cancel" data-bs-toggle="tooltip" title="Cancel image">
<i class="bi bi-x fs-2"></i>
</span>
<!-- Remove -->
<span class="btn btn-icon btn-circle btn-active-color-primary w-25px h-25px bg-body shadow"
data-kt-image-input-action="remove" data-bs-toggle="tooltip" title="Remove image">
<i class="bi bi-x fs-2"></i>
</span>
</div>
<div class="text-muted fs-7">
Update the product image. Accepted formats: *.png, *.jpg, *.jpeg.
</div>
</div>
</div>
</div>
<!-- Submit Button -->
<div class="d-flex gap-2">
<button type="submit" class="btn btn-primary">
<i class="bi bi-check"></i> {{ _lang('Update') }}
</button>
<a href="{{ route('products.index') }}" class="btn btn-secondary">Cancel</a>
</div>
</form>
</div>
</div>
@endsection

View File

@@ -0,0 +1,29 @@
@extends('layouts.backend')
@section('title', ucfirst('Model'))
@section('page_title', ucfirst('Model'))
@section('content')
<!-- Page Header -->
<div class="row mb-4">
<div class="col-12 d-flex justify-content-between align-items-center">
<h1 class="h3 mb-0">{{ ucfirst('Model') }} Management</h1>
<a href="{{ route('models.create') }}" class="btn btn-primary">
<i class="bi bi-plus"></i> Add New {{ ucfirst('Model') }}
</a>
</div>
</div>
<!-- DataTable Card -->
<div class="card">
<div class="card-body">
<div class="table-responsive">
{{ $dataTable->table() }}
</div>
</div>
</div>
@endsection
@section('scripts')
{{ $dataTable->scripts(attributes: ['type' => 'module']) }}
@endsection

View File

@@ -0,0 +1,18 @@
<?php
namespace DummyNamespace;
interface DummyClass
{
public function index($request, int $per_page = 50);
public function getAll($request);
public function getById(int $id);
public function create(array $data);
public function update(int $id, array $data);
public function delete(int $id);
}

View File

@@ -0,0 +1,28 @@
<?php
namespace DummyNamespace;
use Illuminate\Foundation\Http\FormRequest;
class DummyClass extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'name' => 'required|string|max:30',
'email' => 'nullable|string|email|max:30',
'phone' => 'nullable|string|max:20',
'image' => 'nullable|image|max:2048',
];
}
public function message(): array{
return [
//
];
}
}

View File

@@ -0,0 +1,97 @@
<?php
namespace DummyNamespace;
use App\Interfaces\DummyModel\DummyModelInterface;
use App\Models\DummyModel;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Contracts\Pagination\LengthAwarePaginator;
final class DummyClass implements DummyModelInterface
{
public function __construct(
protected DummyModel $model
){}
/**
* Get categories by filtering args.
*/
public function get(array $args = []): \Illuminate\Database\Eloquent\Collection|\Illuminate\Database\Eloquent\Builder
{
$orderBy = empty($args['order_by']) ? 'id' : $args['order_by']; // column name
$order = empty($args['order']) ? 'asc' : $args['order']; // asc, desc
$query = DummyModel::orderBy($orderBy, $order);
if (isset($args['is_query']) && $args['is_query']) {
return $query;
}
return $query->get();
}
public function index($request, int $per_page = 50)
{
$orderColumn = request('sort_column', 'id');
$orderDirection = request('sort_direction', 'desc');
if (!in_array($orderColumn, ['id', 'name', 'created_at'])) {
$orderColumn = 'id';
}
if (!in_array($orderDirection, ['asc', 'desc'])) {
$orderDirection = 'desc';
}
return $this->model::query()
->when($request->search, function ($query) use ($request) {
$query->where('name', 'like', $request->search . '%');
})
->orderBy($orderColumn, $orderDirection)
->paginate($per_page);
}
public function getAll($request)
{
$orderColumn = request('sort_column', 'id');
$orderDirection = request('sort_direction', 'desc');
if (!in_array($orderColumn, ['id', 'name', 'created_at'])) {
$orderColumn = 'id';
}
if (!in_array($orderDirection, ['asc', 'desc'])) {
$orderDirection = 'desc';
}
return $this->model::query()
->when($request->search, function ($query) use ($request) {
$query->where('name', 'like', $request->search . '%');
})
->orderBy($orderColumn, $orderDirection)
->get();
}
public function getById(int $id)
{
$record = $this->model::find($id);
return $record ?? null;
}
public function create(array $data)
{
return $this->model::create($data);
}
public function update(int $id, array $data)
{
$model = $this->model::findOrFail($id);
$model->update($data);
return $model;
}
public function delete(int $id)
{
$model = $this->model::findOrFail($id);
return $model->delete();
}
}

View File

@@ -0,0 +1,253 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Invoice #{{ $invoice->invoice_no }}</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<style>
body {
font-family: 'Helvetica Neue', Helvetica, Arial, sans-serif;
background-color: #f4f6f8;
margin: 0;
padding: 0;
color: #333333;
}
.wrapper {
width: 100%;
padding: 30px 0;
}
.container {
max-width: 700px;
margin: 0 auto;
background-color: #ffffff;
border-radius: 8px;
overflow: hidden;
box-shadow: 0 6px 18px rgba(0, 0, 0, 0.08);
}
.header {
background-color: #1E3A8A;
color: #ffffff;
padding: 30px;
text-align: center;
}
.header h1 {
margin: 0;
font-size: 26px;
font-weight: 700;
letter-spacing: 1px;
}
.header p {
margin: 6px 0 0;
font-size: 15px;
color: #d1d5db;
}
.content {
padding: 30px;
}
.content h2 {
font-size: 20px;
margin: 0 0 10px;
}
.content p {
font-size: 15px;
line-height: 1.6;
margin: 10px 0;
}
.invoice-table {
width: 100%;
border-collapse: collapse;
margin: 25px 0;
}
.invoice-table th,
.invoice-table td {
border: 1px solid #e5e7eb;
padding: 12px 14px;
text-align: left;
font-size: 14px;
}
.invoice-table th {
background-color: #f9fafb;
font-weight: 600;
width: 40%;
}
.invoice-table td {
width: 60%;
}
.total-row td {
font-size: 16px;
font-weight: bold;
color: #1E3A8A;
}
.notice {
background-color: #f9fafb;
border-left: 4px solid #1E3A8A;
padding: 15px;
margin-top: 20px;
font-size: 14px;
color: #555555;
}
.button-wrapper {
text-align: center;
margin: 30px 0 10px;
}
.pay-button {
background-color: #1E3A8A;
color: #ffffff;
padding: 14px 30px;
font-size: 15px;
font-weight: 600;
text-decoration: none;
border-radius: 6px;
display: inline-block;
}
.pay-button:hover {
background-color: #162d6b;
}
.footer {
padding: 25px;
text-align: center;
font-size: 13px;
color: #9ca3af;
}
.footer a {
color: #1E3A8A;
text-decoration: none;
font-weight: 500;
}
@media only screen and (max-width: 600px) {
.content {
padding: 20px;
}
.header h1 {
font-size: 22px;
}
.invoice-table th,
.invoice-table td {
padding: 10px;
}
}
</style>
</head>
<body>
<div class="wrapper">
<div class="container">
{{-- Header --}}
<div class="header">
<h1>
{{ \Carbon\Carbon::parse($invoice->month . '-01')->format('F Y') }} Invoice
</h1>
<p>MolyEcom SaaS Billing</p>
</div>
{{-- Content --}}
<div class="content">
<h2>Hello {{ $shop->name }},</h2>
<p>
This invoice has been generated automatically for your
<strong>{{ $invoice->package_name }}</strong> subscription.
</p>
<table class="invoice-table">
<tr>
<th>Invoice Number</th>
<td>{{ $invoice->invoice_no }}</td>
</tr>
<tr>
<th>Subscription Package</th>
<td>{{ $invoice->package_name }}</td>
</tr>
<tr>
<th>Billing Period</th>
<td>
{{ \Carbon\Carbon::parse($invoice->start_date)->format('d M Y') }}
{{ \Carbon\Carbon::parse($invoice->end_date)->format('d M Y') }}
</td>
</tr>
<tr>
<th>Subscription Expiry</th>
<td>
{{ \Carbon\Carbon::parse($invoice->end_date)->format('d M Y') }}
</td>
</tr>
@if (!empty($domainInfo['domain']))
<tr>
<th>Domain</th>
<td>{{ $domainInfo['domain'] }}</td>
</tr>
<tr>
<th>Domain Expiry</th>
<td>
{{ \Carbon\Carbon::parse($domainInfo['domain_expiry'])->format('d M Y') }}
</td>
</tr>
@endif
<tr class="total-row">
<th>Total Amount</th>
<td> {{ number_format($invoice->amount, 2) }}</td>
</tr>
<tr>
<th>Payment Status</th>
<td>{{ $invoice->status }}</td>
</tr>
</table>
<div class="notice">
<strong>Important:</strong>
Please complete your payment before the subscription expiry date to avoid service interruption.
</div>
@if (!empty($paymentUrl))
<div class="button-wrapper">
<a href="{{ $paymentUrl }}" class="pay-button">
Pay / Upgrade Subscription
</a>
</div>
@endif
<p>
If you have any questions regarding this invoice, feel free to contact our support team.
</p>
</div>
{{-- Footer --}}
<div class="footer">
&copy; {{ date('Y') }} <strong>CodeMoly</strong>. All rights reserved.<br>
MolyEcom SaaS Application |
<a href="{{ config('app.frontend_url') }}">Visit Dashboard</a>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,124 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Welcome to {{ config('app.name') }}</title>
</head>
<body style="margin:0; padding:0; font-family:Arial, sans-serif; background-color:#f4f4f4;">
<table width="100%" cellpadding="0" cellspacing="0" bgcolor="#f4f4f4">
<tr>
<td align="center">
<table width="600" cellpadding="0" cellspacing="0" bgcolor="#ffffff"
style="margin:40px 0; border-radius:8px; overflow:hidden; box-shadow:0 0 10px rgba(0,0,0,0.1);">
<!-- Header -->
<tr>
<td style="background-color:#FF5722; padding:20px; text-align:center; color:#ffffff;">
<h1 style="margin:0; font-size:28px;">🎉 Welcome to {{ config('app.name') }}!</h1>
</td>
</tr>
<!-- Greeting -->
<tr>
<td style="padding:30px;">
<p style="font-size:16px; color:#333;">Hi <strong>{{ $restaurantName }}</strong>,</p>
<p style="font-size:16px; color:#333;">
Your restaurant has been successfully onboarded to
<strong>{{ config('app.name') }}</strong>.<br>
Below are your login details and trial package information:
</p>
</td>
</tr>
<!-- Account Details -->
<tr>
<td style="padding:0 30px 20px;">
<h2
style="font-size:18px; color:#FF5722; border-bottom:2px solid #FF5722; padding-bottom:5px;">
🆔 Account Details
</h2>
<ul style="list-style:none; padding:0; margin:10px 0; color:#333;">
<li><strong>Restaurant ID:</strong> {{ $restaurantId }}</li>
<li><strong>Email:</strong> {{ $email }}</li>
<li><strong>Password:</strong> {{ $password }}</li>
</ul>
<p style="font-size:14px; color:#FF5722;">
⚠️ Please change your password after first login.
</p>
</td>
</tr>
<!-- Trial Package -->
<tr>
<td style="padding:0 30px 20px;">
<h2
style="font-size:18px; color:#FF5722; border-bottom:2px solid #FF5722; padding-bottom:5px;">
📦 Trial Package Details
</h2>
<ul style="list-style:none; padding:0; margin:10px 0; color:#333;">
<li><strong>Package Name:</strong> {{ $packageName }}</li>
<li><strong>Trial Duration:</strong> {{ $trialDays }} days</li>
<li><strong>Valid Until:</strong> {{ $trialEndDate }}</li>
</ul>
</td>
</tr>
<!-- Dashboard CTA -->
<tr>
<td style="padding:30px; text-align:center;">
<a href="{{ $loginUrl }}"
style="display:inline-block; padding:15px 30px; background-color:#FF5722;
color:#ffffff; text-decoration:none; font-size:16px; border-radius:5px;">
Login to Dashboard
</a>
</td>
</tr>
<!-- NameServer Info -->
<tr>
<td style="padding:20px 30px;">
<h2
style="font-size:18px; color:#FF5722; border-bottom:2px solid #FF5722; padding-bottom:5px;">
🌐 DNS / NameServer Configuration
</h2>
<p style="font-size:15px; color:#333; margin:10px 0;">
Please update your domains NameServers to point your subdomain automatically:
</p>
<ul style="list-style:none; padding:0; margin:0; color:#333;">
<li><strong>NS1:</strong> ns1.vercel-dns.com</li>
<li><strong>NS2:</strong> ns2.vercel-dns.com</li>
</ul>
<p style="font-size:13px; color:#555; margin-top:10px;">
After updating NameServers, propagation may take up to 30 minutes.
</p>
</td>
</tr>
<!-- Footer -->
<tr>
<td
style="padding:20px 30px; font-size:14px; color:#777; text-align:center; background-color:#f4f4f4;">
For any support, contact us:<br>
<a href="mailto:support@yourdomain.com" style="color:#FF5722; text-decoration:none;">
support@yourdomain.com
</a>
<br><br>
The {{ config('app.name') }} Team
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>

View File

@@ -0,0 +1,383 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Invoice - Order #{{ $order->order_number }}</title>
<meta name="viewport" content="width=device-width,initial-scale=1">
<style>
/* Reset */
html,
body {
margin: 0;
padding: 0;
font-family: Arial, Helvetica, sans-serif;
color: #333
}
a {
color: inherit;
text-decoration: none
}
.container {
max-width: 900px;
margin: 24px auto;
padding: 20px;
border: 1px solid #e6e6e6;
border-radius: 8px;
background: #fff
}
header {
display: flex;
align-items: center;
justify-content: space-between;
gap: 16px;
margin-bottom: 18px
}
.brand {
display: flex;
align-items: center;
gap: 12px
}
.brand img {
height: 60px;
width: auto;
border-radius: 6px;
object-fit: contain
}
.brand h2 {
margin: 0;
font-size: 20px;
color: #111
}
.meta {
text-align: right;
font-size: 13px;
color: #666
}
.meta .title {
font-weight: 600;
color: #222
}
.section {
display: flex;
gap: 20px;
margin-bottom: 18px;
flex-wrap: wrap
}
.card {
flex: 1;
min-width: 220px;
padding: 14px;
border: 1px dashed #eee;
border-radius: 6px;
background: #fafafa
}
.card h4 {
margin: 0 0 8px 0;
font-size: 14px
}
.small {
font-size: 13px;
color: #555
}
table {
width: 100%;
border-collapse: collapse;
margin-top: 12px
}
th,
td {
padding: 10px 8px;
text-align: left;
border-bottom: 1px solid #f0f0f0;
font-size: 14px
}
th {
background: #fafafa;
font-weight: 600;
color: #333
}
td.right {
text-align: right
}
.muted {
color: #777;
font-size: 13px
}
.totals {
margin-top: 12px;
max-width: 360px;
margin-left: auto
}
.totals table {
border: none
}
.totals td {
border: none;
padding: 8px 6px
}
.grand {
font-weight: 700;
font-size: 18px
}
.status {
display: inline-block;
padding: 6px 10px;
border-radius: 20px;
font-size: 13px
}
.status.paid {
background: #e6ffef;
color: #046a2f;
border: 1px solid #c9f5d4
}
.status.unpaid {
background: #fff4e6;
color: #a65d00;
border: 1px solid #ffe7c7
}
.notes {
margin-top: 18px;
padding: 12px;
border-left: 4px solid #eee;
background: #fafafa;
border-radius: 4px;
color: #555
}
footer {
margin-top: 24px;
padding-top: 12px;
border-top: 1px solid #f0f0f0;
color: #777;
font-size: 13px;
text-align: center
}
.print-btn {
display: inline-block;
padding: 10px 14px;
border-radius: 6px;
background: #0b5ed7;
color: #fff;
font-weight: 600;
border: none;
cursor: pointer
}
/* Responsive */
@media (max-width:600px) {
header {
flex-direction: column;
align-items: flex-start
}
.meta {
text-align: left
}
.totals {
width: 100%;
margin: 12px 0 0 0
}
}
/* Print */
@media print {
body {
background: #fff
}
.container {
border: none;
box-shadow: none;
margin: 0;
padding: 0
}
.print-btn {
display: none
}
}
</style>
</head>
<body>
<div class="container">
<header>
<div class="brand">
@if (!empty($order->restaurant->logo))
<img src="{{ $order->restaurant->logo }}" alt="{{ $order->restaurant->name }}">
@endif
<div>
<h2>{{ $order->restaurant->name ?? 'Restaurant Name' }}</h2>
<div class="muted" style="margin-top:4px">{{ $order->restaurant->address ?? '' }}</div>
<div class="muted" style="margin-top:2px">Phone: {{ $order->restaurant->phone ?? 'N/A' }}</div>
</div>
</div>
<div class="meta">
<div class="title">Invoice</div>
<div style="margin-top:6px">Order #: <strong>{{ $order->order_number }}</strong></div>
<div style="margin-top:4px">Date:
<strong>{{ \Carbon\Carbon::parse($order->created_at)->format('d M, Y H:i') }}</strong>
</div>
<div style="margin-top:4px">
Status:
@if ($order->payment_status || ($order->payment_status === true || $order->payment_status == 1))
<span class="status paid">Paid</span>
@else
<span class="status unpaid">Unpaid</span>
@endif
</div>
</div>
</header>
<div class="section">
<div class="card">
<h4>Bill To</h4>
<div class="small"><strong>{{ $order->customer->name ?? 'Customer' }}</strong></div>
<div class="muted" style="margin-top:6px">
{{ $order->customer->email ?? '' }}<br>
{{ $order->customer->phone ?? '' }}<br>
{{ $order->shipping_address ?? '' }}
</div>
</div>
<div class="card">
<h4>Order Details</h4>
<div class="small"><strong>Type:</strong>
{{ ucfirst(str_replace('_', ' ', $order->order_type ?? 'N/A')) }}</div>
<div class="small" style="margin-top:6px"><strong>Waiter:</strong> {{ $order->waiter?->name ?? '-' }}
</div>
<div class="small" style="margin-top:6px"><strong>Table:</strong> {{ $order->table?->name ?? '-' }}
</div>
<div class="small" style="margin-top:6px"><strong>Payment:</strong>
{{ $order->payment_method?->name ?? ($order->payment_method_id ? 'Method' : 'N/A') }}</div>
</div>
</div>
<section>
<table>
<thead>
<tr>
<th style="width:48%">Item</th>
<th style="width:12%">Qty</th>
<th style="width:15%">Price</th>
<th style="width:25%" class="right">Total</th>
</tr>
</thead>
<tbody>
@foreach ($order->items as $item)
<tr>
<td>
<div style="font-weight:600">{{ $item->foodItem?->name ?? 'Item' }}</div>
@if (!empty($item->foodVariant))
<div class="muted" style="margin-top:4px;font-size:13px">Variant:
{{ $item->foodVariant->name }}</div>
@endif
@if (!empty($item->addons))
@php
$addons = is_string($item->addons)
? json_decode($item->addons, true)
: $item->addons;
@endphp
@if (!empty($addons) && is_array($addons))
<div class="muted" style="margin-top:6px;font-size:13px">
Addons:
@foreach ($addons as $a)
<span
style="display:inline-block;margin-right:6px">{{ $a['name'] ?? $a }}</span>
@endforeach
</div>
@endif
@endif
</td>
<td>{{ $item->quantity }}</td>
<td>{{ number_format($item->price, 2) }}</td>
<td class="right">{{ number_format($item->total, 2) }}</td>
</tr>
@endforeach
</tbody>
</table>
<div class="totals">
<table>
<tr>
<td class="muted">Subtotal</td>
<td class="right">{{ number_format($order->subtotal ?? 0, 2) }}</td>
</tr>
<tr>
<td class="muted">Discount</td>
<td class="right">- {{ number_format($order->discount ?? 0, 2) }}</td>
</tr>
<tr>
<td class="muted">Tax</td>
<td class="right">{{ number_format($order->tax ?? 0, 2) }}</td>
</tr>
@if (!empty($order->delivery_fee))
<tr>
<td class="muted">Delivery Fee</td>
<td class="right">{{ number_format($order->delivery_fee, 2) }}</td>
</tr>
@endif
<tr class="grand">
<td style="padding-top:8px">Grand Total</td>
<td class="right grand">
{{ number_format($order->grand_total ?? $order->subtotal - ($order->discount ?? 0) + ($order->tax ?? 0), 2) }}
</td>
</tr>
</table>
</div>
@if (!empty($order->note))
<div class="notes">
<strong>Note:</strong>
<div style="margin-top:6px">{{ $order->note }}</div>
</div>
@endif
<div
style="margin-top:18px;display:flex;justify-content:space-between;align-items:center;gap:10px;flex-wrap:wrap">
<div class="muted" style="font-size:13px">This is a computer generated invoice and does not require a
signature.</div>
<div style="text-align:right">
<button class="print-btn" onclick="window.print()">Print Invoice</button>
</div>
</div>
</section>
<footer>
{{ $order->restaurant->name ?? 'Restaurant Name' }} {{ $order->restaurant->website ?? '' }}
{{ $order->restaurant->email ?? '' }}
</footer>
</div>
</body>
</html>

View File

@@ -0,0 +1,96 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>New Support Ticket Created</title>
</head>
<body style="margin:0; padding:0; font-family:Arial, sans-serif; background-color:#f4f4f4;">
<table width="100%" cellpadding="0" cellspacing="0" bgcolor="#f4f4f4">
<tr>
<td align="center">
<table width="600" cellpadding="0" cellspacing="0" bgcolor="#ffffff"
style="margin:40px 0; border-radius:8px; overflow:hidden; box-shadow:0 0 10px rgba(0,0,0,0.1);">
<!-- Header -->
<tr>
<td style="background-color:#FF5722; padding:20px; text-align:center; color:#ffffff;">
<h1 style="margin:0; font-size:24px;">🛠 New Support Ticket Created</h1>
</td>
</tr>
<!-- Greeting -->
<tr>
<td style="padding:30px;">
<p style="font-size:16px; color:#333333;">
Hi <strong>{{ $ticket->name ?? 'User' }}</strong>,
</p>
<p style="font-size:16px; color:#333333;">
Your support ticket has been successfully created. Here are the details:
</p>
</td>
</tr>
<!-- Ticket Details -->
<tr>
<td style="padding:0 30px 30px 30px;">
<h2
style="font-size:18px; color:#FF5722; border-bottom:2px solid #FF5722; padding-bottom:5px;">
📌 Ticket Details</h2>
<table width="100%" cellpadding="5" cellspacing="0"
style="font-size:14px; color:#333333; border-collapse:collapse;">
<tr>
<td style="width:150px; font-weight:bold;">Title:</td>
<td>{{ $ticket->title }}</td>
</tr>
<tr>
<td style="width:150px; font-weight:bold;">Description:</td>
<td>{{ $ticket->description }}</td>
</tr>
<tr>
<td style="width:150px; font-weight:bold;">Category:</td>
<td>{{ $ticket->category->name ?? 'N/A' }}</td>
</tr>
<tr>
<td style="width:150px; font-weight:bold;">Purchase Code:</td>
<td>{{ $ticket->purchase_code ?? 'N/A' }}</td>
</tr>
<tr>
<td style="width:150px; font-weight:bold;">Related URL:</td>
<td>{{ $ticket->related_url ?? 'N/A' }}</td>
</tr>
<tr>
<td style="width:150px; font-weight:bold;">Support Plan:</td>
<td>{{ $ticket->support_plan ?? 'N/A' }}</td>
</tr>
</table>
</td>
</tr>
<!-- CTA Button -->
<tr>
<td style="padding:20px 30px; text-align:center;">
<a href="{{ url('/support-tickets/' . $ticket->id) }}"
style="display:inline-block; padding:15px 30px; background-color:#FF5722; color:#ffffff; text-decoration:none; font-size:16px; border-radius:5px;">
View Ticket
</a>
</td>
</tr>
<!-- Footer -->
<tr>
<td
style="padding:20px 30px; font-size:14px; color:#777777; text-align:center; background-color:#f4f4f4;">
Thanks,<br>
<strong>{{ config('app.name') }} Team</strong>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>

View File

@@ -0,0 +1,122 @@
@extends('install.layouts.master')
@section('title', _lang('install_requirements'))
@section('container')
<form action="{{ url('install/step-5') }}" method="GET" id="install-form">
@csrf
<div class="form-group">
<label for="username">{{ _lang('Envato Username') }}</label>
<input type="text" name="username" id="username" class="form-control" value="{{ old('username') }}"
placeholder="Envato username" required>
</div>
<div class="form-group">
<label for="purchase_key">{{ _lang('Purchase Key') }}</label>
<input type="text" name="purchase_key" id="purchase_key" class="form-control"
value="{{ old('purchase_key') }}" placeholder="Envato Item Purchase Code" required>
<span id="purchase_key-error" class="text-danger d-block mt-1"></span>
<div id="purchase_key-success" class="form-check mt-2 d-none">
<input class="form-check-input" type="checkbox" disabled checked>
<label class="form-check-label">{{ _lang('Purchase key is valid.') }}</label>
</div>
<button type="button" id="check-key" class="btn btn-sm btn-info mt-2">
{{ _lang('Check Purchase Key') }}
</button>
</div>
<div class="form-group text-right">
<button type="submit" id="next-button" class="btn btn-primary" style="display: none;" disabled>
{{ _lang('install_next') }}
</button>
</div>
</form>
@endsection
<script src="https://code.jquery.com/jquery-3.6.0.min.js"></script>
<script>
$(document).ready(function() {
function resetValidationState() {
$('#purchase_key').removeClass('is-valid is-invalid').prop('readonly', false);
$('#purchase_key-success').addClass('d-none');
$('#purchase_key-error').text('');
$('#next-button').hide().prop('disabled', true);
$('#check-key').show().prop('disabled', false).text('Check Purchase Key');
}
function showError(message) {
$('#purchase_key-error').text(message).show();
$('#purchase_key').addClass('is-invalid').removeClass('is-valid');
$('#purchase_key-success').addClass('d-none');
$('#next-button').hide().prop('disabled', true);
}
function showSuccess() {
$('#purchase_key-error').text('');
$('#purchase_key').removeClass('is-invalid').addClass('is-valid').prop('readonly', true);
$('#purchase_key-success').removeClass('d-none');
$('#check-key').hide();
$('#next-button').show().prop('disabled', false);
}
$('#check-key').on('click', function() {
const purchase_key = $('#purchase_key').val().trim();
const username = $('#username').val().trim();
if (!purchase_key || purchase_key.length !== 36) {
showError('Purchase key must be exactly 36 characters.');
return;
}
if (!username) {
showError('Envato username is required.');
return;
}
$('#purchase_key-error').text('');
$('#check-key').text('Checking...').prop('disabled', true);
$.ajax({
url: "{{ route('install.validate') }}",
method: 'POST',
data: {
_token: '{{ csrf_token() }}',
purchase_key,
username
},
success: function(response) {
if (response.status === 'success') {
showSuccess();
} else {
showError(response.message || 'Invalid purchase key.');
}
},
error: function(xhr) {
const msg = xhr.responseJSON?.message || 'Server error occurred.';
showError(msg);
},
complete: function() {
$('#check-key').text('Check Purchase Key').prop('disabled', false);
}
});
});
// Re-check logic if user edits the key after validation
$('#purchase_key').on('input', function() {
resetValidationState();
});
// Prevent form submission if not validated
$('#install-form').on('submit', function(e) {
if ($('#next-button').prop('disabled')) {
e.preventDefault();
alert('Please validate your purchase key first.');
}
});
});
</script>

View File

@@ -0,0 +1,16 @@
@extends('install.layouts.master')
@section('title', _lang('install_complete'))
@section('container')
<p class="paragraph mb-5">
Installation completed successfully, you can login now with default login details.
<br>Email: <strong>saasadmin@gmail.com</strong>
<br>Password: <strong>123456</strong>
</p>
<div class="d-flex justify-content-center mb-4">
<a href="{{ url('/login') }}" class="btn btn-warning">
{{ _lang('Login Page') }}
</a>
</div>
@endsection

View File

@@ -0,0 +1,54 @@
@extends('install.layouts.master')
@section('title', _lang('install_database'))
@section('container')
<form action="{{ url('install/database') }}" method="POST" name="form" enctype="multipart/form-data">
@csrf
@if ($errors->any())
<div class="alert alert-danger">
<ul>
@foreach ($errors->all() as $error)
<li>{{ $error }}</li>
@endforeach
</ul>
</div>
@endif
<div class="form-group">
<label for="software_name">{{ _lang('Software Name') }}</label>
<input type="text" name="software_name" id="software_name" class="form-control"
value="{{ old('software_name') }}" placeholder="Software Name" required>
</div>
<div class="form-group">
<label for="host">{{ _lang('install_host') }}</label>
<input type="text" name="host" id="host" class="form-control" value="127.0.0.1" required>
</div>
<div class="form-group">
<label for="username">{{ _lang('install_username') }}</label>
<input type="text" name="username" id="username" value="{{ old('username') }}" class="form-control"
required>
</div>
<div class="form-group">
<label for="password">{{ _lang('install_password') }}</label>
<input type="password" name="password" id="password" value="{{ old('password') }}" class="form-control">
</div>
<div class="form-group">
<label for="name">{{ _lang('install_name') }}</label>
<input type="text" name="name" id="name" class="form-control" value="{{ old('name') }}" required>
</div>
<div class="form-group">
<label for="port">{{ _lang('install_port') }}</label>
<input type="number" name="port" id="port" class="form-control" value="3306" required>
</div>
<div class="form-group">
<button type="submit" class="btn pull-right">{{ _lang('install_next') }}</button>
</div>
</form>
@endsection

View File

@@ -0,0 +1,67 @@
@extends('install.layouts.master')
@section('title', _lang('install_installation'))
<style>
.welcome-message {
background-color: #f9f9f9;
border: 1px solid #ddd;
padding: 20px;
margin-bottom: 20px;
border-radius: 5px;
}
.upgrade-highlights {
list-style-type: disc;
padding-left: 20px;
}
.upgrade-highlights li {
margin: 5px 0;
}
</style>
@section('container')
<div class="welcome-message">
<h1>{{ _lang('install_welcome') }}</h1>
<p class="paragraph">{{ _lang('install_msg') }}</p>
<p class="paragraph">
Install Upgrade Notice
<strong>Install New Features</strong>
Install Enjoy Improvements
</p>
<ul class="upgrade-highlights">
<li>
{{ _lang('Restaurant Management System') }}
</li>
<li>
{{ _lang('Staff Management System') }}
</li>
<li>
{{ _lang('Accounts & Financial Management') }}
</li>
<li>
{{ _lang('Authentication & Role-Based Permissions') }}
</li>
<li>
{{ _lang('Global Settings & Configurations') }}
</li>
<li>
{{ _lang('Notifications & SMS Module') }}
</li>
<li>
{{ _lang('HRM Management') }}
</li>
<li>
{{ _lang('Reports') }}
</li>
</ul>
</div>
<form action="{{ url('install/installation') }}" method="post" enctype="multipart/form-data">
@csrf
<div class="form-group">
<button type="submit" class="btn pull-right"> {{ _lang('install_install') }}</button>
</div>
</form>
@endsection

View File

@@ -0,0 +1,48 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>@yield('title')</title>
<!-- Tell the browser to be responsive to screen width -->
<meta content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no" name="viewport">
<!-- Bootstrap 3.3.6 -->
<link rel="stylesheet" href="{{ asset('assets/bootstrap/css/bootstrap.min.css') }}">
<link rel="stylesheet" href="{{ asset('assets/css/style.css') }}">
<!-- Theme style -->
<link href="{{ asset('assets/plugins/font-awesome/css/font-awesome.min.css') }}" rel="stylesheet" type="text/css" />
<!-- jQuery 2.2.3 -->
<script src="{{ asset('assets/plugins/jQuery/jquery-2.2.3.min.js') }}"></script>
<!-- Bootstrap 3.3.6 -->
<script src="{{ asset('assets/bootstrap/js/bootstrap.min.js') }}"></script>
<script src="{{ asset('assets/plugins/jQueryUI/jquery-ui.min.js') }}" type="text/javascript"></script>
</head>
<body class="master">
<div class="box">
<div class="header">
<h1 class="header__title">@yield('title')</h1>
</div>
<div class="main">
<div class="row">
<div class="col-md-12">
@if (Session::has('flash_notification.message'))
<div class="alert alert-{{ Session::get('flash_notification.level') }}">
{{ Session::get('flash_notification.message') }}
</div>
@endif
@yield('container')
</div>
</div>
</div>
</div>
@if (Session::has('flash_notification.message'))
<script>
toastr.{{ Session::get('flash_notification.level') }}('{{ Session::get('flash_notification.message') }}',
'Response Status')
</script>
@endif
</body>
</html>

View File

@@ -0,0 +1,28 @@
@extends('install.layouts.master')
@section('title', _lang('install_permissions'))
@section('container')
<ul class="list-group">
@foreach ($permissions as $path => $isWritable)
<li class="list-group-item">
{{ $path }}
@if ($isWritable)
<span class="badge badge1"><i class="fa fa-check"></i></span>
@else
<span class="badge badge2"><i class="fa fa-times"></i></span>
@endif
</li>
@endforeach
</ul>
<div class="form-group">
@if ($next)
<a href="{{ url('install/step-4') }}" class="btn pull-right"> {{ _lang('install_next') }}</a>
@else
<div class="alert alert-danger">{{ _lang('install_check') }}</div>
<a class="btn pull-right" href="{{ Request::url() }}">
{{ _lang('refresh') }}
<i class="fa fa-refresh"></i></a>
@endif
</div>
@endsection

View File

@@ -0,0 +1,28 @@
@extends('install.layouts.master')
@section('title', _lang('install_requirements'))
@section('container')
<ul class="list-group">
@foreach ($requirements as $extention => $enabled)
<li class="list-group-item">
{{ $extention }}
@if ($enabled)
<span class="badge badge1"><i class="fa fa-check"></i></span>
@else
<span class="badge badge2"><i class="fa fa-times"></i></span>
@endif
</li>
@endforeach
</ul>
<div class="form-group">
@if ($next)
<a href="{{ url('install/permissions') }}" class="btn pull-right">{{ _lang('install_next') }}</a>
@else
<div class="alert alert-danger">{{ _lang('install_check') }}</div>
<a class="btn pull-right" href="{{ Request::url() }}">
{{ _lang('refresh') }}
<i class="fa fa-refresh"></i></a>
@endif
</div>
@endsection

View File

@@ -0,0 +1,35 @@
@extends('install.layouts.master')
@section('title', _lang('start_install'))
@section('container')
<div class="form-group">
<h1 class="header_one">Mighty School Software Installation
</h1>
<hr>
<p class="paragraph_justify">
Please proceed step by step with proper data according to instructions</p>
<p class="paragraph_justify">
Before starting the installation process please collect this
information. Without this information, you wont be able to complete the installation process.
</p>
<div class="info-box">
<ul class="info-box_ul">
<li>
<strong> <span class="text-danger">Required *</span> </strong>
</li>
<li>
<strong> <span class="text_color"> Host Name </span> </strong>
</li>
<li>
<strong> <span class="text_color"> Database Name </span> </strong>
</li>
<li>
<strong> <span class="text_color"> Database Username </span> </strong>
</li>
<li>
<strong> <span class="text_color"> Database Password </span> </strong>
</li>
</ul>
</div>
<a href="{{ url('install/requirements') }}" class="btn pull-right">{{ _lang('install_next') }}</a>
</div>
@endsection

View File

@@ -0,0 +1,60 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>{{ 'Payment' }}</title>
<link rel="stylesheet" href="{{ asset('assets/bootstrap-5/bootstrap.min.css') }}">
@stack('script')
<style>
body {
margin: 0;
padding: 0;
height: 100vh;
background: #f4f4f9;
display: flex;
align-items: center;
justify-content: center;
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
}
.loader-container {
text-align: center;
}
.loader {
border: 8px solid #e0e0e0;
border-top: 8px solid #4A90E2;
border-radius: 50%;
width: 60px;
height: 60px;
animation: spin 1s linear infinite;
margin: 0 auto 20px;
}
@keyframes spin {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
h1 {
color: #333;
font-size: 1.5rem;
}
</style>
</head>
<body>
@yield('content')
<script src="{{ asset('assets/bootstrap-5/bootstrap.bundle.min.js') }}"></script>
</body>
</html>

View File

@@ -0,0 +1,226 @@
<!DOCTYPE html>
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
<head>
<meta charset="utf-8">
<title>
@yield('title')
</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="stylesheet" type="text/css" href="{{ asset('assets/modules/payment/mercado_pogo/css/bootstrap.min.css') }}">
<link rel="stylesheet" type="text/css" href="{{ asset('assets/modules/payment/mercado_pogo/css/index.css') }}">
<script src="{{ asset('assets/admin-module/js/jquery-3.6.0.min.js') }}"></script>
<script src="https://sdk.mercadopago.com/js/v2"></script>
</head>
<body>
<main>
<!-- Hidden input to store your integration public key -->
<input type="hidden" id="mercado-pago-public-key" value="{{ $config->public_key }}">
<!-- Payment -->
<section class="payment-form dark">
<div class="container__payment">
<div class="block-heading">
<h2>Card Payment</h2>
<!-- <p>This is an example of a Mercado Pago integration</p> -->
</div>
<div class="form-payment">
<div class="products">
<p class="alert alert-danger d-none" role="alert" id="error_alert"></p>
<div class="total">Amount to be paid {{ $data->currency_code }}<span
class="price">{{ $data->payment_amount }}</span></div>
</div>
<div class="payment-details">
<form id="form-checkout">
<h3 class="title">Buyer Details</h3>
<div class="row">
<div class="form-group col">
<input id="form-checkout__cardholderEmail" name="cardholderEmail" type="email"
class="form-control" />
</div>
</div>
<div class="row">
<div class="form-group col-sm-5">
<select id="form-checkout__identificationType" name="identificationType"
class="form-control"></select>
</div>
<div class="form-group col-sm-7">
<input id="form-checkout__identificationNumber" name="docNumber" type="text"
class="form-control" />
</div>
</div>
<br>
<h3 class="title">Card Details</h3>
<div class="row">
<div class="form-group col-sm-8">
<input id="form-checkout__cardholderName" name="cardholderName" type="text"
class="form-control" />
</div>
<div class="form-group col-sm-4">
<div class="input-group expiration-date">
<input id="form-checkout__cardExpirationMonth" name="cardExpirationMonth"
type="text" class="form-control" />
<span class="date-separator">/</span>
<input id="form-checkout__cardExpirationYear" name="cardExpirationYear"
type="text" class="form-control" />
</div>
</div>
<div class="form-group col-sm-8">
<input id="form-checkout__cardNumber" name="cardNumber" type="text"
class="form-control" />
</div>
<div class="form-group col-sm-4">
<input id="form-checkout__securityCode" name="securityCode" type="text"
class="form-control" />
</div>
<div id="issuerInput" class="form-group col-sm-12 hidden">
<select id="form-checkout__issuer" name="issuer" class="form-control"></select>
</div>
<div class="form-group col-sm-12">
<select id="form-checkout__installments" name="installments" type="text"
class="form-control"></select>
</div>
<div class="form-group col-sm-12">
<br>
<button id="form-checkout__submit" type="submit"
class="btn btn--primary btn-block">Pay</button>
<br>
<p id="loading-message">Loading, please wait...</p>
<br>
</div>
</div>
</form>
</div>
</div>
</div>
</section>
</main>
</body>
<script>
"use strict";
const publicKey = document.getElementById("mercado-pago-public-key").value;
const mercadopago = new MercadoPago(publicKey);
loadCardForm();
function loadCardForm() {
const productCost = '{{ $data->payment_amount }}';
const cardForm = mercadopago.cardForm({
amount: productCost,
autoMount: true,
form: {
id: "form-checkout",
cardholderName: {
id: "form-checkout__cardholderName",
placeholder: "Card holder name",
},
cardholderEmail: {
id: "form-checkout__cardholderEmail",
placeholder: "Card holder email",
},
cardNumber: {
id: "form-checkout__cardNumber",
placeholder: "Card number",
},
cardExpirationMonth: {
id: "form-checkout__cardExpirationMonth",
placeholder: "MM",
},
cardExpirationYear: {
id: "form-checkout__cardExpirationYear",
placeholder: "YY",
},
securityCode: {
id: "form-checkout__securityCode",
placeholder: "Security code",
},
installments: {
id: "form-checkout__installments",
placeholder: "Installments",
},
identificationType: {
id: "form-checkout__identificationType",
},
identificationNumber: {
id: "form-checkout__identificationNumber",
placeholder: "Identification number",
},
issuer: {
id: "form-checkout__issuer",
placeholder: "Issuer",
},
},
callbacks: {
onFormMounted: error => {
if (error)
return console.warn("Form Mounted handling error: ", error);
},
onSubmit: event => {
event.preventDefault();
document.getElementById("loading-message").style.display = "block";
const {
paymentMethodId,
issuerId,
cardholderEmail: email,
amount,
token,
installments,
identificationNumber,
identificationType,
} = cardForm.getCardFormData();
fetch("{{ route('mercadopago.make_payment', ['payment_id' => $data->id]) }}", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-CSRF-TOKEN": "{{ csrf_token() }}"
},
body: JSON.stringify({
token,
issuerId,
paymentMethodId,
transactionAmount: Number(amount),
installments: Number(installments),
payer: {
email,
identification: {
type: identificationType,
number: identificationNumber,
},
},
}),
})
.then(response => {
return response.json();
})
.then(result => {
if (result.error) {
document.getElementById("loading-message").style.display = "none";
document.getElementById("error_alert").innerText = result.error;
document.getElementById("error_alert").style.display = "block";
return false;
}
location.href = '{{ route('payment-success') }}';
})
.catch(error => {
document.getElementById("loading-message").style.display = "none";
document.getElementById("error_alert").innerHtml = error;
document.getElementById("error_alert").style.display = "block";
});
},
onFetching: (resource) => {
const payButton = document.getElementById("form-checkout__submit");
payButton.setAttribute('disabled', true);
return () => {
payButton.removeAttribute("disabled");
};
},
},
});
}
</script>
</html>

View File

@@ -0,0 +1,35 @@
@extends('payment.layouts.master')
@section('content')
<center>
<div class="loader"></div>
</center>
<form method="POST" action="{!! route('paystack.payment', ['token' => $data->id]) !!}" accept-charset="UTF-8" class="form-horizontal" role="form">
@csrf
<div class="row">
<div class="col-md-8 col-md-offset-2">
<input type="hidden" name="email"
value="{{ $payer->email != null ? $payer->email : 'required@email.com' }}">
{{-- required --}}
<input type="hidden" name="orderID" value="{{ $data->attribute_id }}">
<input type="hidden" name="amount" value="{{ $data->payment_amount * 100 }}"> {{-- required in kobo --}}
<input type="hidden" name="quantity" value="1">
<input type="hidden" name="currency" value="{{ $data->currency_code }}">
<input type="hidden" name="metadata" value="{{ json_encode($array = ['key_name' => 'value']) }}">
{{-- For other necessary things you want to add to your payload. it is optional though --}}
<input type="hidden" name="reference" value="{{ $reference }}"> {{-- required --}}
<button class="btn btn-block d-none" id="pay-button" type="submit"></button>
</div>
</div>
</form>
<script type="text/javascript">
"use strict";
document.addEventListener("DOMContentLoaded", function() {
document.getElementById("pay-button").click();
});
</script>
@endsection

View File

@@ -0,0 +1,28 @@
@extends('payment.layouts.master')
@push('script')
@endpush
@section('content')
<center>
<div class="loader"></div>
</center>
<form method="post" action="<?php echo \Illuminate\Support\Facades\Config::get('paytm_config.PAYTM_TXN_URL'); ?>" id="form">
<table border="1">
<tbody>
@foreach ($paramList as $name => $value)
<input type="hidden" name="{{ $name }}" value="{{ $value }}">
@endforeach
<input type="hidden" name="CHECKSUMHASH" value="{{ $checkSum }}">
</tbody>
</table>
</form>
<script type="text/javascript">
"use strict";
document.addEventListener("DOMContentLoaded", function() {
document.getElementById("form").submit();
});
</script>
@endsection

View File

@@ -0,0 +1,44 @@
@extends('payment.layouts.master')
@section('content')
<center>
<div class="loader"></div>
</center>
<form action="{!! route('razor-pay.payment', ['payment_id' => $data->id]) !!}" id="form" method="POST">
@csrf
<script src="https://checkout.razorpay.com/v1/checkout.js" data-key="{{ config()->get('razor_config.api_key') }}"
data-amount="{{ round($data->payment_amount, 2) * 100 }}"
data-buttontext="Pay {{ round($data->payment_amount, 2) . ' ' . $data->currency_code }}"
data-name="{{ $business_name }}" data-description="{{ $data->payment_amount }}" data-image="{{ $business_logo }}"
data-prefill.name="{{ $data->name ?? '' }}" data-prefill.email="{{ $data->email ?? '' }}"
data-prefill.contact="{{ $data?->phone ?? '' }}"
data-callback_url="{{ route('razor-pay.callback', ['payment_data' => base64_encode($data->id)]) }}"
data-theme.color="#ff7529"></script>
<button class="btn btn-block" id="pay-button" type="submit" style="display:none"></button>
<button class="razorpay-cancel-button" type="button" id="cancel-button" onclick="handleCancel()">Cancel</button>
</form>
<script type="text/javascript">
"use strict";
document.addEventListener("DOMContentLoaded", function() {
document.getElementById("pay-button").click();
});
function handleCancel() {
window.location.href = '{{ route('razor-pay.cancel', ['payment_id' => $data->id]) }}';
}
</script>
@endsection
@push('script')
<style>
.razorpay-cancel-button {
border: 1px solid #0000008c;
border-radius: 2px;
margin: 0;
font-size: 16px;
padding: .125rem 1rem;
}
</style>
@endpush

View File

@@ -0,0 +1,33 @@
@extends('payment.layouts.master')
@push('script')
<script src="https://polyfill.io/v3/polyfill.min.js?version=3.52.1&features=fetch"></script>
<script src="https://js.stripe.com/v3/"></script>
@endpush
@section('content')
<center>
<div class="loader"></div>
</center>
<script type="text/javascript">
var stripe = Stripe('{{ $config['published_key'] }}');
document.addEventListener("DOMContentLoaded", function() {
fetch("{{ url("payment/stripe/token/?payment_id={$data->id}") }}", {
method: "GET",
}).then(function(response) {
return response.text();
}).then(function(session) {
return stripe.redirectToCheckout({
sessionId: JSON.parse(session).id
});
}).then(function(result) {
if (result.error) {
alert(result.error.message);
}
}).catch(function(error) {
console.error("error:", error);
});
});
</script>
@endsection

View File

@@ -0,0 +1,237 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Create Restaurant Account | Mighty</title>
<!-- Favicon -->
<link rel="shortcut icon" href="{{ asset('favicon.png') }}" />
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet">
<style>
body {
background-color: #f5f7fb;
font-family: "Noto Sans", sans-serif;
}
.card {
border: none;
border-radius: 12px;
}
.btn-register {
background-color: #ffc107;
color: #000;
font-weight: 600;
}
.btn-register:hover {
background-color: #ffca2c;
color: #000;
}
label {
font-weight: 500;
}
.form-control,
.form-select {
border-radius: 8px;
}
.form-section {
background-color: #fff;
border-radius: 12px;
box-shadow: 0 4px 20px rgba(0, 0, 0, 0.05);
}
.logo {
text-align: center;
margin-bottom: 15px;
}
.logo img {
width: 90px;
}
.form-title {
text-align: center;
font-size: 20px;
font-weight: 600;
margin-bottom: 25px;
}
</style>
</head>
<body>
<div class="container py-5">
<div class="row justify-content-center">
<div class="col-lg-8">
<div class="form-section p-4">
<div class="logo">
<img src="{{ asset('backend_assets/logo/logo.png') }}" alt="Logo" style="height:100px;">
</div>
<h4 class="form-title">Create Your Restaurant Account</h4>
@if (session('success'))
<div class="alert alert-success">{{ session('success') }}</div>
@endif
<form action="{{ route('public.onboarding.store') }}" method="POST" enctype="multipart/form-data">
@csrf
<div class="row g-3">
<!-- Owner Name -->
<div class="col-md-6">
<label class="form-label">Owner Name <span class="text-danger">*</span></label>
<input type="text" name="name" value="{{ old('name') }}"
class="form-control @error('name') is-invalid @enderror"
placeholder="Owner Full Name" required>
@error('name')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<!-- Owner Email -->
<div class="col-md-6">
<label class="form-label">Owner Email <span class="text-danger">*</span></label>
<input type="email" name="email" value="{{ old('email') }}"
class="form-control @error('email') is-invalid @enderror" placeholder="Owner Email"
required>
@error('email')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<!-- Owner Phone -->
<div class="col-md-6">
<label class="form-label">Owner Phone <span class="text-danger">*</span></label>
<input type="text" name="phone" value="{{ old('phone') }}"
class="form-control @error('phone') is-invalid @enderror" placeholder="Owner Phone"
required>
@error('phone')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<!-- Owner Avatar -->
<div class="col-md-6">
<label class="form-label">Owner Avatar</label>
<input type="file" name="avatar"
class="form-control @error('avatar') is-invalid @enderror">
@error('avatar')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<!-- Restaurant Name -->
<div class="col-md-6">
<label class="form-label">Restaurant Name <span class="text-danger">*</span></label>
<input type="text" name="restaurant_name" value="{{ old('restaurant_name') }}"
class="form-control @error('restaurant_name') is-invalid @enderror"
placeholder="Restaurant Name" required>
@error('restaurant_name')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<!-- Restaurant Email -->
<div class="col-md-6">
<label class="form-label">Restaurant Email <span class="text-danger">*</span></label>
<input type="email" name="restaurant_email" value="{{ old('restaurant_email') }}"
class="form-control @error('restaurant_email') is-invalid @enderror"
placeholder="Restaurant Email" required>
@error('restaurant_email')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<!-- Restaurant Phone -->
<div class="col-md-6">
<label class="form-label">Restaurant Phone <span class="text-danger">*</span></label>
<input type="text" name="restaurant_phone" value="{{ old('restaurant_phone') }}"
class="form-control @error('restaurant_phone') is-invalid @enderror"
placeholder="Restaurant Phone" required>
@error('restaurant_phone')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<!-- Restaurant Domain -->
<div class="col-md-6">
<label class="form-label">Restaurant Domain</label>
<input type="text" name="restaurant_domain" value="{{ old('restaurant_domain') }}"
class="form-control @error('restaurant_domain') is-invalid @enderror"
placeholder="myrestaurant.com">
@error('restaurant_domain')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<!-- Restaurant Type -->
<div class="col-md-6">
<label class="form-label">Restaurant Type</label>
<input type="text" name="restaurant_type" value="{{ old('restaurant_type') }}"
class="form-control @error('restaurant_type') is-invalid @enderror"
placeholder="Restaurant, Cafe, etc.">
@error('restaurant_type')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<!-- Restaurant Address -->
<div class="col-md-12">
<label class="form-label">Restaurant Address</label>
<textarea name="restaurant_address" rows="2"
class="form-control @error('restaurant_address') is-invalid @enderror" placeholder="Full Address">{{ old('restaurant_address') }}</textarea>
@error('restaurant_address')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<!-- Restaurant Logo -->
<div class="col-md-6">
<label class="form-label">Restaurant Logo</label>
<input type="file" name="restaurant_logo"
class="form-control @error('restaurant_logo') is-invalid @enderror">
@error('restaurant_logo')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<!-- Password -->
<div class="col-md-6">
<label class="form-label">Password <span class="text-danger">*</span></label>
<input type="password" name="password"
class="form-control @error('password') is-invalid @enderror"
placeholder="Password" required>
@error('password')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<!-- Confirm Password -->
<div class="col-md-6">
<label class="form-label">Confirm Password <span class="text-danger">*</span></label>
<input type="password" name="password_confirmation"
class="form-control @error('password_confirmation') is-invalid @enderror"
placeholder="Confirm Password" required>
@error('password_confirmation')
<div class="invalid-feedback">{{ $message }}</div>
@enderror
</div>
<div class="col-12 text-center mt-3">
<button type="submit" class="btn btn-register px-5 py-2">Apply for
Restaurant</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,114 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Mighty | Restaurant SaaS</title>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- Tailwind CSS CDN -->
<script src="https://cdn.tailwindcss.com"></script>
<style>
body {
font-family: 'Inter', sans-serif;
}
</style>
</head>
<body class="bg-gray-50 text-gray-800">
<!-- Navbar -->
<nav class="bg-white shadow-sm">
<div class="max-w-7xl mx-auto px-6 py-4 flex justify-between items-center">
<h1 class="text-2xl font-bold text-orange-600">RestaurantSaaS</h1>
<div class="space-x-4">
<a href="#" class="text-gray-600 hover:text-orange-600">Features</a>
<a href="#" class="text-gray-600 hover:text-orange-600">Pricing</a>
</div>
</div>
</nav>
<!-- Hero Section -->
<section class="bg-gradient-to-r from-orange-500 to-red-500 text-white">
<div class="max-w-7xl mx-auto px-6 py-20 text-center">
<h2 class="text-4xl md:text-5xl font-extrabold mb-6">
Welcome to Restaurant SaaS Platform
</h2>
<p class="text-lg md:text-xl mb-8 max-w-3xl mx-auto">
Manage orders, deliveries, riders, payments, and customers from one powerful dashboard.
Built for modern restaurants.
</p>
<div class="flex justify-center gap-4">
<a href="#"
class="bg-white text-orange-600 font-semibold px-8 py-3 rounded-lg shadow hover:bg-gray-100 transition">
Get Started
</a>
<a href="#"
class="border border-white px-8 py-3 rounded-lg font-semibold hover:bg-white hover:text-orange-600 transition">
Request Demo
</a>
</div>
</div>
</section>
<!-- Features -->
<section class="py-16">
<div class="max-w-7xl mx-auto px-6">
<h3 class="text-3xl font-bold text-center mb-12">
Everything You Need to Run Your Restaurant
</h3>
<div class="grid grid-cols-1 md:grid-cols-3 gap-8">
<div class="bg-white p-8 rounded-xl shadow hover:shadow-lg transition">
<h4 class="text-xl font-semibold mb-4">Order Management</h4>
<p class="text-gray-600">
Track, process, and manage customer orders in real-time with smart automation.
</p>
</div>
<div class="bg-white p-8 rounded-xl shadow hover:shadow-lg transition">
<h4 class="text-xl font-semibold mb-4">Delivery & Riders</h4>
<p class="text-gray-600">
Assign riders, live-track deliveries, and optimize routes effortlessly.
</p>
</div>
<div class="bg-white p-8 rounded-xl shadow hover:shadow-lg transition">
<h4 class="text-xl font-semibold mb-4">Reports & Analytics</h4>
<p class="text-gray-600">
Get powerful insights on sales, performance, and customer behavior.
</p>
</div>
</div>
</div>
</section>
<!-- Call to Action -->
<section class="bg-orange-600 text-white py-16">
<div class="max-w-7xl mx-auto px-6 text-center">
<h3 class="text-3xl font-bold mb-6">
Ready to Grow Your Restaurant?
</h3>
<p class="mb-8 text-lg">
Join hundreds of restaurants using our SaaS to scale faster and smarter.
</p>
<a href="#"
class="bg-white text-orange-600 px-10 py-4 rounded-lg font-semibold shadow hover:bg-gray-100 transition">
Start Free Trial
</a>
</div>
</section>
<!-- Footer -->
<footer class="bg-gray-900 text-gray-400 py-8">
<div class="max-w-7xl mx-auto px-6 text-center">
<p>
© {{ date('Y') ?? '2026' }} RestaurantSaaS. All rights reserved.
</p>
</div>
</footer>
</body>
</html>