@@ -0,0 +1,675 @@
import { db } from './db'
export interface Category {
id : string
slug : string
nameTr : string
nameEn : string
nameRu : string
}
export interface Neighborhood {
id : string
slug : string
nameTr : string
nameEn : string
nameRu : string
}
export interface Gallery {
id : string
listingId : string
url : string
}
export interface Listing {
id : string
slug : string
categoryId : string
neighborhoodId : string
city : string
nameTr : string
nameEn : string
nameRu : string
descriptionTr : string
descriptionEn : string
descriptionRu : string
address : string
phone? : string | null
whatsapp? : string | null
website? : string | null
instagram? : string | null
priceRange : number
rating? : number | null
isLocalApproved : boolean
latitude? : number | null
longitude? : number | null
openingHours? : any | null
images : Gallery [ ]
category? : Category
neighborhood? : Neighborhood
createdAt : Date
updatedAt : Date
deletedAt? : Date | null
}
export interface BusinessSubmission {
id : string
businessName : string
categoryId : string
neighborhoodId : string
address : string
phone? : string | null
whatsapp? : string | null
description : string
contactName : string
contactEmail : string
imageUrl? : string | null
status : string
createdAt : Date
updatedAt : Date
}
export interface ContactMessage {
id : string
name : string
email : string
subject : string
message : string
isRead : boolean
createdAt : Date
updatedAt : Date
}
const globalForMockDb = globalThis as unknown as {
categories : Category [ ]
neighborhoods : Neighborhood [ ]
listings : Listing [ ]
submissions : BusinessSubmission [ ]
messages : ContactMessage [ ]
initialized : boolean
}
if ( ! globalForMockDb . initialized ) {
globalForMockDb . categories = [
{ id : 'cat-1' , slug : 'restoran' , nameTr : 'Restoran' , nameEn : 'Restaurant' , nameRu : 'Ресторан' } ,
{ id : 'cat-2' , slug : 'apart' , nameTr : 'Apart' , nameEn : 'Apart Hotel' , nameRu : 'Апарт-отель' } ,
{ id : 'cat-3' , slug : 'isletme' , nameTr : 'İşletme & Hizmet' , nameEn : 'Business & Service' , nameRu : 'Бизнес и Услуги' }
]
globalForMockDb . neighborhoods = [
{ id : 'neigh-1' , slug : 'yat-limani' , nameTr : 'Yat Limanı ' , nameEn : 'Marina' , nameRu : 'Марина' } ,
{ id : 'neigh-2' , slug : 'icmeler' , nameTr : 'İçmeler' , nameEn : 'Icmeler' , nameRu : 'Ичмелер' } ,
{ id : 'neigh-3' , slug : 'armutalan' , nameTr : 'Armutalan' , nameEn : 'Armutalan' , nameRu : 'Армуталан' } ,
{ id : 'neigh-4' , slug : 'siteler' , nameTr : 'Siteler' , nameEn : 'Siteler' , nameRu : 'Сителер' } ,
{ id : 'neigh-5' , slug : 'turunc' , nameTr : 'Turunç' , nameEn : 'Turunc' , nameRu : 'Турунч' }
]
globalForMockDb . submissions = [ ]
globalForMockDb . messages = [ ]
// Pre-populate with realistic Marmaris data
globalForMockDb . listings = [
{
id : 'list-1' ,
slug : 'iskele-balik-ocakbasi' ,
categoryId : 'cat-1' ,
neighborhoodId : 'neigh-1' ,
city : 'marmaris' ,
nameTr : 'İskele Balı k Ocakbaşı' ,
nameEn : 'Iskele Fish & Grill' ,
nameRu : 'Рыбный Гриль Искеле' ,
descriptionTr : 'Yat Limanı \'nda taze Ege balı kları ve geleneksel meze çeşitleriyle yerel lezzet durağını z. Mükemmel körfez manzarası eşliğinde akşam yemeği.' ,
descriptionEn : 'Your local taste stop at the Marina with fresh Aegean fish and traditional appetizers. Dinner accompanied by excellent bay views.' ,
descriptionRu : 'Ваша местная гастрономическая остановка в Марине со свежей эгейской рыбой и традиционными закусками. Ужин в сопровождении великолепного вида на залив.' ,
address : 'Yat Limanı No:12, Marmaris' ,
phone : '+90 252 412 34 56' ,
whatsapp : '+90 532 123 45 67' ,
website : 'https://iskelemarmaris.com' ,
instagram : 'https://instagram.com/iskele_marmaris' ,
priceRange : 3 ,
rating : 4.8 ,
isLocalApproved : true ,
latitude : 36.8524 ,
longitude : 28.2741 ,
openingHours : { all : '12:00 - 00:00' } ,
images : [
{ id : 'img-1-1' , listingId : 'list-1' , url : 'https://images.unsplash.com/photo-1519708227418-c8fd9a32b7a2?w=800&auto=format&fit=crop&q=80' } ,
{ id : 'img-1-2' , listingId : 'list-1' , url : 'https://images.unsplash.com/photo-1555396273-367ea4eb4db5?w=800&auto=format&fit=crop&q=80' }
] ,
createdAt : new Date ( ) ,
updatedAt : new Date ( )
} ,
{
id : 'list-2' ,
slug : 'mavi-beyaz-restoran' ,
categoryId : 'cat-1' ,
neighborhoodId : 'neigh-1' ,
city : 'marmaris' ,
nameTr : 'Mavi Beyaz Restoran' ,
nameEn : 'Blue White Restaurant' ,
nameRu : 'Ресторан Сине-Белый' ,
descriptionTr : 'Ege kı yı ları nı n esintisini taşıyan, deniz ürünleri ağırlı klı menüsü ve gün batı mı eşliğindeki eşsiz mezeleriyle ünlüdür.' ,
descriptionEn : 'Famous for its seafood-oriented menu carrying the breeze of the Aegean coasts and unique appetizers accompanied by sunset.' ,
descriptionRu : 'Славится своим меню из морепродуктов, несущим бриз Эгейского побережья, и уникальными закусками на фоне заката.' ,
address : 'Kordon Caddesi No:45, Yat Limanı , Marmaris' ,
phone : '+90 252 412 78 90' ,
whatsapp : '+90 533 987 65 43' ,
website : 'https://mavibeyazmarmaris.com' ,
instagram : 'https://instagram.com/mavibeyaz_marmaris' ,
priceRange : 2 ,
rating : 4.5 ,
isLocalApproved : true ,
latitude : 36.8530 ,
longitude : 28.2725 ,
openingHours : { all : '11:00 - 23:30' } ,
images : [
{ id : 'img-2-1' , listingId : 'list-2' , url : 'https://images.unsplash.com/photo-1414235077428-338989a2e8c0?w=800&auto=format&fit=crop&q=80' }
] ,
createdAt : new Date ( ) ,
updatedAt : new Date ( )
} ,
{
id : 'list-3' ,
slug : 'dostlar-kebap' ,
categoryId : 'cat-1' ,
neighborhoodId : 'neigh-3' ,
city : 'marmaris' ,
nameTr : 'Dostlar Kebap' ,
nameEn : 'Dostlar Kebab House' ,
nameRu : 'Кебаб Хаус Достлар' ,
descriptionTr : 'Marmaris Armutalan\'da yı llardı r değişmeyen lezzetiyle gerçek ocakbaşı ve kebap deneyimi sunan samimi bir mahalle restoranı .' ,
descriptionEn : 'A cozy neighborhood restaurant offering real grill and kebab experience with its unchanged taste for years in Armutalan, Marmaris.' ,
descriptionRu : 'Уютный районный ресторан, предлагающий настоящий гриль и кебаб с неизменным вкусом на протяжении многих лет в Армуталане, Мармарис.' ,
address : 'Vatan Caddesi No:18, Armutalan, Marmaris' ,
phone : '+90 252 413 11 22' ,
whatsapp : null ,
website : null ,
instagram : 'https://instagram.com/dostlarkebap_marmaris' ,
priceRange : 1 ,
rating : 4.7 ,
isLocalApproved : false ,
latitude : 36.8488 ,
longitude : 28.2450 ,
openingHours : { all : '11:00 - 22:00' } ,
images : [
{ id : 'img-3-1' , listingId : 'list-3' , url : 'https://images.unsplash.com/photo-1544025162-d76694265947?w=800&auto=format&fit=crop&q=80' }
] ,
createdAt : new Date ( ) ,
updatedAt : new Date ( )
} ,
{
id : 'list-4' ,
slug : 'zeytin-bahcesi-apart' ,
categoryId : 'cat-2' ,
neighborhoodId : 'neigh-3' ,
city : 'marmaris' ,
nameTr : 'Zeytin Bahçesi Apart' ,
nameEn : 'Olive Garden Apart' ,
nameRu : 'Апарт Оливковый Сад' ,
descriptionTr : 'Zeytin ağaçları arası nda, sakin ve huzurlu bir ortamda ailece tatil yapmak isteyenler için tasarlanmış geniş mutfaklı apart daireler.' ,
descriptionEn : 'Spacious apart apartments with kitchens designed for families who want to have a holiday in a quiet and peaceful environment among olive trees.' ,
descriptionRu : 'Просторные апартаменты с кухнями, предназначенные для семей, желающих отдохнуть в тихой и спокойной обстановке среди оливковых деревьев.' ,
address : 'Zeytinlik Sokak No:5, Armutalan, Marmaris' ,
phone : '+90 252 413 55 66' ,
whatsapp : '+90 535 555 66 77' ,
website : 'https://zeytinbahcesiapart.com' ,
instagram : null ,
priceRange : 2 ,
rating : 4.6 ,
isLocalApproved : true ,
latitude : 36.8510 ,
longitude : 28.2415 ,
openingHours : null ,
images : [
{ id : 'img-4-1' , listingId : 'list-4' , url : 'https://images.unsplash.com/photo-1566073771259-6a8506099945?w=800&auto=format&fit=crop&q=80' } ,
{ id : 'img-4-2' , listingId : 'list-4' , url : 'https://images.unsplash.com/photo-1520250497591-112f2f40a3f4?w=800&auto=format&fit=crop&q=80' }
] ,
createdAt : new Date ( ) ,
updatedAt : new Date ( )
} ,
{
id : 'list-5' ,
slug : 'deniz-apart' ,
categoryId : 'cat-2' ,
neighborhoodId : 'neigh-4' ,
city : 'marmaris' ,
nameTr : 'Deniz Apart' ,
nameEn : 'Sea Apart Hotel' ,
nameRu : 'Апарт-отель Дениз' ,
descriptionTr : 'Denize sadece 100 metre mesafede, bütçe dostu fiyatları ve güler yüzlü yerel işletme sahibiyle Marmaris\'te sı cak konaklama.' ,
descriptionEn : 'Cozy accommodation in Marmaris, just 100 meters from the sea, with budget-friendly prices and a friendly local owner.' ,
descriptionRu : 'Уютное жилье в Мармарисе, всего в 100 метрах от моря, с доступными ценами и дружелюбным местным владельцем.' ,
address : 'Sahil Yolu Caddesi No:88, Siteler, Marmaris' ,
phone : '+90 252 417 88 99' ,
whatsapp : null ,
website : null ,
instagram : null ,
priceRange : 1 ,
rating : 4.2 ,
isLocalApproved : false ,
latitude : 36.8375 ,
longitude : 28.2580 ,
openingHours : null ,
images : [
{ id : 'img-5-1' , listingId : 'list-5' , url : 'https://images.unsplash.com/photo-1582719478250-c89cae4dc85b?w=800&auto=format&fit=crop&q=80' }
] ,
createdAt : new Date ( ) ,
updatedAt : new Date ( )
} ,
{
id : 'list-6' ,
slug : 'marina-dalis-merkezi' ,
categoryId : 'cat-3' ,
neighborhoodId : 'neigh-2' ,
city : 'marmaris' ,
nameTr : 'Marina Dalış Merkezi' ,
nameEn : 'Marina Diving Center' ,
nameRu : 'Дайвинг-центр Марина' ,
descriptionTr : 'Marmaris\'in eşsiz koyları nda profesyonel eğitmenler eşliğinde tüplü dalış deneyimi. Başlangıç seviyesinden PADI sertifikasyonuna kadar hizmet.' ,
descriptionEn : 'Scuba diving experience in unique bays of Marmaris accompanied by professional instructors. Service from discovery dive to PADI certification.' ,
descriptionRu : 'Опыт подводного плавания в уникальных бухтах Мармариса в сопровождении профессиональных инструкторов. Услуги от ознакомительного погружения до сертификации PADI.' ,
address : 'Liman Yolu No:32, İçmeler, Marmaris' ,
phone : '+90 252 455 22 33' ,
whatsapp : '+90 536 777 88 99' ,
website : 'https://marinadivingmarmaris.com' ,
instagram : 'https://instagram.com/marinadiving_marmaris' ,
priceRange : 3 ,
rating : 4.9 ,
isLocalApproved : true ,
latitude : 36.8020 ,
longitude : 28.2320 ,
openingHours : { all : '08:30 - 19:30' } ,
images : [
{ id : 'img-6-1' , listingId : 'list-6' , url : 'https://images.unsplash.com/photo-1544551763-46a013bb70d5?w=800&auto=format&fit=crop&q=80' }
] ,
createdAt : new Date ( ) ,
updatedAt : new Date ( )
} ,
{
id : 'list-7' ,
slug : 'ege-ruzgari-tekne-kiralama' ,
categoryId : 'cat-3' ,
neighborhoodId : 'neigh-1' ,
city : 'marmaris' ,
nameTr : 'Ege Rüzgarı Tekne Kiralama' ,
nameEn : 'Aegean Wind Boat Rental' ,
nameRu : 'Аренда Лодок Эгейский Ветер' ,
descriptionTr : 'Kaptanlı veya kaptansı z günlük ve haftalı k özel tekne kiralama hizmeti. Marmaris koyları nı kendi rotanı zda özgürce keşfedin.' ,
descriptionEn : 'Daily and weekly private boat rental service with or without skipper. Discover Marmaris bays freely on your own route.' ,
descriptionRu : 'Ежедневная и еженедельная аренда частных лодок со шкипером или без. Откройте для себя бухты Мармариса свободно по собственному маршруту.' ,
address : 'Yat Limanı G İskelesi, Marmaris' ,
phone : '+90 532 999 88 77' ,
whatsapp : '+90 532 999 88 77' ,
website : 'https://egeruzgariboat.com' ,
instagram : 'https://instagram.com/egeruzgariboat' ,
priceRange : 3 ,
rating : 4.8 ,
isLocalApproved : true ,
latitude : 36.8528 ,
longitude : 28.2755 ,
openingHours : { all : '08:00 - 21:00' } ,
images : [
{ id : 'img-7-1' , listingId : 'list-7' , url : 'https://images.unsplash.com/photo-1567899378494-47b22a2ae96a?w=800&auto=format&fit=crop&q=80' }
] ,
createdAt : new Date ( ) ,
updatedAt : new Date ( )
} ,
{
id : 'list-8' ,
slug : 'marmaris-transfer-tours' ,
categoryId : 'cat-3' ,
neighborhoodId : 'neigh-3' ,
city : 'marmaris' ,
nameTr : 'Marmaris VIP Transfer & Tur' ,
nameEn : 'Marmaris VIP Transfer & Tours' ,
nameRu : 'Marmaris VIP Трансфер и Туры' ,
descriptionTr : 'Dalaman Havalimanı transferleri ve Marmaris çevresindeki tarihi/doğal alanlara özel konforlu turlar. Güvenilir ve lüks taşımacı lı k.' ,
descriptionEn : 'Dalaman Airport transfers and comfortable private tours to historical/natural areas around Marmaris. Reliable and luxurious transportation.' ,
descriptionRu : 'Трансфер из аэропорта Даламан и комфортабельные частные туры по историческим и природным местам вокруг Мармариса. Надежный и роскошный транспорт.' ,
address : 'Atatürk Caddesi No:102, Armutalan, Marmaris' ,
phone : '+90 252 413 77 88' ,
whatsapp : '+90 541 333 44 55' ,
website : 'https://marmarisviptransfer.com' ,
instagram : null ,
priceRange : 2 ,
rating : 4.6 ,
isLocalApproved : false ,
latitude : 36.8495 ,
longitude : 28.2430 ,
openingHours : { all : '24 Hours Open' } ,
images : [
{ id : 'img-8-1' , listingId : 'list-8' , url : 'https://images.unsplash.com/photo-1549317661-bd32c8ce0db2?w=800&auto=format&fit=crop&q=80' }
] ,
createdAt : new Date ( ) ,
updatedAt : new Date ( )
}
]
globalForMockDb . initialized = true
}
export const mockDb = {
// Config helpers
isMock : ( ) = > process . env . USE_MOCK === 'true' ,
// Categories
async getCategories() {
if ( this . isMock ( ) ) {
return globalForMockDb . categories
}
return db . category . findMany ( { orderBy : { nameTr : 'asc' } } )
} ,
async getCategoryBySlug ( slug : string ) {
if ( this . isMock ( ) ) {
return globalForMockDb . categories . find ( c = > c . slug === slug ) || null
}
return db . category . findUnique ( { where : { slug } } )
} ,
async createCategory ( data : { slug : string ; nameTr : string ; nameEn : string ; nameRu : string } ) {
if ( this . isMock ( ) ) {
const newCat = { id : ` cat- ${ Date . now ( ) } ` , . . . data }
globalForMockDb . categories . push ( newCat )
return newCat
}
return db . category . create ( { data } )
} ,
async updateCategory ( id : string , data : { slug : string ; nameTr : string ; nameEn : string ; nameRu : string } ) {
if ( this . isMock ( ) ) {
const idx = globalForMockDb . categories . findIndex ( c = > c . id === id )
if ( idx !== - 1 ) {
globalForMockDb . categories [ idx ] = { . . . globalForMockDb . categories [ idx ] , . . . data }
return globalForMockDb . categories [ idx ]
}
return null
}
return db . category . update ( { where : { id } , data } )
} ,
// Neighborhoods
async getNeighborhoods() {
if ( this . isMock ( ) ) {
return globalForMockDb . neighborhoods
}
return db . neighborhood . findMany ( { orderBy : { nameTr : 'asc' } } )
} ,
async getNeighborhoodBySlug ( slug : string ) {
if ( this . isMock ( ) ) {
return globalForMockDb . neighborhoods . find ( n = > n . slug === slug ) || null
}
return db . neighborhood . findUnique ( { where : { slug } } )
} ,
async createNeighborhood ( data : { slug : string ; nameTr : string ; nameEn : string ; nameRu : string } ) {
if ( this . isMock ( ) ) {
const newNeigh = { id : ` neigh- ${ Date . now ( ) } ` , . . . data }
globalForMockDb . neighborhoods . push ( newNeigh )
return newNeigh
}
return db . neighborhood . create ( { data } )
} ,
async updateNeighborhood ( id : string , data : { slug : string ; nameTr : string ; nameEn : string ; nameRu : string } ) {
if ( this . isMock ( ) ) {
const idx = globalForMockDb . neighborhoods . findIndex ( n = > n . id === id )
if ( idx !== - 1 ) {
globalForMockDb . neighborhoods [ idx ] = { . . . globalForMockDb . neighborhoods [ idx ] , . . . data }
return globalForMockDb . neighborhoods [ idx ]
}
return null
}
return db . neighborhood . update ( { where : { id } , data } )
} ,
// Listings
async getListings ( filters ? : {
categoryId? : string
neighborhoodId? : string
priceRange? : number
isLocalApproved? : boolean
search? : string
} ) {
if ( this . isMock ( ) ) {
let result = globalForMockDb . listings . filter ( l = > ! l . deletedAt )
if ( filters ) {
if ( filters . categoryId ) result = result . filter ( l = > l . categoryId === filters . categoryId )
if ( filters . neighborhoodId ) result = result . filter ( l = > l . neighborhoodId === filters . neighborhoodId )
if ( filters . priceRange ) result = result . filter ( l = > l . priceRange === filters . priceRange )
if ( filters . isLocalApproved !== undefined ) result = result . filter ( l = > l . isLocalApproved === filters . isLocalApproved )
if ( filters . search ) {
const s = filters . search . toLowerCase ( )
result = result . filter ( l = >
l . nameTr . toLowerCase ( ) . includes ( s ) ||
l . nameEn . toLowerCase ( ) . includes ( s ) ||
l . nameRu . toLowerCase ( ) . includes ( s ) ||
l . address . toLowerCase ( ) . includes ( s )
)
}
}
return result . map ( l = > ( {
. . . l ,
category : globalForMockDb.categories.find ( c = > c . id === l . categoryId ) ,
neighborhood : globalForMockDb.neighborhoods.find ( n = > n . id === l . neighborhoodId )
} ) )
}
const where : any = { deletedAt : null }
if ( filters ) {
if ( filters . categoryId ) where . categoryId = filters . categoryId
if ( filters . neighborhoodId ) where . neighborhoodId = filters . neighborhoodId
if ( filters . priceRange ) where . priceRange = filters . priceRange
if ( filters . isLocalApproved !== undefined ) where . isLocalApproved = filters . isLocalApproved
if ( filters . search ) {
where . OR = [
{ nameTr : { contains : filters.search , mode : 'insensitive' } } ,
{ nameEn : { contains : filters.search , mode : 'insensitive' } } ,
{ nameRu : { contains : filters.search , mode : 'insensitive' } } ,
{ address : { contains : filters.search , mode : 'insensitive' } } ,
]
}
}
return db . listing . findMany ( {
where ,
include : { category : true , neighborhood : true , images : true } ,
orderBy : { createdAt : 'desc' }
} )
} ,
async getListingBySlug ( slug : string ) {
if ( this . isMock ( ) ) {
const listing = globalForMockDb . listings . find ( l = > l . slug === slug && ! l . deletedAt )
if ( ! listing ) return null
return {
. . . listing ,
category : globalForMockDb.categories.find ( c = > c . id === listing . categoryId ) ,
neighborhood : globalForMockDb.neighborhoods.find ( n = > n . id === listing . neighborhoodId )
}
}
return db . listing . findUnique ( {
where : { slug } ,
include : { category : true , neighborhood : true , images : true }
} )
} ,
async getListingById ( id : string ) {
if ( this . isMock ( ) ) {
const listing = globalForMockDb . listings . find ( l = > l . id === id && ! l . deletedAt )
if ( ! listing ) return null
return {
. . . listing ,
category : globalForMockDb.categories.find ( c = > c . id === listing . categoryId ) ,
neighborhood : globalForMockDb.neighborhoods.find ( n = > n . id === listing . neighborhoodId )
}
}
return db . listing . findUnique ( {
where : { id } ,
include : { category : true , neighborhood : true , images : true }
} )
} ,
async createListing ( data : Omit < Listing , 'id' | 'images' | 'createdAt' | 'updatedAt' > & { images? : string [ ] } ) {
const { images , category , neighborhood , . . . rest } = data
if ( this . isMock ( ) ) {
const newId = ` list- ${ Date . now ( ) } `
const gallery = ( images || [ ] ) . map ( ( url , i ) = > ( { id : ` img- ${ newId } - ${ i } ` , listingId : newId , url } ) )
const newListing : Listing = {
id : newId ,
. . . rest ,
images : gallery ,
createdAt : new Date ( ) ,
updatedAt : new Date ( )
}
globalForMockDb . listings . unshift ( newListing )
return newListing
}
return db . listing . create ( {
data : {
. . . rest ,
images : images ? { create : images.map ( url = > ( { url } ) ) } : undefined
} ,
include : { images : true }
} )
} ,
async updateListing ( id : string , data : Partial < Omit < Listing , 'id' | 'images' | 'createdAt' | 'updatedAt' > > & { images? : string [ ] } ) {
const { images , category , neighborhood , . . . rest } = data
if ( this . isMock ( ) ) {
const idx = globalForMockDb . listings . findIndex ( l = > l . id === id )
if ( idx !== - 1 ) {
const oldListing = globalForMockDb . listings [ idx ]
const updatedGallery = images
? images . map ( ( url , i ) = > ( { id : ` img- ${ id } - ${ i } ` , listingId : id , url } ) )
: oldListing . images
const updated = {
. . . oldListing ,
. . . rest ,
images : updatedGallery ,
updatedAt : new Date ( )
} as Listing
globalForMockDb . listings [ idx ] = updated
return updated
}
return null
}
if ( images ) {
await db . gallery . deleteMany ( { where : { listingId : id } } )
}
return db . listing . update ( {
where : { id } ,
data : {
. . . rest ,
images : images ? { create : images.map ( url = > ( { url } ) ) } : undefined
} ,
include : { images : true }
} )
} ,
async deleteListing ( id : string ) {
if ( this . isMock ( ) ) {
const idx = globalForMockDb . listings . findIndex ( l = > l . id === id )
if ( idx !== - 1 ) {
globalForMockDb . listings [ idx ] . deletedAt = new Date ( )
return true
}
return false
}
await db . listing . update ( {
where : { id } ,
data : { deletedAt : new Date ( ) }
} )
return true
} ,
// Business Submissions
async getSubmissions() {
if ( this . isMock ( ) ) {
return globalForMockDb . submissions . sort ( ( a , b ) = > b . createdAt . getTime ( ) - a . createdAt . getTime ( ) )
}
return db . businessSubmission . findMany ( { orderBy : { createdAt : 'desc' } } )
} ,
async createSubmission ( data : Omit < BusinessSubmission , 'id' | 'status' | 'createdAt' | 'updatedAt' > ) {
if ( this . isMock ( ) ) {
const newSub : BusinessSubmission = {
id : ` sub- ${ Date . now ( ) } ` ,
. . . data ,
status : 'PENDING' ,
createdAt : new Date ( ) ,
updatedAt : new Date ( )
}
globalForMockDb . submissions . push ( newSub )
return newSub
}
return db . businessSubmission . create ( { data : { . . . data , status : 'PENDING' } } )
} ,
async updateSubmissionStatus ( id : string , status : 'APPROVED' | 'REJECTED' ) {
if ( this . isMock ( ) ) {
const idx = globalForMockDb . submissions . findIndex ( s = > s . id === id )
if ( idx !== - 1 ) {
globalForMockDb . submissions [ idx ] . status = status
globalForMockDb . submissions [ idx ] . updatedAt = new Date ( )
return globalForMockDb . submissions [ idx ]
}
return null
}
return db . businessSubmission . update ( {
where : { id } ,
data : { status }
} )
} ,
async getSubmissionById ( id : string ) {
if ( this . isMock ( ) ) {
return globalForMockDb . submissions . find ( s = > s . id === id ) || null
}
return db . businessSubmission . findUnique ( { where : { id } } )
} ,
// Contact Messages
async getMessages() {
if ( this . isMock ( ) ) {
return globalForMockDb . messages . sort ( ( a , b ) = > b . createdAt . getTime ( ) - a . createdAt . getTime ( ) )
}
return db . contactMessage . findMany ( { orderBy : { createdAt : 'desc' } } )
} ,
async createMessage ( data : Omit < ContactMessage , 'id' | 'isRead' | 'createdAt' | 'updatedAt' > ) {
if ( this . isMock ( ) ) {
const newMsg : ContactMessage = {
id : ` msg- ${ Date . now ( ) } ` ,
. . . data ,
isRead : false ,
createdAt : new Date ( ) ,
updatedAt : new Date ( )
}
globalForMockDb . messages . push ( newMsg )
return newMsg
}
return db . contactMessage . create ( { data : { . . . data , isRead : false } } )
} ,
async markMessageAsRead ( id : string ) {
if ( this . isMock ( ) ) {
const idx = globalForMockDb . messages . findIndex ( m = > m . id === id )
if ( idx !== - 1 ) {
globalForMockDb . messages [ idx ] . isRead = true
globalForMockDb . messages [ idx ] . updatedAt = new Date ( )
return globalForMockDb . messages [ idx ]
}
return null
}
return db . contactMessage . update ( {
where : { id } ,
data : { isRead : true }
} )
}
}