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,187 @@
<?php
namespace Modules\Frontend\Repositories;
use App\Abstracts\EntityRepository;
use Exception;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder;
use Modules\Frontend\Models\AboutUs;
use Symfony\Component\HttpFoundation\Response;
class AboutUsRepository extends EntityRepository
{
public string $table = AboutUs::TABLE_NAME;
protected array $fillableColumns = [
'restaurant_id',
'title',
'description',
'image',
'status',
'created_by',
'created_at',
'updated_at',
];
protected function getQuery(): Builder
{
return parent::getQuery();
}
public function getAll(array $filterData = []): Paginator
{
$filter = $this->getFilterData($filterData);
$query = $this->getAboutUsQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
if (isset($filter['search']) && strlen($filter['search']) > 0) {
$query = $this->filterSearchQuery($query, $filter['search']);
}
return $query
->orderBy($filter['orderBy'], $filter['order'])
->paginate($filter['perPage']);
}
protected function getFilterData(array $filterData = []): array
{
$defaultArgs = [
'perPage' => 10,
'search' => '',
'orderBy' => 'id',
'order' => 'desc',
'with_deleted' => false,
];
return array_merge($defaultArgs, $filterData);
}
private function getAboutUsQuery(): Builder
{
return $this->getQuery()
->select(
'about_us.id',
'about_us.restaurant_id',
'about_us.title',
'about_us.description',
'about_us.image',
'about_us.status',
'about_us.created_at',
);
}
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
{
$searchable = "%$searchedText%";
return $query->where('about_us.question', 'LIKE', $searchable)
->orWhere('about_us.title', 'LIKE', $searchable)
->orWhere('about_us.description', 'LIKE', $searchable)
->orWhere('about_us.status', 'LIKE', $searchable);
}
/**
* @throws Exception
*/
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
{
$user = $this->getAboutUsQuery()
->where($columnName, $columnValue)
->first();
if (empty($user)) {
throw new Exception(
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
Response::HTTP_NOT_FOUND
);
}
return $user;
}
public function getCount(array $filterData = []): int
{
$filter = $this->getFilterData($filterData);
$query = $this->getQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
return $query->count();
}
/**
* @throws Exception
*/
public function create(array $data): object
{
try {
$data = $this->prepareForDB($data);
$userId = $this->getQuery()->insertGetId($data);
$user = AboutUs::find($userId);
return $user;
} catch (Exception $exception) {
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* @throws Exception
*/
public function prepareForDB(array $data, ?object $item = null): array
{
$data = parent::prepareForDB($data, $item);
if (empty($item)) {
$data['created_at'] = now();
$data['restaurant_id'] = $this->getCurrentRestaurantId();
$data['status'] = 1;
if (! empty($data['image']) && $data['image'] instanceof \Illuminate\Http\UploadedFile) {
$data['image'] = fileUploader('about_us/', 'png', $data['image']);
}
} else {
$data['updated_at'] = now();
if (! empty($data['image']) && $data['image'] instanceof \Illuminate\Http\UploadedFile) {
$data['image'] = fileUploader('about_us/', 'png', $data['image'], $item->image);
}
}
return $data;
}
/**
* @throws Exception
*/
public function update(int $id, array $data): ?object
{
try {
$user = AboutUs::find($id);
$data = $this->prepareForDB($data, $user);
parent::update($id, $data);
return $this->getById($id);
} catch (Exception $exception) {
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
protected function getExceptionMessages(): array
{
$exceptionMessages = parent::getExceptionMessages();
$userExceptionMessages = [
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'AboutUs does not exist.',
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'AboutUs could not be deleted.',
];
return array_merge($exceptionMessages, $userExceptionMessages);
}
}

View File

@@ -0,0 +1,189 @@
<?php
namespace Modules\Frontend\Repositories;
use App\Abstracts\EntityRepository;
use Exception;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder;
use Modules\Frontend\Models\AcademicImage;
use Symfony\Component\HttpFoundation\Response;
class AcademicImageRepository extends EntityRepository
{
public string $table = AcademicImage::TABLE_NAME;
protected array $fillableColumns = [
'restaurant_id',
'title',
'heading',
'description',
'image',
'status',
'created_by',
'created_at',
'updated_at',
];
protected function getQuery(): Builder
{
return parent::getQuery();
}
public function getAll(array $filterData = []): Paginator
{
$filter = $this->getFilterData($filterData);
$query = $this->getAcademicImageQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
if (isset($filter['search']) && strlen($filter['search']) > 0) {
$query = $this->filterSearchQuery($query, $filter['search']);
}
return $query
->orderBy($filter['orderBy'], $filter['order'])
->paginate($filter['perPage']);
}
protected function getFilterData(array $filterData = []): array
{
$defaultArgs = [
'perPage' => 10,
'search' => '',
'orderBy' => 'id',
'order' => 'desc',
'with_deleted' => false,
];
return array_merge($defaultArgs, $filterData);
}
private function getAcademicImageQuery(): Builder
{
return $this->getQuery()
->select(
'academic_images.id',
'academic_images.restaurant_id',
'academic_images.title',
'academic_images.heading',
'academic_images.description',
'academic_images.image',
'academic_images.status',
'academic_images.created_at',
);
}
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
{
$searchable = "%$searchedText%";
return $query->where('academic_images.question', 'LIKE', $searchable)
->orWhere('academic_images.title', 'LIKE', $searchable)
->orWhere('academic_images.heading', 'LIKE', $searchable)
->orWhere('academic_images.status', 'LIKE', $searchable);
}
/**
* @throws Exception
*/
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
{
$user = $this->getAcademicImageQuery()
->where($columnName, $columnValue)
->first();
if (empty($user)) {
throw new Exception(
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
Response::HTTP_NOT_FOUND
);
}
return $user;
}
public function getCount(array $filterData = []): int
{
$filter = $this->getFilterData($filterData);
$query = $this->getQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
return $query->count();
}
/**
* @throws Exception
*/
public function create(array $data): object
{
try {
$data = $this->prepareForDB($data);
$userId = $this->getQuery()->insertGetId($data);
$user = AcademicImage::find($userId);
return $user;
} catch (Exception $exception) {
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* @throws Exception
*/
public function prepareForDB(array $data, ?object $item = null): array
{
$data = parent::prepareForDB($data, $item);
if (empty($item)) {
$data['created_at'] = now();
$data['created_by'] = $this->getCurrentUserId();
$data['restaurant_id'] = $this->getCurrentRestaurantId();
$data['status'] = 1;
if (! empty($data['image']) && $data['image'] instanceof \Illuminate\Http\UploadedFile) {
$data['image'] = fileUploader('academic_images/', 'png', $data['image']);
}
} else {
$data['updated_at'] = now();
if (! empty($data['image']) && $data['image'] instanceof \Illuminate\Http\UploadedFile) {
$data['image'] = fileUploader('academic_images/', 'png', $data['image'], $item->image);
}
}
return $data;
}
/**
* @throws Exception
*/
public function update(int $id, array $data): ?object
{
try {
$user = AcademicImage::find($id);
$data = $this->prepareForDB($data, $user);
parent::update($id, $data);
return $this->getById($id);
} catch (Exception $exception) {
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
protected function getExceptionMessages(): array
{
$exceptionMessages = parent::getExceptionMessages();
$userExceptionMessages = [
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'AcademicImage does not exist.',
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'AcademicImage could not be deleted.',
];
return array_merge($exceptionMessages, $userExceptionMessages);
}
}

View File

@@ -0,0 +1,189 @@
<?php
namespace Modules\Frontend\Repositories;
use App\Abstracts\EntityRepository;
use Exception;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder;
use Modules\Frontend\Models\Banner;
use Symfony\Component\HttpFoundation\Response;
class BannerRepository extends EntityRepository
{
public string $table = Banner::TABLE_NAME;
protected array $fillableColumns = [
'restaurant_id',
'title',
'description',
'button_name',
'button_link',
'image',
'status',
'created_by',
'created_at',
'updated_at',
];
protected function getQuery(): Builder
{
return parent::getQuery();
}
public function getAll(array $filterData = []): Paginator
{
$filter = $this->getFilterData($filterData);
$query = $this->getBannerQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
if (isset($filter['search']) && strlen($filter['search']) > 0) {
$query = $this->filterSearchQuery($query, $filter['search']);
}
return $query
->orderBy($filter['orderBy'], $filter['order'])
->paginate($filter['perPage']);
}
protected function getFilterData(array $filterData = []): array
{
$defaultArgs = [
'perPage' => 10,
'search' => '',
'orderBy' => 'id',
'order' => 'desc',
'with_deleted' => false,
];
return array_merge($defaultArgs, $filterData);
}
private function getBannerQuery(): Builder
{
return $this->getQuery()
->select(
'banners.id',
'banners.restaurant_id',
'banners.title',
'banners.description',
'banners.button_name',
'banners.button_link',
'banners.image',
'banners.status',
'banners.created_at'
);
}
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
{
$searchable = "%$searchedText%";
return $query->where('banners.first_name', 'LIKE', $searchable)
->orWhere('banners.title', 'LIKE', $searchable)
->orWhere('banners.status', 'LIKE', $searchable);
}
/**
* @throws Exception
*/
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
{
$user = $this->getBannerQuery()
->where($columnName, $columnValue)
->first();
if (empty($user)) {
throw new Exception(
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
Response::HTTP_NOT_FOUND
);
}
return $user;
}
public function getCount(array $filterData = []): int
{
$filter = $this->getFilterData($filterData);
$query = $this->getQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
return $query->count();
}
/**
* @throws Exception
*/
public function create(array $data): object
{
try {
$data = $this->prepareForDB($data);
$userId = $this->getQuery()->insertGetId($data);
$user = Banner::find($userId);
return $user;
} catch (Exception $exception) {
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* @throws Exception
*/
public function prepareForDB(array $data, ?object $item = null): array
{
$data = parent::prepareForDB($data, $item);
if (empty($item)) {
$data['created_at'] = now();
$data['restaurant_id'] = $this->getCurrentRestaurantId();
$data['status'] = 1;
if (! empty($data['image']) && $data['image'] instanceof \Illuminate\Http\UploadedFile) {
$data['image'] = fileUploader('banners/', 'png', $data['image']);
}
} else {
$data['updated_at'] = now();
if (! empty($data['image']) && $data['image'] instanceof \Illuminate\Http\UploadedFile) {
$data['image'] = fileUploader('banners/', 'png', $data['image'], $item->image);
}
}
return $data;
}
/**
* @throws Exception
*/
public function update(int $id, array $data): ?object
{
try {
$user = Banner::find($id);
$data = $this->prepareForDB($data, $user);
parent::update($id, $data);
return $this->getById($id);
} catch (Exception $exception) {
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
protected function getExceptionMessages(): array
{
$exceptionMessages = parent::getExceptionMessages();
$userExceptionMessages = [
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'Banner does not exist.',
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'Banner could not be deleted.',
];
return array_merge($exceptionMessages, $userExceptionMessages);
}
}

View File

@@ -0,0 +1,178 @@
<?php
namespace Modules\Frontend\Repositories;
use App\Abstracts\EntityRepository;
use Exception;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder;
use Modules\Frontend\Models\CMSSection;
use Symfony\Component\HttpFoundation\Response;
class CMSSectionRepository extends EntityRepository
{
public string $table = CMSSection::TABLE_NAME;
protected array $fillableColumns = [
'restaurant_id',
'name',
'serial',
'title',
'description',
'image',
'status',
'created_at',
'updated_at',
'deleted_at',
];
protected function getQuery(): Builder
{
return parent::getQuery();
}
protected function getFilterData(array $filterData = []): array
{
$defaultArgs = [
'perPage' => 10,
'search' => '',
'orderBy' => 'id',
'order' => 'desc',
'with_deleted' => false,
];
return array_merge($defaultArgs, $filterData);
}
private function getCMSSectionQuery(): Builder
{
return $this->getQuery()
->select(
"{$this->table}.id",
"{$this->table}.restaurant_id",
"{$this->table}.name",
"{$this->table}.serial",
"{$this->table}.title",
"{$this->table}.description",
"{$this->table}.image",
"{$this->table}.status",
"{$this->table}.created_at",
"{$this->table}.deleted_at"
);
}
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
{
$searchable = "%$searchedText%";
return $query->where("{$this->table}.name", 'LIKE', $searchable)
->orWhere("{$this->table}.status", 'LIKE', $searchable);
}
public function getAll(array $filterData = []): Paginator
{
$filter = $this->getFilterData($filterData);
$query = $this->getCMSSectionQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
if (! empty($filter['search'])) {
$query = $this->filterSearchQuery($query, $filter['search']);
}
return $query
->orderBy($filter['orderBy'], $filter['order'])
->paginate($filter['perPage']);
}
public function getCount(array $filterData = []): int
{
$filter = $this->getFilterData($filterData);
$query = $this->getQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
return $query->count();
}
/**
* @throws Exception
*/
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
{
$item = $this->getCMSSectionQuery()
->where($columnName, $columnValue)
->first($selects);
if (empty($item)) {
throw new Exception(
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
Response::HTTP_NOT_FOUND
);
}
return $item;
}
/**
* @throws Exception
*/
public function create(array $data): object
{
$data = $this->prepareForDB($data);
$id = $this->getQuery()->insertGetId($data);
return CMSSection::find($id);
}
/**
* @throws Exception
*/
public function update(int $id, array $data): object
{
$item = CMSSection::findOrFail($id);
$data = $this->prepareForDB($data, $item);
parent::update($id, $data);
return $this->getById($id);
}
/**
* @throws Exception
*/
public function prepareForDB(array $data, ?object $item = null): array
{
$data = parent::prepareForDB($data, $item);
if (empty($item)) {
$data['created_at'] = now();
$data['restaurant_id'] = $this->getCurrentRestaurantId();
$data['status'] = 1;
if (! empty($data['image']) && $data['image'] instanceof \Illuminate\Http\UploadedFile) {
$data['image'] = fileUploader('cms_background_images/', 'png', $data['image']);
}
} else {
if (! empty($data['image']) && $data['image'] instanceof \Illuminate\Http\UploadedFile) {
$data['image'] = fileUploader('cms_background_images/', 'png', $data['image'], $item->image);
}
$data['updated_at'] = now();
}
return $data;
}
protected function getExceptionMessages(): array
{
return [
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'CMSSection does not exist.',
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'CMSSection could not be deleted.',
];
}
}

View File

@@ -0,0 +1,180 @@
<?php
namespace Modules\Frontend\Repositories;
use App\Abstracts\EntityRepository;
use Exception;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder;
use Modules\Frontend\Models\Contact;
use Symfony\Component\HttpFoundation\Response;
class ContactRepository extends EntityRepository
{
public string $table = Contact::TABLE_NAME;
protected array $fillableColumns = [
'restaurant_id',
'name',
'phone',
'email',
'subject',
'message',
];
protected function getQuery(): Builder
{
return parent::getQuery();
}
public function getAll(array $filterData = []): Paginator
{
$filter = $this->getFilterData($filterData);
$query = $this->getContactQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
if (isset($filter['search']) && strlen($filter['search']) > 0) {
$query = $this->filterSearchQuery($query, $filter['search']);
}
return $query
->orderBy($filter['orderBy'], $filter['order'])
->paginate($filter['perPage']);
}
protected function getFilterData(array $filterData = []): array
{
$defaultArgs = [
'perPage' => 10,
'search' => '',
'orderBy' => 'id',
'order' => 'desc',
'with_deleted' => false,
];
return array_merge($defaultArgs, $filterData);
}
private function getContactQuery(): Builder
{
return $this->getQuery()
->select(
'frontend_contacts.id',
'frontend_contacts.restaurant_id',
'frontend_contacts.name',
'frontend_contacts.phone',
'frontend_contacts.email',
'frontend_contacts.subject',
'frontend_contacts.message',
'frontend_contacts.created_at',
);
}
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
{
$searchable = "%$searchedText%";
return $query->where('frontend_contacts.name', 'LIKE', $searchable)
->orWhere('frontend_contacts.phone', 'LIKE', $searchable)
->orWhere('frontend_contacts.email', 'LIKE', $searchable)
->orWhere('frontend_contacts.subject', 'LIKE', $searchable)
->orWhere('frontend_contacts.message', 'LIKE', $searchable)
->orWhere('frontend_contacts.status', 'LIKE', $searchable);
}
/**
* @throws Exception
*/
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
{
$user = $this->getContactQuery()
->where($columnName, $columnValue)
->first();
if (empty($user)) {
throw new Exception(
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
Response::HTTP_NOT_FOUND
);
}
return $user;
}
public function getCount(array $filterData = []): int
{
$filter = $this->getFilterData($filterData);
$query = $this->getQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
return $query->count();
}
/**
* @throws Exception
*/
public function create(array $data): object
{
try {
$data = $this->prepareForDB($data);
$userId = $this->getQuery()->insertGetId($data);
$user = Contact::find($userId);
return $user;
} catch (Exception $exception) {
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* @throws Exception
*/
public function prepareForDB(array $data, ?object $item = null): array
{
$data = parent::prepareForDB($data, $item);
if (empty($item)) {
$data['created_at'] = now();
$data['restaurant_id'] = $this->getCurrentRestaurantId();
} else {
$data['updated_at'] = now();
}
return $data;
}
/**
* @throws Exception
*/
public function update(int $id, array $data): ?object
{
try {
$user = Contact::find($id);
$data = $this->prepareForDB($data, $user);
parent::update($id, $data);
return $this->getById($id);
} catch (Exception $exception) {
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
protected function getExceptionMessages(): array
{
$exceptionMessages = parent::getExceptionMessages();
$userExceptionMessages = [
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'Contact does not exist.',
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'Contact could not be deleted.',
];
return array_merge($exceptionMessages, $userExceptionMessages);
}
}

View File

@@ -0,0 +1,195 @@
<?php
namespace Modules\Frontend\Repositories;
use App\Abstracts\EntityRepository;
use Exception;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder;
use Modules\Frontend\Models\Coupon;
use Symfony\Component\HttpFoundation\Response;
class CouponRepository extends EntityRepository
{
public string $table = Coupon::TABLE_NAME;
protected array $fillableColumns = [
'restaurant_id',
'user_id',
'name',
'added_by',
'discount_type',
'coupon_type',
'amount',
'valid_from',
'valid_to',
'usage_limit',
'max_uses_per_customer',
'min_order_amount',
'image',
'source',
'status',
'created_at',
'updated_at',
'deleted_at',
];
protected function getQuery(): Builder
{
return parent::getQuery();
}
protected function getFilterData(array $filterData = []): array
{
$defaultArgs = [
'perPage' => 10,
'search' => '',
'orderBy' => 'id',
'order' => 'desc',
'with_deleted' => false,
];
return array_merge($defaultArgs, $filterData);
}
private function getCouponQuery(): Builder
{
return $this->getQuery()
->select(
"{$this->table}.id",
"{$this->table}.restaurant_id",
"{$this->table}.user_id",
"{$this->table}.name",
"{$this->table}.added_by",
"{$this->table}.discount_type",
"{$this->table}.coupon_type",
"{$this->table}.amount",
"{$this->table}.valid_from",
"{$this->table}.valid_to",
"{$this->table}.usage_limit",
"{$this->table}.max_uses_per_customer",
"{$this->table}.min_order_amount",
"{$this->table}.image",
"{$this->table}.source",
"{$this->table}.status",
"{$this->table}.created_at",
"{$this->table}.updated_at",
"{$this->table}.deleted_at",
);
}
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
{
$searchable = "%$searchedText%";
return $query->where("{$this->table}.name", 'LIKE', $searchable)
->orWhere("{$this->table}.status", 'LIKE', $searchable);
}
public function getAll(array $filterData = []): Paginator
{
$filter = $this->getFilterData($filterData);
$query = $this->getCouponQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
if (! empty($filter['search'])) {
$query = $this->filterSearchQuery($query, $filter['search']);
}
return $query
->orderBy($filter['orderBy'], $filter['order'])
->paginate($filter['perPage']);
}
public function getCount(array $filterData = []): int
{
$filter = $this->getFilterData($filterData);
$query = $this->getQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
return $query->count();
}
/**
* @throws Exception
*/
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
{
$item = $this->getCouponQuery()
->where($columnName, $columnValue)
->first($selects);
if (empty($item)) {
throw new Exception(
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
Response::HTTP_NOT_FOUND
);
}
return $item;
}
/**
* @throws Exception
*/
public function create(array $data): object
{
$data = $this->prepareForDB($data);
$id = $this->getQuery()->insertGetId($data);
return Coupon::find($id);
}
/**
* @throws Exception
*/
public function update(int $id, array $data): object
{
$item = Coupon::findOrFail($id);
$data = $this->prepareForDB($data, $item);
parent::update($id, $data);
return $this->getById($id);
}
/**
* @throws Exception
*/
public function prepareForDB(array $data, ?object $item = null): array
{
$data = parent::prepareForDB($data, $item);
if (empty($item)) {
$data['created_at'] = now();
$data['restaurant_id'] = $this->getCurrentRestaurantId();
$data['status'] = 1;
if (! empty($data['image']) && $data['image'] instanceof \Illuminate\Http\UploadedFile) {
$data['image'] = fileUploader('coupons/', 'png', $data['image']);
}
} else {
if (! empty($data['image']) && $data['image'] instanceof \Illuminate\Http\UploadedFile) {
$data['image'] = fileUploader('coupons/', 'png', $data['image'], $item->image);
}
$data['updated_at'] = now();
}
return $data;
}
protected function getExceptionMessages(): array
{
return [
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'Coupon does not exist.',
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'Coupon could not be deleted.',
];
}
}

View File

@@ -0,0 +1,177 @@
<?php
namespace Modules\Frontend\Repositories;
use App\Abstracts\EntityRepository;
use Exception;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder;
use Modules\Frontend\Models\FaqQuestion;
use Symfony\Component\HttpFoundation\Response;
class FaqQuestionRepository extends EntityRepository
{
public string $table = FaqQuestion::TABLE_NAME;
protected array $fillableColumns = [
'restaurant_id',
'question',
'answer',
'status',
'created_by',
'created_at',
'updated_at',
];
protected function getQuery(): Builder
{
return parent::getQuery();
}
public function getAll(array $filterData = []): Paginator
{
$filter = $this->getFilterData($filterData);
$query = $this->getFaqQuestionQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
if (isset($filter['search']) && strlen($filter['search']) > 0) {
$query = $this->filterSearchQuery($query, $filter['search']);
}
return $query
->orderBy($filter['orderBy'], $filter['order'])
->paginate($filter['perPage']);
}
protected function getFilterData(array $filterData = []): array
{
$defaultArgs = [
'perPage' => 10,
'search' => '',
'orderBy' => 'id',
'order' => 'desc',
'with_deleted' => false,
];
return array_merge($defaultArgs, $filterData);
}
private function getFaqQuestionQuery(): Builder
{
return $this->getQuery()
->select(
'faq_questions.id',
'faq_questions.restaurant_id',
'faq_questions.question',
'faq_questions.answer',
'faq_questions.status',
'faq_questions.created_at'
);
}
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
{
$searchable = "%$searchedText%";
return $query->where('faq_questions.question', 'LIKE', $searchable)
->orWhere('faq_questions.answer', 'LIKE', $searchable)
->orWhere('faq_questions.status', 'LIKE', $searchable);
}
/**
* @throws Exception
*/
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
{
$user = $this->getFaqQuestionQuery()
->where($columnName, $columnValue)
->first();
if (empty($user)) {
throw new Exception(
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
Response::HTTP_NOT_FOUND
);
}
return $user;
}
public function getCount(array $filterData = []): int
{
$filter = $this->getFilterData($filterData);
$query = $this->getQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
return $query->count();
}
/**
* @throws Exception
*/
public function create(array $data): object
{
try {
$data = $this->prepareForDB($data);
$userId = $this->getQuery()->insertGetId($data);
$user = FaqQuestion::find($userId);
return $user;
} catch (Exception $exception) {
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* @throws Exception
*/
public function prepareForDB(array $data, ?object $item = null): array
{
$data = parent::prepareForDB($data, $item);
if (empty($item)) {
$data['created_at'] = now();
$data['restaurant_id'] = $this->getCurrentRestaurantId();
$data['status'] = 1;
} else {
$data['updated_at'] = now();
}
return $data;
}
/**
* @throws Exception
*/
public function update(int $id, array $data): ?object
{
try {
$user = FaqQuestion::find($id);
$data = $this->prepareForDB($data, $user);
parent::update($id, $data);
return $this->getById($id);
} catch (Exception $exception) {
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
protected function getExceptionMessages(): array
{
$exceptionMessages = parent::getExceptionMessages();
$userExceptionMessages = [
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'FaqQuestion does not exist.',
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'FaqQuestion could not be deleted.',
];
return array_merge($exceptionMessages, $userExceptionMessages);
}
}

View File

@@ -0,0 +1,194 @@
<?php
namespace Modules\Frontend\Repositories;
use App\Abstracts\EntityRepository;
use Exception;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder;
use Modules\Frontend\Models\MobileAppSection;
use Symfony\Component\HttpFoundation\Response;
class MobileAppSectionRepository extends EntityRepository
{
public string $table = MobileAppSection::TABLE_NAME;
protected array $fillableColumns = [
'restaurant_id',
'title',
'heading',
'description',
'image',
'feature_one',
'feature_two',
'feature_three',
'play_store_link',
'app_store_link',
'created_at',
'updated_at',
];
protected function getQuery(): Builder
{
return parent::getQuery();
}
public function getAll(array $filterData = []): Paginator
{
$filter = $this->getFilterData($filterData);
$query = $this->getMobileAppSectionQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
if (isset($filter['search']) && strlen($filter['search']) > 0) {
$query = $this->filterSearchQuery($query, $filter['search']);
}
return $query
->orderBy($filter['orderBy'], $filter['order'])
->paginate($filter['perPage']);
}
protected function getFilterData(array $filterData = []): array
{
$defaultArgs = [
'perPage' => 10,
'search' => '',
'orderBy' => 'id',
'order' => 'desc',
'with_deleted' => false,
];
return array_merge($defaultArgs, $filterData);
}
private function getMobileAppSectionQuery(): Builder
{
return $this->getQuery()
->select(
'mobile_app_sections.id',
'mobile_app_sections.restaurant_id',
'mobile_app_sections.title',
'mobile_app_sections.heading',
'mobile_app_sections.description',
'mobile_app_sections.image',
'mobile_app_sections.feature_one',
'mobile_app_sections.feature_two',
'mobile_app_sections.feature_three',
'mobile_app_sections.play_store_link',
'mobile_app_sections.app_store_link',
'mobile_app_sections.created_at',
'mobile_app_sections.updated_at',
);
}
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
{
$searchable = "%$searchedText%";
return $query->where('mobile_app_sections.title', 'LIKE', $searchable)
->orWhere('mobile_app_sections.heading', 'LIKE', $searchable);
}
/**
* @throws Exception
*/
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
{
$user = $this->getMobileAppSectionQuery()
->where($columnName, $columnValue)
->first();
if (empty($user)) {
throw new Exception(
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
Response::HTTP_NOT_FOUND
);
}
return $user;
}
public function getCount(array $filterData = []): int
{
$filter = $this->getFilterData($filterData);
$query = $this->getQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
return $query->count();
}
/**
* @throws Exception
*/
public function create(array $data): object
{
try {
$data = $this->prepareForDB($data);
$userId = $this->getQuery()->insertGetId($data);
$user = MobileAppSection::find($userId);
return $user;
} catch (Exception $exception) {
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* @throws Exception
*/
public function prepareForDB(array $data, ?object $item = null): array
{
$data = parent::prepareForDB($data, $item);
if (empty($item)) {
$data['created_at'] = now();
$data['restaurant_id'] = $this->getCurrentRestaurantId();
if (! empty($data['image']) && $data['image'] instanceof \Illuminate\Http\UploadedFile) {
$data['image'] = fileUploader('mobile_app_sections/', 'png', $data['image']);
}
} else {
if (! empty($data['image']) && $data['image'] instanceof \Illuminate\Http\UploadedFile) {
$data['image'] = fileUploader('mobile_app_sections/', 'png', $data['image'], $item->image);
}
$data['updated_at'] = now();
}
return $data;
}
/**
* @throws Exception
*/
public function update(int $id, array $data): ?object
{
try {
$user = MobileAppSection::find($id);
$data = $this->prepareForDB($data, $user);
parent::update($id, $data);
return $this->getById($id);
} catch (Exception $exception) {
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
protected function getExceptionMessages(): array
{
$exceptionMessages = parent::getExceptionMessages();
$userExceptionMessages = [
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'MobileAppSection does not exist.',
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'MobileAppSection could not be deleted.',
];
return array_merge($exceptionMessages, $userExceptionMessages);
}
}

View File

@@ -0,0 +1,177 @@
<?php
namespace Modules\Frontend\Repositories;
use App\Abstracts\EntityRepository;
use Exception;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder;
use Modules\Frontend\Models\Policy;
use Symfony\Component\HttpFoundation\Response;
class PolicyRepository extends EntityRepository
{
public string $table = Policy::TABLE_NAME;
protected array $fillableColumns = [
'restaurant_id',
'type',
'description',
'status',
'created_by',
'created_at',
'updated_at',
];
protected function getQuery(): Builder
{
return parent::getQuery();
}
public function getAll(array $filterData = []): Paginator
{
$filter = $this->getFilterData($filterData);
$query = $this->getPolicyQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
if (isset($filter['search']) && strlen($filter['search']) > 0) {
$query = $this->filterSearchQuery($query, $filter['search']);
}
return $query
->orderBy($filter['orderBy'], $filter['order'])
->paginate($filter['perPage']);
}
protected function getFilterData(array $filterData = []): array
{
$defaultArgs = [
'perPage' => 10,
'search' => '',
'orderBy' => 'id',
'order' => 'desc',
'with_deleted' => false,
];
return array_merge($defaultArgs, $filterData);
}
private function getPolicyQuery(): Builder
{
return $this->getQuery()
->select(
'policies.id',
'policies.restaurant_id',
'policies.type',
'policies.description',
'policies.status',
'policies.created_at'
);
}
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
{
$searchable = "%$searchedText%";
return $query->where('policies.type', 'LIKE', $searchable)
->orWhere('policies.description', 'LIKE', $searchable)
->orWhere('policies.status', 'LIKE', $searchable);
}
/**
* @throws Exception
*/
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
{
$user = $this->getPolicyQuery()
->where($columnName, $columnValue)
->first();
if (empty($user)) {
throw new Exception(
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
Response::HTTP_NOT_FOUND
);
}
return $user;
}
public function getCount(array $filterData = []): int
{
$filter = $this->getFilterData($filterData);
$query = $this->getQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
return $query->count();
}
/**
* @throws Exception
*/
public function create(array $data): object
{
try {
$data = $this->prepareForDB($data);
$userId = $this->getQuery()->insertGetId($data);
$user = Policy::find($userId);
return $user;
} catch (Exception $exception) {
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* @throws Exception
*/
public function prepareForDB(array $data, ?object $item = null): array
{
$data = parent::prepareForDB($data, $item);
if (empty($item)) {
$data['created_at'] = now();
$data['restaurant_id'] = $this->getCurrentRestaurantId();
$data['status'] = 1;
} else {
$data['updated_at'] = now();
}
return $data;
}
/**
* @throws Exception
*/
public function update(int $id, array $data): ?object
{
try {
$user = Policy::find($id);
$data = $this->prepareForDB($data, $user);
parent::update($id, $data);
return $this->getById($id);
} catch (Exception $exception) {
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
protected function getExceptionMessages(): array
{
$exceptionMessages = parent::getExceptionMessages();
$userExceptionMessages = [
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'Policy does not exist.',
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'Policy could not be deleted.',
];
return array_merge($exceptionMessages, $userExceptionMessages);
}
}

View File

@@ -0,0 +1,174 @@
<?php
namespace Modules\Frontend\Repositories;
use App\Abstracts\EntityRepository;
use Exception;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder;
use Modules\Frontend\Models\ReadyToJoinUs;
use Symfony\Component\HttpFoundation\Response;
class ReadyToJoinUsRepository extends EntityRepository
{
public string $table = ReadyToJoinUs::TABLE_NAME;
protected array $fillableColumns = [
'restaurant_id',
'title',
'description',
'icon',
'created_at',
'updated_at',
];
protected function getQuery(): Builder
{
return parent::getQuery();
}
public function getAll(array $filterData = []): Paginator
{
$filter = $this->getFilterData($filterData);
$query = $this->getReadyToJoinUsQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
if (isset($filter['search']) && strlen($filter['search']) > 0) {
$query = $this->filterSearchQuery($query, $filter['search']);
}
return $query
->orderBy($filter['orderBy'], $filter['order'])
->paginate($filter['perPage']);
}
protected function getFilterData(array $filterData = []): array
{
$defaultArgs = [
'perPage' => 10,
'search' => '',
'orderBy' => 'id',
'order' => 'desc',
'with_deleted' => false,
];
return array_merge($defaultArgs, $filterData);
}
private function getReadyToJoinUsQuery(): Builder
{
return $this->getQuery()
->select('*');
}
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
{
$searchable = "%$searchedText%";
return $query->where('ready_to_join_us.title', 'LIKE', $searchable)
->orWhere('ready_to_join_us.description', 'LIKE', $searchable);
}
/**
* @throws Exception
*/
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
{
$user = $this->getReadyToJoinUsQuery()
->where($columnName, $columnValue)
->first();
if (empty($user)) {
throw new Exception(
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
Response::HTTP_NOT_FOUND
);
}
return $user;
}
public function getCount(array $filterData = []): int
{
$filter = $this->getFilterData($filterData);
$query = $this->getQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
return $query->count();
}
/**
* @throws Exception
*/
public function create(array $data): object
{
try {
$data = $this->prepareForDB($data);
$userId = $this->getQuery()->insertGetId($data);
$user = ReadyToJoinUs::find($userId);
return $user;
} catch (Exception $exception) {
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* @throws Exception
*/
public function prepareForDB(array $data, ?object $item = null): array
{
$data = parent::prepareForDB($data, $item);
if (empty($item)) {
$data['created_at'] = now();
$data['restaurant_id'] = $this->getCurrentRestaurantId();
if (! empty($data['icon']) && $data['icon'] instanceof \Illuminate\Http\UploadedFile) {
$data['icon'] = fileUploader('ready_to_join_us/', 'png', $data['icon']);
}
} else {
if (! empty($data['icon']) && $data['icon'] instanceof \Illuminate\Http\UploadedFile) {
$data['icon'] = fileUploader('ready_to_join_us/', 'png', $data['icon'], $item->icon);
}
$data['updated_at'] = now();
}
return $data;
}
/**
* @throws Exception
*/
public function update(int $id, array $data): ?object
{
try {
$user = ReadyToJoinUs::find($id);
$data = $this->prepareForDB($data, $user);
parent::update($id, $data);
return $this->getById($id);
} catch (Exception $exception) {
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
protected function getExceptionMessages(): array
{
$exceptionMessages = parent::getExceptionMessages();
$userExceptionMessages = [
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'Ready To Join Us does not exist.',
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'Ready To Join Us could not be deleted.',
];
return array_merge($exceptionMessages, $userExceptionMessages);
}
}

View File

@@ -0,0 +1,191 @@
<?php
namespace Modules\Frontend\Repositories;
use App\Abstracts\EntityRepository;
use Exception;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder;
use Modules\Frontend\Models\Testimonial;
use Symfony\Component\HttpFoundation\Response;
class TestimonialRepository extends EntityRepository
{
public string $table = Testimonial::TABLE_NAME;
protected array $fillableColumns = [
'restaurant_id',
'name',
'description',
'thumbnail_image',
'video_url',
'note',
'ratting',
'status',
'created_at',
'updated_at',
];
protected function getQuery(): Builder
{
return parent::getQuery();
}
public function getAll(array $filterData = []): Paginator
{
$filter = $this->getFilterData($filterData);
$query = $this->getTestimonialQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
if (isset($filter['search']) && strlen($filter['search']) > 0) {
$query = $this->filterSearchQuery($query, $filter['search']);
}
return $query
->orderBy($filter['orderBy'], $filter['order'])
->paginate($filter['perPage']);
}
protected function getFilterData(array $filterData = []): array
{
$defaultArgs = [
'perPage' => 10,
'search' => '',
'orderBy' => 'id',
'order' => 'desc',
'with_deleted' => false,
];
return array_merge($defaultArgs, $filterData);
}
private function getTestimonialQuery(): Builder
{
return $this->getQuery()
->select(
'testimonials.id',
'testimonials.restaurant_id',
'testimonials.name',
'testimonials.description',
'testimonials.thumbnail_image',
'testimonials.video_url',
'testimonials.note',
'testimonials.ratting',
'testimonials.status',
'testimonials.created_at',
'testimonials.updated_at'
);
}
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
{
$searchable = "%$searchedText%";
return $query->where('testimonials.restaurant_id', 'LIKE', $searchable)
->orWhere('testimonials.name', 'LIKE', $searchable)
->orWhere('testimonials.description', 'LIKE', $searchable)
->orWhere('testimonials.status', 'LIKE', $searchable);
}
/**
* @throws Exception
*/
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
{
$user = $this->getTestimonialQuery()
->where($columnName, $columnValue)
->first();
if (empty($user)) {
throw new Exception(
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
Response::HTTP_NOT_FOUND
);
}
return $user;
}
public function getCount(array $filterData = []): int
{
$filter = $this->getFilterData($filterData);
$query = $this->getQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
return $query->count();
}
/**
* @throws Exception
*/
public function create(array $data): object
{
try {
$data = $this->prepareForDB($data);
$userId = $this->getQuery()->insertGetId($data);
$user = Testimonial::find($userId);
return $user;
} catch (Exception $exception) {
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* @throws Exception
*/
public function prepareForDB(array $data, ?object $item = null): array
{
$data = parent::prepareForDB($data, $item);
if (empty($item)) {
$data['created_at'] = now();
$data['restaurant_id'] = $this->getCurrentRestaurantId();
if (! empty($data['thumbnail_image']) && $data['thumbnail_image'] instanceof \Illuminate\Http\UploadedFile) {
$data['thumbnail_image'] = fileUploader('testimonials/', 'png', $data['thumbnail_image']);
}
} else {
if (! empty($data['thumbnail_image']) && $data['thumbnail_image'] instanceof \Illuminate\Http\UploadedFile) {
$data['thumbnail_image'] = fileUploader('testimonials/', 'png', $data['thumbnail_image'], $item->thumbnail_image);
}
$data['updated_at'] = now();
}
return $data;
}
/**
* @throws Exception
*/
public function update(int $id, array $data): ?object
{
try {
$user = Testimonial::find($id);
$data = $this->prepareForDB($data, $user);
parent::update($id, $data);
return $this->getById($id);
} catch (Exception $exception) {
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
protected function getExceptionMessages(): array
{
$exceptionMessages = parent::getExceptionMessages();
$userExceptionMessages = [
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'Testimonial does not exist.',
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'Testimonial could not be deleted.',
];
return array_merge($exceptionMessages, $userExceptionMessages);
}
}

View File

@@ -0,0 +1,175 @@
<?php
namespace Modules\Frontend\Repositories;
use App\Abstracts\EntityRepository;
use Exception;
use Illuminate\Contracts\Pagination\Paginator;
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
use Illuminate\Database\Query\Builder;
use Modules\Frontend\Models\WhyChooseUs;
use Symfony\Component\HttpFoundation\Response;
class WhyChooseUsRepository extends EntityRepository
{
public string $table = WhyChooseUs::TABLE_NAME;
protected array $fillableColumns = [
'restaurant_id',
'title',
'description',
'icon',
'created_at',
'updated_at',
];
protected function getQuery(): Builder
{
return parent::getQuery();
}
public function getAll(array $filterData = []): Paginator
{
$filter = $this->getFilterData($filterData);
$query = $this->getWhyChooseUsQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
if (isset($filter['search']) && strlen($filter['search']) > 0) {
$query = $this->filterSearchQuery($query, $filter['search']);
}
return $query
->orderBy($filter['orderBy'], $filter['order'])
->paginate($filter['perPage']);
}
protected function getFilterData(array $filterData = []): array
{
$defaultArgs = [
'perPage' => 10,
'search' => '',
'orderBy' => 'id',
'order' => 'desc',
'with_deleted' => false,
];
return array_merge($defaultArgs, $filterData);
}
private function getWhyChooseUsQuery(): Builder
{
return $this->getQuery()
->select('*');
}
protected function filterSearchQuery(Builder|EloquentBuilder $query, string $searchedText): Builder
{
$searchable = "%$searchedText%";
return $query->where('why_choose_us.title', 'LIKE', $searchable)
->orWhere('why_choose_us.description', 'LIKE', $searchable);
}
/**
* @throws Exception
*/
public function getByColumn(string $columnName, $columnValue, array $selects = ['*']): ?object
{
$user = $this->getWhyChooseUsQuery()
->where($columnName, $columnValue)
->first();
if (empty($user)) {
throw new Exception(
$this->getExceptionMessage(static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE),
Response::HTTP_NOT_FOUND
);
}
return $user;
}
public function getCount(array $filterData = []): int
{
$filter = $this->getFilterData($filterData);
$query = $this->getQuery();
if (! $filter['with_deleted']) {
$query->whereNull("{$this->table}.deleted_at");
}
return $query->count();
}
/**
* @throws Exception
*/
public function create(array $data): object
{
try {
$data = $this->prepareForDB($data);
$userId = $this->getQuery()->insertGetId($data);
$user = WhyChooseUs::find($userId);
return $user;
} catch (Exception $exception) {
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
/**
* @throws Exception
*/
public function prepareForDB(array $data, ?object $item = null): array
{
$data = parent::prepareForDB($data, $item);
if (empty($item)) {
$data['created_at'] = now();
$data['restaurant_id'] = $this->getCurrentRestaurantId();
if (! empty($data['icon']) && $data['icon'] instanceof \Illuminate\Http\UploadedFile) {
$data['icon'] = fileUploader('why_choose_us/', 'png', $data['icon']);
}
} else {
if (! empty($data['icon']) && $data['icon'] instanceof \Illuminate\Http\UploadedFile) {
$data['icon'] = fileUploader('why_choose_us/', 'png', $data['icon'], $item->icon);
}
$data['updated_at'] = now();
}
return $data;
}
/**
* @throws Exception
*/
public function update(int $id, array $data): ?object
{
try {
$user = WhyChooseUs::find($id);
$data = $this->prepareForDB($data, $user);
parent::update($id, $data);
return $this->getById($id);
} catch (Exception $exception) {
throw new Exception($exception->getMessage(), Response::HTTP_INTERNAL_SERVER_ERROR);
}
}
protected function getExceptionMessages(): array
{
$exceptionMessages = parent::getExceptionMessages();
$userExceptionMessages = [
static::MESSAGE_ITEM_DOES_NOT_EXIST_MESSAGE => 'WhyChooseUs does not exist.',
static::MESSAGE_ITEM_COULD_NOT_BE_DELETED => 'WhyChooseUs could not be deleted.',
];
return array_merge($exceptionMessages, $userExceptionMessages);
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace Modules\Frontend\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Traits\RequestSanitizerTrait;
use Exception;
use Illuminate\Http\JsonResponse;
use Modules\Frontend\Http\Requests\AboutUs\AboutUsStoreRequest;
use Modules\Frontend\Http\Requests\AboutUs\AboutUsUpdateRequest;
use Modules\Frontend\Repositories\AboutUsRepository;
class AboutUsController extends Controller
{
use RequestSanitizerTrait;
public function __construct(private AboutUsRepository $faq) {}
public function index(): JsonResponse
{
try {
return $this->responseSuccess(
$this->faq->getAll(request()->all()),
'AboutUs has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function store(AboutUsStoreRequest $request): JsonResponse
{
try {
return $this->responseSuccess(
$this->faq->create($request->all()),
'AboutUs has been created successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function show(int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->faq->getById($id),
'AboutUs has been fetched successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function update(AboutUsUpdateRequest $request, int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->faq->update($id, $this->getUpdateRequest($request)),
'AboutUs has been updated successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function destroy(int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->faq->delete($id),
'AboutUs has been deleted successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace Modules\Frontend\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Traits\RequestSanitizerTrait;
use Exception;
use Illuminate\Http\JsonResponse;
use Modules\Frontend\Http\Requests\AcademicImage\AcademicImageStoreRequest;
use Modules\Frontend\Http\Requests\AcademicImage\AcademicImageUpdateRequest;
use Modules\Frontend\Repositories\AcademicImageRepository;
class AcademicImageController extends Controller
{
use RequestSanitizerTrait;
public function __construct(private AcademicImageRepository $academicImage) {}
public function index(): JsonResponse
{
try {
return $this->responseSuccess(
$this->academicImage->getAll(request()->all()),
'AcademicImages has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function store(AcademicImageStoreRequest $request): JsonResponse
{
try {
return $this->responseSuccess(
$this->academicImage->create($request->all()),
'AcademicImages has been created successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function show(int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->academicImage->getById($id),
'AcademicImages has been fetched successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function update(AcademicImageUpdateRequest $request, int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->academicImage->update($id, $this->getUpdateRequest($request)),
'AcademicImages has been updated successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function destroy(int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->academicImage->delete($id),
'AcademicImages has been deleted successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
}

View File

@@ -0,0 +1,86 @@
<?php
namespace Modules\Frontend\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Traits\RequestSanitizerTrait;
use Exception;
use Illuminate\Http\JsonResponse;
use Modules\Frontend\Http\Requests\Banner\BannerStoreRequest;
use Modules\Frontend\Http\Requests\Banner\BannerUpdateRequest;
use Modules\Frontend\Repositories\BannerRepository;
class BannerController extends Controller
{
use RequestSanitizerTrait;
public function __construct(private BannerRepository $banner) {}
public function index(): JsonResponse
{
try {
return $this->responseSuccess(
$this->banner->getAll(request()->all()),
'Banner has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function store(BannerStoreRequest $request): JsonResponse
{
try {
return $this->responseSuccess(
$this->banner->create($request->all()),
'Banner has been created successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function show(int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->banner->getById($id),
'Banner has been fetched successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function update(BannerUpdateRequest $request, int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->banner->update($id, $this->getUpdateRequest($request)),
'Banner has been updated successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function destroy(int $id): JsonResponse
{
try {
$banner = $this->banner->getById($id);
if (! $banner) {
return $this->responseError([], 'Restaurant Not Found');
}
if ($banner->image) {
fileRemover('banners/', $banner->image);
}
return $this->responseSuccess(
$this->banner->delete($id),
'Banner has been deleted successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
}

View File

@@ -0,0 +1,225 @@
<?php
namespace Modules\Frontend\Http\Controllers\API;
use App\Helper\RestaurantHelper;
use App\Http\Controllers\Controller;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Modules\Booking\Models\Floor;
use Modules\Booking\Models\Hotel;
use Modules\Booking\Models\Room;
use Modules\Booking\Models\RoomAvailability;
use Modules\Booking\Models\RoomBlock;
use Modules\Booking\Models\RoomType;
class BookingFrontendController extends Controller
{
/**
* Get Hotels with filters, search, sorting, pagination
*/
public function getHotels(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
$filters = $request->all();
$query = Hotel::query()->where('restaurant_id', $restaurantId);
// Search
if (! empty($filters['search'])) {
$search = $filters['search'];
$query->where(function ($q) use ($search) {
$q->where('name', 'LIKE', "%$search%")
->orWhere('code', 'LIKE', "%$search%");
});
}
// Status filter
if (isset($filters['status'])) {
$query->where('status', $filters['status']);
}
return $this->applySortingPagination($query, $filters, ['id', 'name', 'status', 'created_at'], 'Hotels fetched successfully.');
}
/**
* Get Floors with filters, search, sorting, pagination
*/
public function getFloors(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
$filters = $request->all();
$query = Floor::query()->with('hotel:id,name')->where('restaurant_id', $restaurantId);
if (! empty($filters['search'])) {
$query->where('name', 'LIKE', "%{$filters['search']}%");
}
if (! empty($filters['hotel_id'])) {
$query->where('hotel_id', $filters['hotel_id']);
}
return $this->applySortingPagination($query, $filters, ['id', 'name', 'created_at'], 'Floors fetched successfully.');
}
/**
* Get Room Types
*/
public function getRoomTypes(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
$filters = $request->all();
$query = RoomType::query()->where('restaurant_id', $restaurantId);
if (! empty($filters['search'])) {
$query->where('name', 'LIKE', "%{$filters['search']}%");
}
return $this->applySortingPagination($query, $filters, ['id', 'name', 'created_at'], 'Room types fetched successfully.');
}
/**
* Get Rooms
*/
public function getRooms(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
$filters = $request->all();
$query = Room::with(['hotel:id,name', 'floor:id,name', 'roomType:id,name'])
->where('restaurant_id', $restaurantId);
if (! empty($filters['search'])) {
$search = $filters['search'];
$query->where(function ($q) use ($search) {
$q->where('room_number', 'LIKE', "%$search%")
->orWhere('room_code', 'LIKE', "%$search%")
->orWhereHas('hotel', fn ($q) => $q->where('name', 'LIKE', "%$search%"))
->orWhereHas('floor', fn ($q) => $q->where('name', 'LIKE', "%$search%"));
});
}
if (! empty($filters['hotel_id'])) {
$query->where('hotel_id', $filters['hotel_id']);
}
if (! empty($filters['floor_id'])) {
$query->where('floor_id', $filters['floor_id']);
}
if (! empty($filters['room_type_id'])) {
$query->where('room_type_id', $filters['room_type_id']);
}
if (isset($filters['status'])) {
$query->where('status', $filters['status']);
}
return $this->applySortingPagination($query, $filters, ['id', 'room_number', 'status', 'created_at'], 'Rooms fetched successfully.');
}
/**
* Get Room Availabilities
*/
public function getRoomAvailabilities(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
$filters = $request->all();
$query = RoomAvailability::with(['room:id,room_number,hotel_id'])
->where('restaurant_id', $restaurantId);
if (! empty($filters['room_id'])) {
$query->where('room_id', $filters['room_id']);
}
if (! empty($filters['hotel_id'])) {
$query->where('hotel_id', $filters['hotel_id']);
}
if (! empty($filters['date_from']) && ! empty($filters['date_to'])) {
$query->whereBetween('date', [$filters['date_from'], $filters['date_to']]);
}
return $this->applySortingPagination($query, $filters, ['date', 'room_id', 'hotel_id'], 'Room availabilities fetched successfully.');
}
/**
* Get Room Blocks
*/
public function getRoomBlocks(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
$filters = $request->all();
$query = RoomBlock::with(['room:id,room_number,hotel_id'])
->where('restaurant_id', $restaurantId);
if (! empty($filters['room_id'])) {
$query->where('room_id', $filters['room_id']);
}
if (! empty($filters['hotel_id'])) {
$query->where('hotel_id', $filters['hotel_id']);
}
if (! empty($filters['start_date']) && ! empty($filters['end_date'])) {
$query->where(function ($q) use ($filters) {
$q->whereBetween('start_date', [$filters['start_date'], $filters['end_date']])
->orWhereBetween('end_date', [$filters['start_date'], $filters['end_date']]);
});
}
return $this->applySortingPagination($query, $filters, ['start_date', 'room_id', 'hotel_id'], 'Room blocks fetched successfully.');
}
/**
* Extract restaurant_id from X-Domain header
*/
private function getRestaurantIdFromHeader(Request $request): mixed
{
$domain = $request->header('X-Domain');
if (! $domain) {
return $this->responseError([], 'Domain header is missing.', 400);
}
$restaurantResponse = RestaurantHelper::getRestaurantIdByDomain($domain);
if (! $restaurantResponse['status']) {
return $this->responseError([], $restaurantResponse['error'], 404);
}
return $restaurantResponse['restaurant_id'];
}
/**
* Reusable function for sorting & pagination
*/
private function applySortingPagination($query, array $filters, array $allowedSortColumns, string $message): JsonResponse
{
$sortBy = $filters['sort_by'] ?? $allowedSortColumns[0];
$sortOrder = $filters['sort_order'] ?? 'desc';
if (! in_array($sortBy, $allowedSortColumns)) {
$sortBy = $allowedSortColumns[0];
}
$query->orderBy($sortBy, $sortOrder);
$perPage = $filters['per_page'] ?? 15;
return $this->responseSuccess($query->paginate($perPage), $message);
}
}

View File

@@ -0,0 +1,81 @@
<?php
namespace Modules\Frontend\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Modules\Frontend\Http\Requests\CMSSection\CMSSectionStoreRequest;
use Modules\Frontend\Http\Requests\CMSSection\CMSSectionUpdateRequest;
use Modules\Frontend\Repositories\CMSSectionRepository;
class CMSSectionController extends Controller
{
public function __construct(private CMSSectionRepository $repo) {}
public function index(): JsonResponse
{
try {
return $this->responseSuccess($this->repo->getAll(request()->all()), 'CMSSection has been fetched successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function store(CMSSectionStoreRequest $request): JsonResponse
{
try {
return $this->responseSuccess($this->repo->create($request->all()), 'CMSSection has been created successfully.');
} catch (\Illuminate\Database\QueryException $exception) {
return $this->responseError([], 'Database error: '.$exception->getMessage());
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function show(int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->getById($id), 'CMSSection has been fetched successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function update(CMSSectionUpdateRequest $request, int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->update($id, $request->all()), 'CMSSection has been updated successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function destroy(int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->delete($id), 'CMSSection has been deleted successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function updateOrder(Request $request)
{
$request->validate([
'sections' => ['required', 'array'],
'sections.*.id' => ['required', 'integer', 'exists:c_m_s_sections,id'],
'sections.*.serial' => ['required', 'integer'],
]);
foreach ($request->sections as $item) {
DB::table('c_m_s_sections')
->where('id', $item['id'])
->update(['serial' => $item['serial']]);
}
return $this->responseSuccess([], 'CMS Section order updated successfully.');
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace Modules\Frontend\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Modules\Frontend\Models\Contact;
class ContactController extends Controller
{
public function index(Request $request): JsonResponse
{
try {
$query = Contact::query()->select('id', 'email');
// --- Filter by email ---
if ($request->has('email') && $request->email) {
$query->where('email', 'like', '%'.$request->email.'%');
}
// --- Sorting ---
$sortBy = $request->get('sort_by', 'email'); // default sort column
$sortOrder = $request->get('sort_order', 'asc'); // asc or desc
$query->orderBy($sortBy, $sortOrder);
// --- Pagination ---
$perPage = (int) $request->get('perPage', 15); // default 15
$contacts = $query->paginate($perPage);
return $this->responseSuccess(
$contacts,
'Contacts fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
}

View File

@@ -0,0 +1,62 @@
<?php
namespace Modules\Frontend\Http\Controllers\API;
use App\Http\Controllers\Controller;
use Exception;
use Illuminate\Http\JsonResponse;
use Modules\Frontend\Http\Requests\Coupon\CouponStoreRequest;
use Modules\Frontend\Http\Requests\Coupon\CouponUpdateRequest;
use Modules\Frontend\Repositories\CouponRepository;
class CouponController extends Controller
{
public function __construct(private CouponRepository $repo) {}
public function index(): JsonResponse
{
try {
return $this->responseSuccess($this->repo->getAll(request()->all()), 'Coupon has been fetched successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function store(CouponStoreRequest $request): JsonResponse
{
try {
return $this->responseSuccess($this->repo->create($request->all()), 'Coupon has been created successfully.');
} catch (\Illuminate\Database\QueryException $exception) {
return $this->responseError([], 'Database error: '.$exception->getMessage());
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function show(int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->getById($id), 'Coupon has been fetched successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function update(CouponUpdateRequest $request, int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->update($id, $request->all()), 'Coupon has been updated successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function destroy(int $id): JsonResponse
{
try {
return $this->responseSuccess($this->repo->delete($id), 'Coupon has been deleted successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace Modules\Frontend\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Traits\RequestSanitizerTrait;
use Exception;
use Illuminate\Http\JsonResponse;
use Modules\Frontend\Http\Requests\Faq\FaqStoreRequest;
use Modules\Frontend\Http\Requests\Faq\FaqUpdateRequest;
use Modules\Frontend\Repositories\FaqQuestionRepository;
class FaqQuestionController extends Controller
{
use RequestSanitizerTrait;
public function __construct(private FaqQuestionRepository $faqQuestion) {}
public function index(): JsonResponse
{
try {
return $this->responseSuccess(
$this->faqQuestion->getAll(request()->all()),
'Faq has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function store(FaqStoreRequest $request): JsonResponse
{
try {
return $this->responseSuccess(
$this->faqQuestion->create($request->all()),
'Faq has been created successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function show(int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->faqQuestion->getById($id),
'Faq has been fetched successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function update(FaqUpdateRequest $request, int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->faqQuestion->update($id, $this->getUpdateRequest($request)),
'Faq has been updated successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function destroy(int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->faqQuestion->delete($id),
'Faq has been deleted successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
}

View File

@@ -0,0 +1,976 @@
<?php
namespace Modules\Frontend\Http\Controllers\API;
use App\Helper\RestaurantHelper;
use App\Http\Controllers\Controller;
use Carbon\Carbon;
use Exception;
use Illuminate\Http\JsonResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Hash;
use Modules\Authentication\Models\Restaurant;
use Modules\Authentication\Models\RestaurantImageSAASSetting;
use Modules\Authentication\Models\RestaurantImageSetting;
use Modules\Authentication\Models\User;
use Modules\Authentication\Services\RestaurantSetupService;
use Modules\Frontend\Http\Requests\Contact\ContactStoreRequest;
use Modules\Frontend\Http\Requests\Onboarding\OnboardingStoreRequest;
use Modules\Frontend\Models\AboutUs;
use Modules\Frontend\Models\AcademicImage;
use Modules\Frontend\Models\Banner;
use Modules\Frontend\Models\CMSSection;
use Modules\Frontend\Models\Contact;
use Modules\Frontend\Models\Coupon;
use Modules\Frontend\Models\FaqQuestion;
use Modules\Frontend\Models\MobileAppSection;
use Modules\Frontend\Models\Onboarding;
use Modules\Frontend\Models\OurHistory;
use Modules\Frontend\Models\Policy;
use Modules\Frontend\Models\ReadyToJoinUs;
use Modules\Frontend\Models\Testimonial;
use Modules\Frontend\Models\Theme;
use Modules\Frontend\Models\WhyChooseUs;
use Modules\Restaurant\Models\Customer;
use Modules\Restaurant\Models\FoodCategory;
use Modules\Restaurant\Models\FoodItem;
use Modules\Restaurant\Models\MenuCategory;
use Modules\Restaurant\Models\ReservationSetting;
use Modules\Restaurant\Models\ReservationUnavailable;
use Modules\Restaurant\Models\RestaurantSchedule;
use Modules\Restaurant\Models\Table;
use Modules\Restaurant\Repositories\ReservationRepository;
class FrontendController extends Controller
{
public function __construct(private ReservationRepository $reservationRepository) {}
public function publicFoodCategories(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
$categoryLimit = 100;
$productLimit = 100;
try {
$categories = FoodCategory::where('restaurant_id', $restaurantId)
->where('status', 1)
->limit($categoryLimit)
->with(['foodItems' => function ($q) use ($restaurantId, $productLimit) {
$q->where('restaurant_id', $restaurantId)
->with('variants', 'defaultVariant')
->orderBy('id', 'desc')
->limit($productLimit);
}])
->get();
return $this->responseSuccess(
$categories,
'Categories with food items fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function foodItems(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$query = FoodItem::with([
'category',
'variants',
'defaultVariant',
'availabilities',
'addons',
])
->where('restaurant_id', $restaurantId);
// 🔥 Filter by status
if ($request->has('status')) {
$query->where('status', $request->status);
} else {
$query->where('status', 1); // default active
}
// 🔥 Filter by category
if ($request->filled('category_id')) {
$query->where('category_id', $request->category_id);
}
if ($request->filled('menu_category_id')) {
$query->where('menu_category_id', $request->menu_category_id);
}
if ($request->filled('menu_section_id')) {
$query->where('menu_section_id', $request->menu_section_id);
}
// 🔥 Chef Special filter
if ($request->filled('chef_special')) {
$query->chefSpecial($request->chef_special);
}
// 🔥 Popular Item filter
if ($request->filled('popular')) {
$query->popular($request->popular);
}
// 🔥 Search by name, slug, description
if ($request->filled('search')) {
$search = $request->search;
$query->where(function ($q) use ($search) {
$q->where('name', 'like', "%{$search}%");
});
}
// 🔥 Sorting
$sortBy = $request->get('sort_by', 'id'); // default sort by id
$sortOrder = $request->get('sort_order', 'desc'); // default desc
$query->orderBy($sortBy, $sortOrder);
// 🔥 Pagination
$perPage = (int) $request->get('per_page', 15);
$data = $query->paginate($perPage);
return $this->responseSuccess(
$data,
'Food items fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function foodDetails(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$data = FoodItem::where('slug', $request->slug)
->where('restaurant_id', $restaurantId)
->where('status', 1)
->with('category', 'variants', 'defaultVariant', 'availabilities', 'addons', 'reviews')
->first();
return $this->responseSuccess(
$data,
'FoodItems has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function menuCategoryWiseSections(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId; // invalid restaurant header
}
try {
$categories = MenuCategory::with([
'menuSections' => function ($q) use ($restaurantId) {
$q->where('restaurant_id', $restaurantId)
->where('status', 1)
->with(['foodItems' => function ($q2) {
$q2->where('status', 1)
->with(['variants', 'defaultVariant']);
}]);
},
'foodItems' => function ($q) {
$q->where('status', 1)
->with(['variants', 'defaultVariant']);
},
])
->where('restaurant_id', $restaurantId)
->where('status', 1)
->get(['id', 'name']);
return $this->responseSuccess($categories, 'Menu fetched successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function chefs(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$data = User::where('restaurant_id', $restaurantId)
->where('status', 1)
->where('role_id', 7)
->get();
return $this->responseSuccess(
$data,
'Chef has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function tables(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$data = Table::where('restaurant_id', $restaurantId)
->where('status', 1)
->get();
return $this->responseSuccess(
$data,
'Table has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function tableReservation(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$validated = $request->validate([
'table_id' => 'required|integer|exists:tables,id',
'name' => 'nullable|string|max:255',
'phone' => 'nullable|string|max:255',
'email' => 'nullable|string|email|max:255',
'reservation_date' => 'required|date',
'start_time' => 'required|date_format:H:i',
// 'end_time' => 'required|date_format:H:i|after:start_time',
'people_count' => 'required|integer|min:1',
'status' => 'nullable|in:booked,free,upcoming,cancelled',
'note' => 'nullable|string',
]);
$validated['restaurant_id'] = $restaurantId;
// --- Handle customer ---
$customerId = null;
if (! empty($validated['email']) || ! empty($validated['phone'])) {
$customer = Customer::firstOrCreate(
[
'restaurant_id' => $restaurantId,
'email' => $validated['email'],
'phone' => $validated['phone'],
],
[
'name' => $validated['name'] ?? 'Guest',
'email' => $validated['email'] ?? null,
'phone' => $validated['phone'] ?? null,
'restaurant_id' => $restaurantId,
]
);
$customerId = $customer->id;
}
$validated['customer_id'] = $customerId;
// --- Start & end time logic ---
$start = $validated['start_time'];
$end = $validated['end_time'] ?? null;
// Parse start time
$startTime = Carbon::createFromFormat('H:i', $start);
// If end time is not provided, set +30 mins
if (! $end) {
$endTime = $startTime->copy()->addMinutes(30);
$validated['end_time'] = $endTime->format('H:i');
} else {
$endTime = Carbon::createFromFormat('H:i', $end);
// Ensure minimum 30 mins
if ($endTime->diffInMinutes($startTime) < 30) {
$endTime = $startTime->copy()->addMinutes(30);
$validated['end_time'] = $endTime->format('H:i');
}
}
// --- Store reservation ---
$data = $this->reservationRepository->store($validated);
return $this->responseSuccess($data, 'Reservation created successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function banners(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$data = Banner::where('restaurant_id', $restaurantId)
->where('status', 1)
->get();
return $this->responseSuccess(
$data,
'Banners has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function aboutUs(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$data = AboutUs::where('restaurant_id', $restaurantId)
->where('status', 1)
->first();
return $this->responseSuccess(
$data,
'AboutUs has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function academicImages(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$data['pageTitle'] = 'Academic Images';
$data['academicImages'] = AcademicImage::where('restaurant_id', $restaurantId)->get();
return $this->responseSuccess(
$data,
'AcademicImages has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function whyChooseUs(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$data = WhyChooseUs::select(
'id',
'restaurant_id',
'title',
'description',
'icon',
'created_at',
)
->where('restaurant_id', $restaurantId)
->get();
return $this->responseSuccess(
$data,
'WhyChooseUs has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function readyToJoinUs(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$data = ReadyToJoinUs::select(
'id',
'restaurant_id',
'title',
'description',
'icon',
'button_name',
'button_link',
'created_at',
)
->where('restaurant_id', $restaurantId)
->where('status', 1)
->get();
return $this->responseSuccess(
$data,
'ReadyToJoinUs has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function faq(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$data = FaqQuestion::where('restaurant_id', $restaurantId)
->where('status', 1)
->select('id', 'restaurant_id', 'question', 'answer')
->get();
return $this->responseSuccess(
$data,
'Faqs has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function privacyPolicy(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$data = Policy::where('restaurant_id', $restaurantId)->select('id', 'restaurant_id', 'type', 'description')->whereType(1)->first();
return $this->responseSuccess(
$data,
'Privacy Policy has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function cookiePolicy(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$data = Policy::where('restaurant_id', $restaurantId)
->where('status', 1)
->select('id', 'restaurant_id', 'type', 'description')->whereType(2)->first();
return $this->responseSuccess(
$data,
'Cookie Policy has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function termConditions(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$data = Policy::where('restaurant_id', $restaurantId)
->where('status', 1)
->select('id', 'restaurant_id', 'type', 'description')->whereType(3)->first();
return $this->responseSuccess(
$data,
'Terms & Conditions has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function ourHistory(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$data = OurHistory::where('restaurant_id', $restaurantId)
->select(
'restaurant_id',
'year',
'title',
'descriptions',
'status',
'created_by',
)->first();
return $this->responseSuccess(
$data,
'Our History has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function testimonials(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$data = Testimonial::select(
'restaurant_id',
'name',
'description',
'thumbnail_image',
'video_url',
'note',
'ratting',
'status',
'created_at',
'updated_at',
)
->where('restaurant_id', $restaurantId)
->where('status', 1)
->get();
return $this->responseSuccess(
$data,
'Testimonials has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function mobileAppSections(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$data = MobileAppSection::select(
'id',
'restaurant_id',
'title',
'heading',
'description',
'image',
'feature_one',
'feature_two',
'feature_three',
'play_store_link',
'app_store_link',
)
->where('restaurant_id', $restaurantId)
->where('status', 1)
->get();
return $this->responseSuccess(
$data,
'MobileAppSections has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function settings(Request $request): JsonResponse
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$allowedKeys = [
'restaurant_name',
'site_title',
'phone',
'email',
'language',
'google_map',
'address',
'timezone',
'academic_year',
'currency_symbol',
'logo',
'copyright_text',
'facebook_link',
'google_plus_link',
'youtube_link',
'whats_app_link',
'twitter_link',
'eiin_code',
'header_notice',
'exam_result_status',
'admission_display_status',
'guidance',
'academic_office',
'website_link',
'primary_color',
'secondary_color',
'primary_container_color',
'dark_primary_color',
'dark_secondary_color',
'dark_container_color',
'text_color',
'dark_text_color',
'sidebar_selected_bg_color',
'sidebar_selected_text_color',
];
$settings = DB::table('settings')
->whereIn('option_key', $allowedKeys)
->where('restaurant_id', $restaurantId)
->pluck('option_value', 'option_key');
return $this->responseSuccess(
$settings,
'Settings have been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function contactUs(ContactStoreRequest $request): JsonResponse
{
try {
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
// Create or get existing contact for this restaurant & email
$contact = Contact::firstOrCreate(
[
'restaurant_id' => $restaurantId,
'email' => $request->email,
],
[
'phone' => $request->phone ?? null,
'message' => $request->message ?? null,
]
);
return $this->responseSuccess(
[
'id' => $contact->id,
'email' => $contact->email,
],
'Contact form submitted successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function themes(Request $request)
{
$themes = Theme::where('status', 1)->get();
return $this->responseSuccess(
$themes,
'Themes get successfully.'
);
}
public function defaultTheme(Request $request)
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
$themeId = Restaurant::where('id', $restaurantId)
->value('theme_id'); // or default_theme_id if you use that
return response()->json([
'status' => true,
'default_theme_id' => $themeId,
]);
}
public function onboarding(OnboardingStoreRequest $request): JsonResponse
{
// Step 2: Handle other validation logic and file uploads
$validated = $request->validated();
// Handle the restaurant_logo file upload if it exists
$restaurantLogoPath = null;
if ($request->hasFile('restaurant_logo')) {
$restaurantLogoPath = fileUploader('restaurants/', 'png', $request->file('restaurant_logo'));
}
// Handle the user_avatar file upload if it exists
$userAvatarPath = null;
if ($request->hasFile('user_avatar')) {
$userAvatarPath = fileUploader('user_avatars/', 'png', $request->file('user_avatar'));
}
// Step 3: Save onboarding data
$onboarding = Onboarding::create([
'restaurant_name' => $validated['restaurant_name'],
'restaurant_email' => $validated['restaurant_email'],
'restaurant_phone' => $validated['restaurant_phone'],
'restaurant_domain' => $validated['restaurant_domain'],
'restaurant_type' => $validated['restaurant_type'],
'restaurant_address' => $validated['restaurant_address'],
'name' => $validated['name'],
'email' => $validated['email'],
'phone' => $validated['phone'],
'password' => Hash::make($validated['password']),
'restaurant_logo' => $restaurantLogoPath,
'user_avatar' => $userAvatarPath,
'status' => 'in_progress',
]);
// Create the new restaurant
$restaurant = Restaurant::create([
'name' => $onboarding->restaurant_name,
'restaurant_type' => $onboarding->restaurant_type,
'email' => $onboarding->restaurant_email,
'phone' => $onboarding->restaurant_phone,
'domain' => $onboarding->restaurant_domain,
'address' => $onboarding->restaurant_address,
'logo' => $onboarding->restaurant_logo,
]);
$user = RestaurantSetupService::setup($restaurant, [
'name' => $onboarding->name,
'email' => $onboarding->email,
'phone' => $onboarding->phone,
'password' => $onboarding->password,
'avatar' => $onboarding->avatar,
]);
$accessToken = $user->createToken('app')->accessToken;
// Return success response
return $this->responseSuccess(
[
'user' => $user,
'access_token' => $accessToken,
],
'Onboarding request submitted successfully.'
);
}
public function restaurantSchedules(Request $request)
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$perPage = $request->input('perPage', 15);
$sortBy = $request->input('sortBy', 'id');
$sortDir = $request->input('sortDir', 'desc');
$search = $request->input('search');
$query = RestaurantSchedule::query()
->with('times:id,restaurant_schedule_id,open_time,close_time')
->where('restaurant_id', $restaurantId);
// 🔍 Search Filter
if (! empty($search)) {
$query->where(function ($q) use ($search) {
$q->where('day', 'LIKE', "%{$search}%")
->orWhere('start_date', 'LIKE', "%{$search}%")
->orWhere('end_date', 'LIKE', "%{$search}%");
});
}
// 🔽 Sorting
$query->orderBy($sortBy, $sortDir);
// 📄 Pagination
$data = $query->get();
return $this->responseSuccess($data, 'Restaurant schedule fetched successfully.');
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function reservationUnavailability(Request $request)
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$data = ReservationUnavailable::select(
'id',
'restaurant_id',
'table_id',
'date',
'start_time',
'end_time',
'reason'
)
->with('table')
->where('restaurant_id', $restaurantId)
->get();
return $this->responseSuccess(
$data,
'Restaurant Unavailability has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function reservationSettings(Request $request)
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$data = ReservationSetting::where('restaurant_id', $restaurantId)->get();
return $this->responseSuccess(
$data,
'Reservation Settings has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function cmsSections(Request $request)
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$data = CMSSection::where('restaurant_id', $restaurantId)
->orderBy('serial', 'asc')
->get();
return $this->responseSuccess(
$data,
'Restaurant CMS Sections has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function restaurantImageSAASSetting(Request $request)
{
try {
$data = RestaurantImageSAASSetting::first();
return $this->responseSuccess(
$data,
'Restaurant SAAS Settings Image has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function restaurantImageSetting(Request $request)
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$data = RestaurantImageSetting::where('restaurant_id', $restaurantId)->first();
return $this->responseSuccess(
$data,
'Restaurant Settings Image has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function getCoupons(Request $request)
{
$restaurantId = $this->getRestaurantIdFromHeader($request);
if ($restaurantId instanceof JsonResponse) {
return $restaurantId;
}
try {
$data = Coupon::where('restaurant_id', $restaurantId)->first();
return $this->responseSuccess(
$data,
'Coupons has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
private function getRestaurantIdFromHeader(Request $request): mixed
{
$domain = $request->header('X-Domain'); // Custom header key (Change if needed)
if (! $domain) {
return $this->responseError([], 'Domain header is missing.', 400);
}
$restaurantResponse = RestaurantHelper::getRestaurantIdByDomain($domain);
if (! $restaurantResponse['status']) {
return $this->responseError([], $restaurantResponse['error'], 404);
}
return $restaurantResponse['restaurant_id'];
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace Modules\Frontend\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Traits\RequestSanitizerTrait;
use Exception;
use Illuminate\Http\JsonResponse;
use Modules\Frontend\Http\Requests\MobileAppSection\MobileAppSectionStoreRequest;
use Modules\Frontend\Http\Requests\MobileAppSection\MobileAppSectionUpdateRequest;
use Modules\Frontend\Repositories\MobileAppSectionRepository;
class MobileAppSectionController extends Controller
{
use RequestSanitizerTrait;
public function __construct(private MobileAppSectionRepository $faq) {}
public function index(): JsonResponse
{
try {
return $this->responseSuccess(
$this->faq->getAll(request()->all()),
'MobileAppSection has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function store(MobileAppSectionStoreRequest $request): JsonResponse
{
try {
return $this->responseSuccess(
$this->faq->create($request->all()),
'MobileAppSection has been created successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function show(int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->faq->getById($id),
'MobileAppSection has been fetched successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function update(MobileAppSectionUpdateRequest $request, int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->faq->update($id, $this->getUpdateRequest($request)),
'MobileAppSection has been updated successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function destroy(int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->faq->delete($id),
'MobileAppSection has been deleted successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace Modules\Frontend\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Traits\RequestSanitizerTrait;
use Exception;
use Illuminate\Http\JsonResponse;
use Modules\Frontend\Http\Requests\Policy\PolicyStoreRequest;
use Modules\Frontend\Http\Requests\Policy\PolicyUpdateRequest;
use Modules\Frontend\Repositories\PolicyRepository;
class PolicyController extends Controller
{
use RequestSanitizerTrait;
public function __construct(private PolicyRepository $policy) {}
public function index(): JsonResponse
{
try {
return $this->responseSuccess(
$this->policy->getAll(request()->all()),
'Policy has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function store(PolicyStoreRequest $request): JsonResponse
{
try {
return $this->responseSuccess(
$this->policy->create($request->all()),
'Policy has been created successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function show(int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->policy->getById($id),
'Policy has been fetched successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function update(PolicyUpdateRequest $request, int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->policy->update($id, $this->getUpdateRequest($request)),
'Policy has been updated successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function destroy(int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->policy->delete($id),
'Policy has been deleted successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace Modules\Frontend\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Traits\RequestSanitizerTrait;
use Exception;
use Illuminate\Http\JsonResponse;
use Modules\Frontend\Http\Requests\ReadyToJoinUs\ReadyToJoinUsStoreRequest;
use Modules\Frontend\Http\Requests\ReadyToJoinUs\ReadyToJoinUsUpdateRequest;
use Modules\Frontend\Repositories\ReadyToJoinUsRepository;
class ReadyToJoinUsController extends Controller
{
use RequestSanitizerTrait;
public function __construct(private ReadyToJoinUsRepository $faq) {}
public function index(): JsonResponse
{
try {
return $this->responseSuccess(
$this->faq->getAll(request()->all()),
'ReadyToJoinUs has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function store(ReadyToJoinUsStoreRequest $request): JsonResponse
{
try {
return $this->responseSuccess(
$this->faq->create($request->all()),
'ReadyToJoinUs has been created successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function show(int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->faq->getById($id),
'ReadyToJoinUs has been fetched successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function update(ReadyToJoinUsUpdateRequest $request, int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->faq->update($id, $this->getUpdateRequest($request)),
'ReadyToJoinUs has been updated successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function destroy(int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->faq->delete($id),
'ReadyToJoinUs has been deleted successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace Modules\Frontend\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Traits\RequestSanitizerTrait;
use Exception;
use Illuminate\Http\JsonResponse;
use Modules\Frontend\Http\Requests\Testimonial\TestimonialStoreRequest;
use Modules\Frontend\Http\Requests\Testimonial\TestimonialUpdateRequest;
use Modules\Frontend\Repositories\TestimonialRepository;
class TestimonialsController extends Controller
{
use RequestSanitizerTrait;
public function __construct(private TestimonialRepository $testimonial) {}
public function index(): JsonResponse
{
try {
return $this->responseSuccess(
$this->testimonial->getAll(request()->all()),
'Testimonial has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function store(TestimonialStoreRequest $request): JsonResponse
{
try {
return $this->responseSuccess(
$this->testimonial->create($request->all()),
'Testimonial has been created successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function show(int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->testimonial->getById($id),
'Testimonial has been fetched successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function update(TestimonialUpdateRequest $request, int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->testimonial->update($id, $this->getUpdateRequest($request)),
'Testimonial has been updated successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function destroy(int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->testimonial->delete($id),
'Testimonial has been deleted successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
}

View File

@@ -0,0 +1,78 @@
<?php
namespace Modules\Frontend\Http\Controllers\API;
use App\Http\Controllers\Controller;
use App\Traits\RequestSanitizerTrait;
use Exception;
use Illuminate\Http\JsonResponse;
use Modules\Frontend\Http\Requests\WhyChooseUs\WhyChooseUsStoreRequest;
use Modules\Frontend\Http\Requests\WhyChooseUs\WhyChooseUsUpdateRequest;
use Modules\Frontend\Repositories\WhyChooseUsRepository;
class WhyChooseUsController extends Controller
{
use RequestSanitizerTrait;
public function __construct(private WhyChooseUsRepository $faq) {}
public function index(): JsonResponse
{
try {
return $this->responseSuccess(
$this->faq->getAll(request()->all()),
'WhyChooseUs has been fetched successfully.'
);
} catch (Exception $e) {
return $this->responseError([], $e->getMessage());
}
}
public function store(WhyChooseUsStoreRequest $request): JsonResponse
{
try {
return $this->responseSuccess(
$this->faq->create($request->all()),
'WhyChooseUs has been created successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function show(int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->faq->getById($id),
'WhyChooseUs has been fetched successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function update(WhyChooseUsUpdateRequest $request, int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->faq->update($id, $this->getUpdateRequest($request)),
'WhyChooseUs has been updated successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
public function destroy(int $id): JsonResponse
{
try {
return $this->responseSuccess(
$this->faq->delete($id),
'WhyChooseUs has been deleted successfully.'
);
} catch (Exception $exception) {
return $this->responseError([], $exception->getMessage(), $exception->getCode());
}
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace Modules\Frontend\Http\Requests\AboutUs;
use Illuminate\Foundation\Http\FormRequest;
class AboutUsStoreRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'title' => 'required|string',
'description' => 'nullable|string',
'image' => 'nullable|image',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace Modules\Frontend\Http\Requests\AboutUs;
use Illuminate\Foundation\Http\FormRequest;
class AboutUsUpdateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'title' => 'required|string',
'description' => 'nullable|string',
'image' => 'nullable|image',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Modules\Frontend\Http\Requests\AcademicImage;
use Illuminate\Foundation\Http\FormRequest;
class AcademicImageStoreRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'title' => 'required|string|max:191',
'heading' => 'nullable|string|max:191',
'description' => 'nullable|string|max:255',
'image' => 'required|image',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Modules\Frontend\Http\Requests\AcademicImage;
use Illuminate\Foundation\Http\FormRequest;
class AcademicImageUpdateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'title' => 'required|string|max:191',
'heading' => 'nullable|string|max:191',
'description' => 'nullable|string|max:255',
'image' => 'required|image',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Modules\Frontend\Http\Requests\Banner;
use Illuminate\Foundation\Http\FormRequest;
class BannerStoreRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'title' => 'required|string|max:191',
'description' => 'nullable|string|max:255',
'button_name' => 'nullable|string|max:20',
'button_link' => 'nullable|string|max:100',
'image' => 'required|image',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Modules\Frontend\Http\Requests\Banner;
use Illuminate\Foundation\Http\FormRequest;
class BannerUpdateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'title' => 'required|string|max:191',
'description' => 'nullable|string|max:255',
'button_name' => 'nullable|string|max:20',
'button_link' => 'nullable|string|max:100',
'image' => 'nullable|image',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Modules\Frontend\Http\Requests\CMSSection;
use Illuminate\Foundation\Http\FormRequest;
class CMSSectionStoreRequest extends FormRequest
{
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:100'],
'title' => ['nullable', 'string', 'max:200'],
'description' => ['nullable', 'string'],
'bg_image' => ['nullable', 'image', 'mimes:png,jpg,jpeg,webp', 'max:4096'],
'serial' => ['required', 'integer', 'min:1'], // used for drag-drop order
];
}
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Modules\Frontend\Http\Requests\CMSSection;
use Illuminate\Foundation\Http\FormRequest;
class CMSSectionUpdateRequest extends FormRequest
{
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:100'],
'title' => ['nullable', 'string', 'max:200'],
'description' => ['nullable', 'string'],
'bg_image' => ['nullable', 'image', 'mimes:png,jpg,jpeg,webp', 'max:4096'],
'serial' => ['required', 'integer', 'min:1'], // used for drag-drop order
];
}
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,29 @@
<?php
namespace Modules\Frontend\Http\Requests\Contact;
use Illuminate\Foundation\Http\FormRequest;
class ContactStoreRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'email' => 'required|string|email|max:191',
'name' => 'nullable|string|max:191',
'phone' => 'nullable|string|max:255',
'message' => 'nullable|string|max:191',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Modules\Frontend\Http\Requests\Coupon;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class CouponStoreRequest extends FormRequest
{
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:100'],
'added_by' => 'nullable|string|max:255',
'discount_type' => ['required', Rule::in(['fixed', 'percentage', 'free_delivery'])],
'coupon_type' => ['required', Rule::in(['restaurant', 'hotel', 'both'])],
'amount' => [
'required_if:discount_type,fixed,percentage',
'nullable',
'numeric',
'min:0',
'max:1000000', // optional upper limit
],
'valid_from' => 'nullable|date|before_or_equal:valid_to',
'valid_to' => 'nullable|date|after_or_equal:valid_from',
'usage_limit' => 'nullable|integer|min:0',
'max_uses_per_customer' => 'nullable|integer|min:0',
'min_order_amount' => 'nullable|numeric|min:0',
'image' => 'nullable',
'source' => 'nullable|string|max:255',
'status' => 'nullable|integer|in:0,1', // 1=Active, 0=Inactive
];
}
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Modules\Frontend\Http\Requests\Coupon;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class CouponUpdateRequest extends FormRequest
{
public function rules(): array
{
return [
'name' => ['required', 'string', 'max:100'],
'added_by' => 'nullable|string|max:255',
'discount_type' => ['required', Rule::in(['fixed', 'percentage', 'free_delivery'])],
'coupon_type' => ['required', Rule::in(['restaurant', 'hotel', 'both'])],
'amount' => [
'required_if:discount_type,fixed,percentage',
'nullable',
'numeric',
'min:0',
'max:1000000', // optional upper limit
],
'valid_from' => 'nullable|date|before_or_equal:valid_to',
'valid_to' => 'nullable|date|after_or_equal:valid_from',
'usage_limit' => 'nullable|integer|min:0',
'max_uses_per_customer' => 'nullable|integer|min:0',
'min_order_amount' => 'nullable|numeric|min:0',
'image' => 'nullable',
'source' => 'nullable|string|max:255',
'status' => 'nullable|integer|in:0,1', // 1=Active, 0=Inactive
];
}
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Modules\Frontend\Http\Requests\Faq;
use Illuminate\Foundation\Http\FormRequest;
class FaqStoreRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'question' => 'required|string|max:191',
'answer' => 'required|string|max:500',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Modules\Frontend\Http\Requests\Faq;
use Illuminate\Foundation\Http\FormRequest;
class FaqUpdateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'question' => 'required|string|max:191',
'answer' => 'required|string|max:500',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Modules\Frontend\Http\Requests\MobileAppSection;
use Illuminate\Foundation\Http\FormRequest;
class MobileAppSectionStoreRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'title' => 'required|string|max:255',
'description' => 'nullable|string|max:1000',
'heading' => 'nullable|string',
'string' => 'nullable|string',
'feature_one' => 'nullable|string',
'feature_two' => 'nullable|string',
'feature_three' => 'nullable|string',
'play_store_link' => 'nullable|string',
'app_store_link' => 'nullable|string',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Modules\Frontend\Http\Requests\MobileAppSection;
use Illuminate\Foundation\Http\FormRequest;
class MobileAppSectionUpdateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'title' => 'required|string|max:255',
'description' => 'nullable|string|max:1000',
'heading' => 'nullable|string',
'string' => 'nullable|string',
'feature_one' => 'nullable|string',
'feature_two' => 'nullable|string',
'feature_three' => 'nullable|string',
'play_store_link' => 'nullable|string',
'app_store_link' => 'nullable|string',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace Modules\Frontend\Http\Requests\Onboarding;
use Illuminate\Foundation\Http\FormRequest;
class OnboardingStoreRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'restaurant_name' => 'required|string|max:100',
'restaurant_email' => 'required|email|max:255|unique:restaurants,email,except,id',
'restaurant_phone' => 'required|string|max:15|unique:restaurants,phone,except,id',
'restaurant_domain' => 'nullable|string|max:100|unique:restaurants,domain,except,id',
'restaurant_type' => 'nullable|string|max:100',
'restaurant_address' => 'nullable|string|max:100',
'restaurant_logo' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
'name' => 'required|string|max:100',
'email' => 'required|email|max:255|unique:users,email,except,id',
'phone' => 'required|string|max:50',
'password' => 'required|string|min:6',
'avatar' => 'nullable|image|mimes:jpeg,png,jpg,gif|max:2048',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Modules\Frontend\Http\Requests\Policy;
use Illuminate\Foundation\Http\FormRequest;
class PolicyStoreRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'type' => 'required|string',
'description' => 'required|string',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,27 @@
<?php
namespace Modules\Frontend\Http\Requests\Policy;
use Illuminate\Foundation\Http\FormRequest;
class PolicyUpdateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'type' => 'required|string',
'description' => 'required|string',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Modules\Frontend\Http\Requests\ReadyToJoinUs;
use Illuminate\Foundation\Http\FormRequest;
class ReadyToJoinUsStoreRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'title' => 'required|string|max:191',
'description' => 'nullable|string|max:255',
'icon' => 'nullable|image',
'button_name' => 'nullable|string',
'button_link' => 'nullable|string',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Modules\Frontend\Http\Requests\ReadyToJoinUs;
use Illuminate\Foundation\Http\FormRequest;
class ReadyToJoinUsUpdateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'title' => 'required|string|max:191',
'description' => 'nullable|string|max:255',
'icon' => 'nullable|image',
'button_name' => 'nullable|string',
'button_link' => 'nullable|string',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Modules\Frontend\Http\Requests\Testimonial;
use Illuminate\Foundation\Http\FormRequest;
class TestimonialStoreRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'name' => 'required|string|max:255',
'description' => 'required|string|max:1000',
'thumbnail_image' => 'nullable',
'video_url' => 'nullable|string|max:255',
'note' => 'nullable|string|max:500',
'ratting' => 'required',
'status' => 'nullable|in:0,1', // 1=Active, 2=Inactive
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,32 @@
<?php
namespace Modules\Frontend\Http\Requests\Testimonial;
use Illuminate\Foundation\Http\FormRequest;
class TestimonialUpdateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'name' => 'required|string|max:255',
'description' => 'required|string|max:1000',
'thumbnail_image' => 'nullable',
'video_url' => 'nullable|string|max:255',
'note' => 'nullable|string|max:500',
'ratting' => 'required',
'status' => 'nullable|in:0,1', // 1=Active, 2=Inactive
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace Modules\Frontend\Http\Requests\WhyChooseUs;
use Illuminate\Foundation\Http\FormRequest;
class WhyChooseUsStoreRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'title' => 'required|string|max:191',
'description' => 'nullable|string|max:255',
'icon' => 'nullable|image',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace Modules\Frontend\Http\Requests\WhyChooseUs;
use Illuminate\Foundation\Http\FormRequest;
class WhyChooseUsUpdateRequest extends FormRequest
{
/**
* Get the validation rules that apply to the request.
*/
public function rules(): array
{
return [
'title' => 'required|string|max:191',
'description' => 'nullable|string|max:255',
'icon' => 'nullable|image',
];
}
/**
* Determine if the user is authorized to make this request.
*/
public function authorize(): bool
{
return true;
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Modules\Frontend\Models;
use Illuminate\Database\Eloquent\Model;
class AboutUs extends Model
{
protected $table = 'about_us';
public const TABLE_NAME = 'about_us';
protected $fillable = [
'restaurant_id',
'title',
'description',
'image',
'status',
'created_by',
'created_at',
'updated_at',
];
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Modules\Frontend\Models;
use Illuminate\Database\Eloquent\Model;
class AcademicImage extends Model
{
protected $table = 'academic_images';
public const TABLE_NAME = 'academic_images';
protected $fillable = [
'restaurant_id',
'title',
'heading',
'description',
'image',
'status',
'created_by',
'created_at',
'updated_at',
];
}

View File

@@ -0,0 +1,25 @@
<?php
namespace Modules\Frontend\Models;
use Illuminate\Database\Eloquent\Model;
class Banner extends Model
{
protected $table = 'banners';
public const TABLE_NAME = 'banners';
protected $fillable = [
'restaurant_id',
'title',
'description',
'button_name',
'button_link',
'image',
'status',
'created_by',
'created_at',
'updated_at',
];
}

View File

@@ -0,0 +1,25 @@
<?php
namespace Modules\Frontend\Models;
use Illuminate\Database\Eloquent\Model;
class CMSSection extends Model
{
protected $fillable = [
'restaurant_id',
'name',
'serial',
'title',
'description',
'image',
'status',
'created_at',
'updated_at',
'deleted_at',
];
public const TABLE_NAME = 'c_m_s_sections';
protected $table = self::TABLE_NAME;
}

View File

@@ -0,0 +1,24 @@
<?php
namespace Modules\Frontend\Models;
use Illuminate\Database\Eloquent\Model;
class Contact extends Model
{
protected $table = 'frontend_contacts';
public const TABLE_NAME = 'frontend_contacts';
/**
* The attributes that are mass assignable.
*/
protected $fillable = [
'restaurant_id',
'name',
'phone',
'email',
'subject',
'message',
];
}

View File

@@ -0,0 +1,84 @@
<?php
namespace Modules\Frontend\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Modules\Authentication\Models\User;
class Coupon extends Model
{
protected $fillable = [
'restaurant_id',
'user_id',
'name',
'added_by',
'discount_type',
'coupon_type',
'amount',
'valid_from',
'valid_to',
'usage_limit',
'max_uses_per_customer',
'min_order_amount',
'image',
'source',
'status',
'created_at',
'updated_at',
'deleted_at',
];
protected $casts = [
'amount' => 'decimal:2',
'min_order_amount' => 'decimal:2',
'valid_from' => 'datetime',
'valid_to' => 'datetime',
'status' => 'integer',
];
public const TABLE_NAME = 'coupons';
protected $table = self::TABLE_NAME;
public function user(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id');
}
public function usages(): HasMany
{
return $this->hasMany(CouponUsage::class, 'coupon_id');
}
// Scopes
public function scopeActive($query): mixed
{
return $query->where('status', 1)
->where(function ($q) {
$q->whereNull('valid_from')->orWhere('valid_from', '<=', now());
})
->where(function ($q) {
$q->whereNull('valid_to')->orWhere('valid_to', '>=', now());
});
}
// Helper: Calculate discount for an order
public function calculateDiscount(float $orderTotal): float
{
if ($this->discount_type === 'fixed') {
return min($this->amount, $orderTotal);
}
if ($this->discount_type === 'percentage') {
return round($orderTotal * ($this->amount / 100), 2);
}
if ($this->discount_type === 'free_delivery') {
return 0; // discount only applies to delivery
}
return 0;
}
}

View File

@@ -0,0 +1,19 @@
<?php
namespace Modules\Frontend\Models;
use Illuminate\Database\Eloquent\Model;
class CouponUsage extends Model
{
protected $fillable = [
'restaurant_id',
'coupon_id',
'customer_id',
'order_id',
];
public const TABLE_NAME = 'coupon_usages';
protected $table = self::TABLE_NAME;
}

View File

@@ -0,0 +1,22 @@
<?php
namespace Modules\Frontend\Models;
use Illuminate\Database\Eloquent\Model;
class FaqQuestion extends Model
{
protected $table = 'faq_questions';
public const TABLE_NAME = 'faq_questions';
protected $fillable = [
'restaurant_id',
'question',
'answer',
'status',
'created_by',
'created_at',
'updated_at',
];
}

View File

@@ -0,0 +1,28 @@
<?php
namespace Modules\Frontend\Models;
use Illuminate\Database\Eloquent\Model;
class MobileAppSection extends Model
{
protected $table = 'mobile_app_sections';
public const TABLE_NAME = 'mobile_app_sections';
/**
* The attributes that are mass assignable.
*/
protected $fillable = [
'restaurant_id',
'title',
'heading',
'description',
'image',
'feature_one',
'feature_two',
'feature_three',
'play_store_link',
'app_store_link',
];
}

View File

@@ -0,0 +1,75 @@
<?php
namespace Modules\Frontend\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use Modules\Authentication\Models\User;
class Onboarding extends Model
{
use HasFactory, SoftDeletes;
/**
* The attributes that are mass assignable.
*/
protected $fillable = [
'restaurant_id', // 🏢 Restaurant Information
'restaurant_name',
'restaurant_email',
'restaurant_phone',
'restaurant_domain',
'restaurant_type',
'restaurant_address',
'restaurant_logo',
// 👤 Owner / User Information
'name',
'email',
'phone',
'password',
'avatar',
// 💰 Financial / Status
'amount',
'status',
'approved_by',
'approved_at',
];
/**
* The attributes that should be cast.
*/
protected $casts = [
'approved_at' => 'datetime',
'amount' => 'decimal:2',
];
// ✅ The user who approved the onboarding
public function approver(): BelongsTo
{
return $this->belongsTo(User::class, 'approved_by');
}
// Automatically hash password when setting it
public function setPasswordAttribute($value): void
{
if (! empty($value)) {
$this->attributes['password'] = bcrypt($value);
}
}
// Scope to get only approved onboardings
public function scopeApproved($query): mixed
{
return $query->where('status', 'approved');
}
// Scope to get pending onboardings
public function scopePending($query): mixed
{
return $query->where('status', 'pending');
}
}

View File

@@ -0,0 +1,23 @@
<?php
namespace Modules\Frontend\Models;
use Illuminate\Database\Eloquent\Model;
class OurHistory extends Model
{
protected $table = 'our_histories';
public const TABLE_NAME = 'our_histories';
protected $fillable = [
'restaurant_id',
'year',
'title',
'descriptions',
'status',
'created_by',
'created_at',
'updated_at',
];
}

View File

@@ -0,0 +1,25 @@
<?php
namespace Modules\Frontend\Models;
use Illuminate\Database\Eloquent\Model;
class Page extends Model
{
/**
* The attributes that are mass assignable.
*/
protected $fillable = [
'restaurant_id',
'title',
'slug',
'type',
'content',
'meta_data',
'seo_meta_keywords',
'seo_meta_description',
'page_status',
'page_template',
'author_id',
];
}

View File

@@ -0,0 +1,22 @@
<?php
namespace Modules\Frontend\Models;
use Illuminate\Database\Eloquent\Model;
class Policy extends Model
{
protected $table = 'policies';
public const TABLE_NAME = 'policies';
protected $fillable = [
'restaurant_id',
'type',
'description',
'status',
'created_by',
'created_at',
'updated_at',
];
}

View File

@@ -0,0 +1,22 @@
<?php
namespace Modules\Frontend\Models;
use Illuminate\Database\Eloquent\Model;
class ReadyToJoinUs extends Model
{
protected $table = 'ready_to_join_us';
public const TABLE_NAME = 'ready_to_join_us';
/**
* The attributes that are mass assignable.
*/
protected $fillable = [
'restaurant_id',
'title',
'description',
'icon',
];
}

View File

@@ -0,0 +1,25 @@
<?php
namespace Modules\Frontend\Models;
use Illuminate\Database\Eloquent\Model;
class Testimonial extends Model
{
protected $table = 'testimonials';
public const TABLE_NAME = 'testimonials';
protected $fillable = [
'restaurant_id',
'name',
'description',
'thumbnail_image',
'video_url',
'note',
'ratting',
'status',
'created_at',
'updated_at',
];
}

View File

@@ -0,0 +1,16 @@
<?php
namespace Modules\Frontend\Models;
use Illuminate\Database\Eloquent\Model;
class Theme extends Model
{
protected $fillable = [
'restaurant_id',
'category',
'name',
'icon',
'description',
];
}

View File

@@ -0,0 +1,22 @@
<?php
namespace Modules\Frontend\Models;
use Illuminate\Database\Eloquent\Model;
class WhyChooseUs extends Model
{
protected $table = 'why_choose_us';
public const TABLE_NAME = 'why_choose_us';
/**
* The attributes that are mass assignable.
*/
protected $fillable = [
'restaurant_id',
'title',
'description',
'icon',
];
}

View File

@@ -0,0 +1,30 @@
<?php
namespace Modules\Frontend\Providers;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event handler mappings for the application.
*
* @var array<string, array<int, string>>
*/
protected $listen = [];
/**
* Indicates if events should be discovered.
*
* @var bool
*/
protected static $shouldDiscoverEvents = true;
/**
* Configure the proper event listeners for email verification.
*/
protected function configureEmailVerification(): void
{
//
}
}

View File

@@ -0,0 +1,135 @@
<?php
namespace Modules\Frontend\Providers;
use Illuminate\Support\Facades\Blade;
use Illuminate\Support\ServiceProvider;
use Nwidart\Modules\Traits\PathNamespace;
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
class FrontendServiceProvider extends ServiceProvider
{
use PathNamespace;
protected string $name = 'Frontend';
protected string $nameLower = 'frontend';
/**
* Boot the application events.
*/
public function boot(): void
{
$this->registerCommands();
$this->registerCommandSchedules();
$this->registerTranslations();
$this->registerConfig();
$this->registerViews();
$this->loadMigrationsFrom(module_path($this->name, 'database/migrations'));
}
/**
* Register the service provider.
*/
public function register(): void
{
$this->app->register(EventServiceProvider::class);
$this->app->register(RouteServiceProvider::class);
}
/**
* Register commands in the format of Command::class
*/
protected function registerCommands(): void
{
// $this->commands([]);
}
/**
* Register command Schedules.
*/
protected function registerCommandSchedules(): void
{
// $this->app->booted(function () {
// $schedule = $this->app->make(Schedule::class);
// $schedule->command('inspire')->hourly();
// });
}
/**
* Register translations.
*/
public function registerTranslations(): void
{
$langPath = resource_path('lang/modules/'.$this->nameLower);
if (is_dir($langPath)) {
$this->loadTranslationsFrom($langPath, $this->nameLower);
$this->loadJsonTranslationsFrom($langPath);
} else {
$this->loadTranslationsFrom(module_path($this->name, 'lang'), $this->nameLower);
$this->loadJsonTranslationsFrom(module_path($this->name, 'lang'));
}
}
/**
* Register config.
*/
protected function registerConfig(): void
{
$relativeConfigPath = config('modules.paths.generator.config.path');
$configPath = module_path($this->name, $relativeConfigPath);
if (is_dir($configPath)) {
$iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($configPath));
foreach ($iterator as $file) {
if ($file->isFile() && $file->getExtension() === 'php') {
$relativePath = str_replace($configPath.DIRECTORY_SEPARATOR, '', $file->getPathname());
$configKey = $this->nameLower.'.'.str_replace([DIRECTORY_SEPARATOR, '.php'], ['.', ''], $relativePath);
$key = ($relativePath === 'config.php') ? $this->nameLower : $configKey;
$this->publishes([$file->getPathname() => config_path($relativePath)], 'config');
$this->mergeConfigFrom($file->getPathname(), $key);
}
}
}
}
/**
* Register views.
*/
public function registerViews(): void
{
$viewPath = resource_path('views/modules/'.$this->nameLower);
$sourcePath = module_path($this->name, 'resources/views');
$this->publishes([$sourcePath => $viewPath], ['views', $this->nameLower.'-module-views']);
$this->loadViewsFrom(array_merge($this->getPublishableViewPaths(), [$sourcePath]), $this->nameLower);
$componentNamespace = $this->module_namespace($this->name, $this->app_path(config('modules.paths.generator.component-class.path')));
Blade::componentNamespace($componentNamespace, $this->nameLower);
}
/**
* Get the services provided by the provider.
*/
public function provides(): array
{
return [];
}
private function getPublishableViewPaths(): array
{
$paths = [];
foreach (config('view.paths') as $path) {
if (is_dir($path.'/modules/'.$this->nameLower)) {
$paths[] = $path.'/modules/'.$this->nameLower;
}
}
return $paths;
}
}

View File

@@ -0,0 +1,39 @@
<?php
namespace Modules\Frontend\Providers;
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
use Illuminate\Support\Facades\Route;
class RouteServiceProvider extends ServiceProvider
{
protected string $name = 'Frontend';
/**
* Called before routes are registered.
*
* Register any model bindings or pattern based filters.
*/
public function boot(): void
{
parent::boot();
}
/**
* Define the routes for the application.
*/
public function map(): void
{
$this->mapApiRoutes();
}
/**
* Define the "api" routes for the application.
*
* These routes are typically stateless.
*/
protected function mapApiRoutes(): void
{
Route::middleware('api')->prefix('api')->name('api.')->group(module_path($this->name, '/routes/api.php'));
}
}

View File

@@ -0,0 +1,30 @@
{
"name": "nwidart/frontend",
"description": "",
"authors": [
{
"name": "Nicolas Widart",
"email": "n.widart@gmail.com"
}
],
"extra": {
"laravel": {
"providers": [],
"aliases": {
}
}
},
"autoload": {
"psr-4": {
"Modules\\Frontend\\": "app/",
"Modules\\Frontend\\Database\\Factories\\": "database/factories/",
"Modules\\Frontend\\Database\\Seeders\\": "database/seeders/"
}
},
"autoload-dev": {
"psr-4": {
"Modules\\Frontend\\Tests\\": "tests/"
}
}
}

View File

@@ -0,0 +1,5 @@
<?php
return [
'name' => 'Frontend',
];

View File

@@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('faq_questions', function (Blueprint $table) {
$table->id();
$table->foreignId('restaurant_id')->constrained('restaurants')->cascadeOnDelete();
$table->string('question', 255);
$table->longText('answer')->nullable();
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
$table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('faq_questions');
}
};

View File

@@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('policies', function (Blueprint $table) {
$table->id();
$table->foreignId('restaurant_id')->constrained('restaurants')->cascadeOnDelete();
$table->string('type')->comment('1=privacy, 2=cookie, 3=terms & conditions');
$table->longText('description');
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
$table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('policies');
}
};

View File

@@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('academic_images', function (Blueprint $table) {
$table->id();
$table->foreignId('restaurant_id')->constrained('restaurants')->cascadeOnDelete();
$table->string('title')->nullable();
$table->text('heading')->nullable();
$table->longText('description')->nullable();
$table->string('image')->nullable();
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
$table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('academic_images');
}
};

View File

@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('about_us', function (Blueprint $table) {
$table->id();
$table->foreignId('restaurant_id')->constrained('restaurants')->cascadeOnDelete();
$table->string('title', 255)->index();
$table->longText('description')->nullable();
$table->string('image', 255)->nullable();
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
$table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('about_us');
}
};

View File

@@ -0,0 +1,38 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('our_histories', function (Blueprint $table) {
$table->id();
$table->foreignId('restaurant_id')->constrained('restaurants')->cascadeOnDelete();
$table->year('year');
$table->string('title', 255);
$table->text('descriptions')->nullable();
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
$table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('our_histories');
}
};

View File

@@ -0,0 +1,38 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('banners', function (Blueprint $table) {
$table->id();
$table->foreignId('restaurant_id')->constrained('restaurants')->cascadeOnDelete();
$table->string('title', 255)->nullable();
$table->text('description')->nullable();
$table->string('button_name', 100)->nullable();
$table->string('button_link', 500)->nullable();
$table->string('button_two_name', 100)->nullable();
$table->string('button_two_link', 500)->nullable();
$table->string('image', 255)->nullable();
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
$table->foreignId('created_by')->nullable()->constrained('users')->nullOnDelete();
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('banners');
}
};

View File

@@ -0,0 +1,36 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('testimonials', function (Blueprint $table) {
$table->id();
$table->foreignId('restaurant_id')->constrained('restaurants')->cascadeOnDelete();
$table->string('name');
$table->longText('description');
$table->string('thumbnail_image')->nullable();
$table->string('video_url')->nullable();
$table->string('note')->nullable();
$table->integer('ratting')->default(0);
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('testimonials');
}
};

View File

@@ -0,0 +1,37 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('frontend_contacts', function (Blueprint $table) {
$table->id();
$table->foreignId('restaurant_id')->constrained('restaurants')->cascadeOnDelete();
$table->string('email');
$table->string('name')->nullable();
$table->string('phone')->nullable();
$table->string('subject')->nullable();
$table->text('message')->nullable();
$table->timestamps();
$table->softDeletes();
// Unique per restaurant + email only
$table->unique(['restaurant_id', 'email'], 'restaurant_email_unique');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('frontend_contacts');
}
};

View File

@@ -0,0 +1,42 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('pages', function (Blueprint $table) {
$table->id();
$table->foreignId('restaurant_id')->constrained('restaurants')->cascadeOnDelete();
$table->string('title');
$table->string('slug');
$table->string('type');
$table->text('content')->nullable();
$table->string('meta_data')->nullable();
$table->text('seo_meta_keywords')->nullable();
$table->text('seo_meta_description')->nullable();
$table->string('page_status')->default('draft');
$table->string('page_template')->default('default');
$table->unsignedBigInteger('author_id')->index();
$table->timestamps();
$table->softDeletes();
// Combine unique constraint
$table->unique(['restaurant_id', 'slug'], 'unique_combination');
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('pages');
}
};

View File

@@ -0,0 +1,52 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('onboardings', function (Blueprint $table) {
$table->id();
// 🏢 Restaurant Information
$table->string('restaurant_name');
$table->string('restaurant_email')->nullable();
$table->string('restaurant_phone', 20)->nullable();
$table->string('restaurant_domain');
$table->string('restaurant_type')->nullable();
$table->string('restaurant_address');
$table->string('restaurant_logo')->nullable();
// 👤 Owner / User Information
$table->string('name');
$table->string('email');
$table->string('phone', 20)->nullable();
$table->string('password');
$table->string('avatar')->nullable();
$table->decimal('amount', 10, 2)->default(0);
$table->enum('status', ['pending', 'in_progress', 'documents_submitted', 'approved', 'rejected', 'hold'])->default('pending');
$table->foreignId('approved_by')->nullable()->constrained('users')->nullOnDelete();
$table->timestamp('approved_at')->nullable();
$table->timestamps();
$table->softDeletes();
// ⚡ Indexes
$table->index(['status']);
$table->index(['restaurant_name']);
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('onboardings');
}
};

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('why_choose_us', function (Blueprint $table) {
$table->id();
$table->foreignId('restaurant_id')->constrained('restaurants')->cascadeOnDelete();
$table->string('title');
$table->text('description')->nullable();
$table->string('icon')->nullable();
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('why_choose_us');
}
};

View File

@@ -0,0 +1,35 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('ready_to_join_us', function (Blueprint $table) {
$table->id();
$table->foreignId('restaurant_id')->constrained('restaurants')->cascadeOnDelete();
$table->string('title');
$table->text('description')->nullable();
$table->string('icon')->nullable();
$table->string('button_name', 100)->nullable();
$table->string('button_link', 500)->nullable();
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('ready_to_join_us');
}
};

View File

@@ -0,0 +1,39 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('mobile_app_sections', function (Blueprint $table) {
$table->id();
$table->foreignId('restaurant_id')->constrained('restaurants')->cascadeOnDelete();
$table->string('title');
$table->string('heading');
$table->text('description')->nullable();
$table->string('image')->nullable();
$table->string('feature_one')->nullable();
$table->string('feature_two')->nullable();
$table->string('feature_three')->nullable();
$table->string('play_store_link')->nullable();
$table->string('app_store_link')->nullable();
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('mobile_app_sections');
}
};

View File

@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
/**
* Run the migrations.
*/
public function up(): void
{
Schema::create('themes', function (Blueprint $table) {
$table->id();
$table->string('category'); // Core Academic, Early Childhood, etc.
$table->string('name'); // Elementary, High School, etc.
$table->string('icon')->nullable(); // 🏫, 🎒, etc.
$table->string('description'); // Theme purpose
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
$table->timestamps();
$table->softDeletes();
});
}
/**
* Reverse the migrations.
*/
public function down(): void
{
Schema::dropIfExists('themes');
}
};

View File

@@ -0,0 +1,29 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('c_m_s_sections', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable();
$table->string('name');
$table->integer('serial')->default(0);
$table->string('title')->nullable();
$table->text('description')->nullable();
$table->string('image')->nullable();
$table->smallInteger('status')->default(1)->comment('1=Active, 2=InActive');
$table->timestamps();
$table->softDeletes();
});
}
public function down(): void
{
Schema::dropIfExists('c_m_s_sections');
}
};

View File

@@ -0,0 +1,43 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('coupons', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable()->comment('Optional restaurant id');
$table->unsignedBigInteger('user_id')->nullable()->comment('User who created this coupon');
$table->string('name', 100)->comment('Coupon name');
$table->string('added_by')->nullable()->comment('Added by admin/system');
$table->enum('discount_type', ['fixed', 'percentage', 'free_delivery'])->default('fixed')->comment('Discount type');
$table->enum('coupon_type', ['restaurant', 'hotel', 'both'])->default('restaurant')->comment('Where this coupon can be used');
$table->decimal('amount', 10, 2)->default(0.00)->comment('Discount amount or percentage');
$table->dateTime('valid_from')->nullable()->comment('Start date/time');
$table->dateTime('valid_to')->nullable()->comment('End date/time');
$table->unsignedInteger('usage_limit')->default(1)->comment('Total usage limit');
$table->unsignedInteger('max_uses_per_customer')->default(1)->comment('Max usage per customer');
$table->decimal('min_order_amount', 10, 2)->nullable()->comment('Minimum order amount to apply coupon');
$table->string('image')->nullable()->comment('Coupon image/banner');
$table->string('source')->default('local')->comment('Local or external');
$table->smallInteger('status')->default(1)->comment('1=Active, 2=Inactive');
$table->timestamps();
$table->softDeletes();
// Indexes for faster queries
$table->index('restaurant_id');
$table->index('user_id');
$table->index(['valid_from', 'valid_to']);
$table->index('status');
});
}
public function down(): void
{
Schema::dropIfExists('coupons');
}
};

View File

@@ -0,0 +1,27 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
return new class extends Migration
{
public function up(): void
{
Schema::create('coupon_usages', function (Blueprint $table) {
$table->id();
$table->unsignedBigInteger('restaurant_id')->nullable()->comment('Optional restaurant id');
$table->unsignedBigInteger('coupon_id');
$table->unsignedBigInteger('customer_id')->nullable(); // customer using the coupon
$table->unsignedBigInteger('order_id')->nullable(); // optional link to order
$table->timestamps();
$table->foreign('coupon_id')->references('id')->on('coupons')->onDelete('cascade');
});
}
public function down(): void
{
Schema::dropIfExists('coupon_usages');
}
};

View File

@@ -0,0 +1,27 @@
<?php
namespace Modules\Frontend\Database\Seeders;
use Illuminate\Database\Seeder;
use Modules\Frontend\Models\AboutUs;
class AboutUsTableSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
AboutUs::insert([
[
'restaurant_id' => 1,
'title' => 'Welcome to Fudevs School',
'description' => 'We provide a nurturing environment, a challenging curriculum, and a dedicated faculty to ensure customer success.',
'image' => 'https://i.ibb.co.com/jkr9s80Q/image.png',
'status' => 1,
'created_at' => now(),
'updated_at' => now(),
],
]);
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace Modules\Frontend\Database\Seeders;
use Illuminate\Database\Seeder;
use Modules\Frontend\Models\Banner;
class BannerTableSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
Banner::insert([
[
'restaurant_id' => 1,
'title' => 'Fuedevs School - Excellence in Education, Brighter Futures Ahead!',
'description' => 'A place where customers learn, grow, and succeed.',
'button_name' => 'Enroll Now',
'button_link' => '#',
'image' => 'https://i.ibb.co.com/Hf5zNcmQ/image-1.png',
'created_at' => now(),
'updated_at' => now(),
],
]);
}
}

View File

@@ -0,0 +1,38 @@
<?php
namespace Modules\Frontend\Database\Seeders;
use Illuminate\Database\Seeder;
use Illuminate\Support\Facades\DB;
class CmsSectionsSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
$sections = [
['name' => 'banner', 'serial' => 1],
['name' => 'about_us', 'serial' => 2],
['name' => 'why_choose_us', 'serial' => 3],
['name' => 'signature_creation', 'serial' => 4],
['name' => 'main_menu', 'serial' => 5],
['name' => 'chef', 'serial' => 6],
['name' => 'table_reservation', 'serial' => 7],
['name' => 'testimonial', 'serial' => 8],
['name' => 'visit_us', 'serial' => 9],
['name' => 'newsletter', 'serial' => 10],
];
foreach ($sections as $section) {
DB::table('c_m_s_sections')->insert([
'restaurant_id' => 1,
'name' => $section['name'],
'serial' => $section['serial'],
'created_at' => now(),
'updated_at' => now(),
]);
}
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace Modules\Frontend\Database\Seeders;
use Illuminate\Database\Seeder;
use Modules\Frontend\Models\Coupon;
class CouponSeeder extends Seeder
{
/**
* Run the database seeds.
*/
public function run(): void
{
// Percentage coupon
Coupon::create([
'restaurant_id' => 1,
'name' => '10% OFF',
'discount_type' => 'percentage',
'coupon_type' => 'restaurant',
'amount' => 10, // 10%
'valid_from' => now(),
'valid_to' => now()->addMonth(),
'usage_limit' => 100,
'max_uses_per_customer' => 1,
'min_order_amount' => 500,
'status' => 1,
'source' => 'local',
]);
// Fixed coupon
Coupon::create([
'restaurant_id' => 1,
'name' => '50 BDT OFF',
'discount_type' => 'fixed',
'coupon_type' => 'restaurant',
'amount' => 50, // Fixed amount
'valid_from' => now(),
'valid_to' => now()->addMonth(),
'usage_limit' => 100,
'max_uses_per_customer' => 1,
'min_order_amount' => 200,
'status' => 1,
'source' => 'local',
]);
// Both type coupon
Coupon::create([
'restaurant_id' => 1,
'name' => 'Special Both Coupon',
'discount_type' => 'fixed',
'coupon_type' => 'both', // usable for restaurant & hotel
'amount' => 100, // Fixed amount
'valid_from' => now(),
'valid_to' => now()->addMonth(),
'usage_limit' => 50,
'max_uses_per_customer' => 1,
'min_order_amount' => 500,
'status' => 1,
'source' => 'local',
]);
}
}

View File

@@ -0,0 +1,44 @@
<?php
namespace Modules\Frontend\Database\Seeders;
use Illuminate\Database\Seeder;
use Modules\Frontend\Models\FaqQuestion;
class FaqQuestionSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
FaqQuestion::insert([
[
'restaurant_id' => 1,
'question' => 'What is an academic program?',
'answer' => 'The academic program is a one stop solution for customers. Where every customer has the opportunity to ensure A+ preparation for board exams through interactive live classes, homework, live tests and progress analysis by the best mentors in each subject throughout the year. Once a customer starts this program, he will not have to go to any coaching or private tutor after school/college.',
'created_at' => now(),
'updated_at' => now(),
],
[
'restaurant_id' => 1,
'question' => 'What is an academic program?',
'answer' => 'The academic program is a one stop solution for customers. Where every customer has the opportunity to ensure A+ preparation for board exams through interactive live classes, homework, live tests and progress analysis by the best mentors in each subject throughout the year. Once a customer starts this program, he will not have to go to any coaching or private tutor after school/college.',
'created_at' => now(),
'updated_at' => now(),
],
[
'restaurant_id' => 1,
'question' => 'What is an academic program?',
'answer' => 'The academic program is a one stop solution for customers. Where every customer has the opportunity to ensure A+ preparation for board exams through interactive live classes, homework, live tests and progress analysis by the best mentors in each subject throughout the year. Once a customer starts this program, he will not have to go to any coaching or private tutor after school/college.',
'created_at' => now(),
'updated_at' => now(),
],
]);
}
}

Some files were not shown because too many files have changed in this diff Show More