feat: all properties related backend

This commit is contained in:
RizqiSyahrendra 2025-04-22 21:15:55 +07:00
parent f574fdc66d
commit 16b415740c
7 changed files with 292 additions and 1 deletions

View File

@ -17,6 +17,7 @@
"@payloadcms/payload-cloud": "^3.35.1",
"@payloadcms/richtext-lexical": "^3.35.1",
"@payloadcms/storage-s3": "^3.35.1",
"country-state-city": "^3.2.1",
"dayjs": "^1.11.13",
"graphql": "^16.8.1",
"next": "15.3.0",

View File

@ -3,6 +3,7 @@ import HeroImage from "@/components/HeroImage";
import Pagination from "@/components/Pagination";
import { CardPropertyData } from "@/schema/property";
import { getDefaultMetadata } from "@/utils/metadata";
import { Country, State } from "country-state-city";
import { Metadata } from "next";
const metaDesc = "Explore the latest properties on the Dynamic Realty.";
@ -75,6 +76,9 @@ const propertiesData: CardPropertyData[] = [
];
export default function ListingsForRent() {
// const countries = State.getStatesOfCountry("ID");
// console.log(countries);
return (
<>
<HeroImage title="Listings For Rent" />

View File

@ -0,0 +1,140 @@
import formatSlug from "@/utils/payload/formatSlug";
import type { CollectionConfig } from "payload";
export const Properties: CollectionConfig = {
slug: "properties",
labels: { plural: "Properties", singular: "Property" },
fields: [
{
name: "name",
type: "text",
required: true,
},
{
name: "slug",
type: "text",
admin: {
position: "sidebar",
},
hooks: {
beforeValidate: [formatSlug("name")],
},
},
{
name: "images",
type: "relationship",
relationTo: "media",
hasMany: true,
minRows: 1,
required: true,
},
{
name: "aboutGroup",
label: "About",
type: "group",
fields: [
{
name: "description",
type: "richText",
required: true,
},
{
name: "area",
label: "Area (Sqft)",
type: "text",
required: true,
},
{
name: "bathrooms_count",
label: "Total Bathrooms",
type: "text",
required: true,
},
{
name: "bedrooms_count",
label: "Total Bedrooms",
type: "text",
required: true,
},
],
},
{
name: "addressGroup",
label: "Address",
type: "group",
fields: [
{
name: "country_code",
label: "Country",
type: "text",
required: true,
},
{
name: "state_code",
label: "State",
type: "text",
required: true,
},
{
name: "city_code",
label: "City",
type: "text",
required: true,
},
{
name: "zip_code",
label: "Zip",
type: "text",
required: true,
},
{
name: "address",
label: "Address",
type: "text",
required: true,
},
],
},
{
name: "features",
type: "relationship",
relationTo: "propertyFeatures",
required: true,
hasMany: true,
minRows: 1,
},
{
name: "base_price",
label: "Base Price",
type: "number",
required: true,
},
{
name: "additional_price",
label: "Additional Price",
type: "array",
fields: [
{
name: "name",
type: "text",
required: true,
},
{
name: "price",
type: "number",
required: true,
},
],
},
{
name: "embed_map_url",
label: "Embed Map URL",
type: "text",
},
],
admin: {
hideAPIURL: true,
group: "Properties",
useAsTitle: "name",
},
};

View File

@ -0,0 +1,18 @@
import type { CollectionConfig } from "payload";
export const PropertyFeatures: CollectionConfig = {
slug: "propertyFeatures",
labels: { plural: "Property Features", singular: "Property Feature" },
fields: [
{
name: "name",
type: "text",
required: true,
},
],
admin: {
hideAPIURL: true,
group: "Properties",
useAsTitle: "name",
},
};

View File

@ -72,6 +72,8 @@ export interface Config {
blogTags: BlogTag;
blogCategories: BlogCategory;
blogs: Blog;
propertyFeatures: PropertyFeature;
properties: Property;
'payload-locked-documents': PayloadLockedDocument;
'payload-preferences': PayloadPreference;
'payload-migrations': PayloadMigration;
@ -83,6 +85,8 @@ export interface Config {
blogTags: BlogTagsSelect<false> | BlogTagsSelect<true>;
blogCategories: BlogCategoriesSelect<false> | BlogCategoriesSelect<true>;
blogs: BlogsSelect<false> | BlogsSelect<true>;
propertyFeatures: PropertyFeaturesSelect<false> | PropertyFeaturesSelect<true>;
properties: PropertiesSelect<false> | PropertiesSelect<true>;
'payload-locked-documents': PayloadLockedDocumentsSelect<false> | PayloadLockedDocumentsSelect<true>;
'payload-preferences': PayloadPreferencesSelect<false> | PayloadPreferencesSelect<true>;
'payload-migrations': PayloadMigrationsSelect<false> | PayloadMigrationsSelect<true>;
@ -219,6 +223,65 @@ export interface Blog {
createdAt: string;
_status?: ('draft' | 'published') | null;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "propertyFeatures".
*/
export interface PropertyFeature {
id: number;
name: string;
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "properties".
*/
export interface Property {
id: number;
name: string;
slug?: string | null;
images: (number | Media)[];
aboutGroup: {
description: {
root: {
type: string;
children: {
type: string;
version: number;
[k: string]: unknown;
}[];
direction: ('ltr' | 'rtl') | null;
format: 'left' | 'start' | 'center' | 'right' | 'end' | 'justify' | '';
indent: number;
version: number;
};
[k: string]: unknown;
};
area: string;
bathrooms_count: string;
bedrooms_count: string;
};
addressGroup: {
country_code: string;
state_code: string;
city_code: string;
zip_code: string;
address: string;
};
features: (number | PropertyFeature)[];
base_price: number;
additional_price?:
| {
name: string;
price: number;
id?: string | null;
}[]
| null;
embed_map_url?: string | null;
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "payload-locked-documents".
@ -245,6 +308,14 @@ export interface PayloadLockedDocument {
| ({
relationTo: 'blogs';
value: number | Blog;
} | null)
| ({
relationTo: 'propertyFeatures';
value: number | PropertyFeature;
} | null)
| ({
relationTo: 'properties';
value: number | Property;
} | null);
globalSlug?: string | null;
user: {
@ -370,6 +441,53 @@ export interface BlogsSelect<T extends boolean = true> {
createdAt?: T;
_status?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "propertyFeatures_select".
*/
export interface PropertyFeaturesSelect<T extends boolean = true> {
name?: T;
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "properties_select".
*/
export interface PropertiesSelect<T extends boolean = true> {
name?: T;
slug?: T;
images?: T;
aboutGroup?:
| T
| {
description?: T;
area?: T;
bathrooms_count?: T;
bedrooms_count?: T;
};
addressGroup?:
| T
| {
country_code?: T;
state_code?: T;
city_code?: T;
zip_code?: T;
address?: T;
};
features?: T;
base_price?: T;
additional_price?:
| T
| {
name?: T;
price?: T;
id?: T;
};
embed_map_url?: T;
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "payload-locked-documents_select".

View File

@ -13,6 +13,8 @@ import { Media } from "@/collections/Media";
import { BlogTags } from "@/collections/BlogTags";
import { BlogCategories } from "@/collections/BlogCategories";
import { Blogs } from "@/collections/Blogs";
import { PropertyFeatures } from "@/collections/PropertyFeatures";
import { Properties } from "./collections/Properties";
const filename = fileURLToPath(import.meta.url);
const dirname = path.dirname(filename);
@ -37,7 +39,7 @@ export default buildConfig({
},
theme: "dark",
},
collections: [Users, Media, BlogTags, BlogCategories, Blogs],
collections: [Users, Media, BlogTags, BlogCategories, Blogs, PropertyFeatures, Properties],
editor: lexicalEditor(),
secret: process.env.PAYLOAD_SECRET || "",
typescript: {

View File

@ -4652,6 +4652,13 @@ __metadata:
languageName: node
linkType: hard
"country-state-city@npm:^3.2.1":
version: 3.2.1
resolution: "country-state-city@npm:3.2.1"
checksum: 10c0/2545a000c207345514de31c20ed8a331bba9796f36ab1e6e4019ebb319bca37894180e4ade40eef9d7f2443aa60045ec3f317bfdb3f4c7b99b9c711e4688d8cb
languageName: node
linkType: hard
"croner@npm:9.0.0":
version: 9.0.0
resolution: "croner@npm:9.0.0"
@ -5022,6 +5029,7 @@ __metadata:
"@types/node": "npm:^20"
"@types/react": "npm:^19"
"@types/react-dom": "npm:^19"
country-state-city: "npm:^3.2.1"
dayjs: "npm:^1.11.13"
eslint: "npm:^9"
eslint-config-next: "npm:15.3.0"