import payloadConfig from "@/payload.config"; import { CardPropertyData } from "@/schema/property"; import { FetchPropertyDetailParams, FetchPropertyParams } from "@/schema/services/property"; import { formatDate } from "@/utils/datetime"; import { formatCurrency, getRandomNumber } from "@/utils/general"; import { getPayload, Where } from "payload"; export async function fetchProperty({ page, name = "", location, min_price, max_price, min_area, max_area, property_type, }: FetchPropertyParams = {}) { const payload = await getPayload({ config: payloadConfig }); const queryCondition: Where = { _status: { equals: "published" }, }; if (!!property_type) { queryCondition["property_type"] = { equals: property_type, }; } if (!!name) { queryCondition["name"] = { contains: name, }; } if (!!min_price) { queryCondition["base_price"] = { greater_than_equal: min_price, }; } if (!!max_price) { queryCondition["base_price"] = { less_than_equal: max_price, }; } if (!!min_area) { queryCondition["aboutGroup.area"] = { greater_than_equal: min_area, }; } if (!!max_area) { queryCondition["aboutGroup.area"] = { less_than_equal: max_area, }; } if (!!location) { queryCondition["addressGroup.state_code"] = { equals: location, }; } const dataQuery = await payload.find({ collection: "properties", page, pagination: true, limit: 10, where: queryCondition, }); const formattedData: CardPropertyData[] = dataQuery.docs.map((item) => { return { slug: item.slug ?? "", title: item.name, price: item.base_price, area: item.aboutGroup.area, propertyType: item.property_type, bathrooms_count: item.aboutGroup.bathrooms_count, bedrooms_count: item.aboutGroup.bedrooms_count, images: item.images.map((img) => typeof img !== "number" ? { url: img?.url ?? "", alt: img.alt } : { url: "", alt: "" } ), posted_at: formatDate(item.createdAt), }; }); return { ...dataQuery, formattedData, }; } export async function fetchPropertySuggestion() { const payload = await getPayload({ config: payloadConfig }); const limitPerPage = 2; const countrQuery = await payload.count({ collection: "properties", where: { _status: { equals: "published" } }, }); // randomize page let page = 1; const totalDocs = countrQuery.totalDocs; if (totalDocs > limitPerPage) { const totalPage = Math.ceil(totalDocs / limitPerPage); page = getRandomNumber(totalPage); } const dataQuery = await payload.find({ collection: "properties", page, limit: limitPerPage, }); const formattedData: CardPropertyData[] = dataQuery.docs.map((item) => { return { slug: item.slug ?? "", title: item.name, price: item.base_price, area: item.aboutGroup.area, propertyType: item.property_type, bathrooms_count: item.aboutGroup.bathrooms_count, bedrooms_count: item.aboutGroup.bedrooms_count, images: item.images.map((img) => typeof img !== "number" ? { url: img?.url ?? "", alt: img.alt } : { url: "", alt: "" } ), posted_at: formatDate(item.createdAt), }; }); return { ...dataQuery, formattedData, }; } export async function fetchPropertyDetail({ slug }: FetchPropertyDetailParams) { const payload = await getPayload({ config: payloadConfig }); const queryCondition: Where = { _status: { equals: "published" }, slug: { equals: slug }, }; const dataQuery = await payload.find({ collection: "properties", where: queryCondition, limit: 1, pagination: false, }); if (!dataQuery?.docs?.[0]) return null; const data = dataQuery?.docs?.[0]; const postedAt = formatDate(data.createdAt); const images = data.images.map((img) => typeof img !== "number" ? { url: img?.url ?? "", alt: img.alt } : { url: "", alt: "" } ); const formattedBasePrice = formatCurrency(data.base_price); const additionalPrice: { name: string; price: string }[] = []; let totalPrice = 0; if (Array.isArray(data.additional_price)) { for (const p of data.additional_price) { additionalPrice.push({ name: p.name, price: formatCurrency(p.price), }); totalPrice += p.price; } } const formattedTotalPrice = formatCurrency(data.base_price + totalPrice); return { data, formattedData: { price: formattedBasePrice, additionalPrice, totalPrice: formattedTotalPrice, images, postedAt, }, }; }