fix: properties feature, add InputState and InputCity payload custom components #10
@ -9,6 +9,7 @@ import FilterProperty from "@/components/properties/FilterProperty";
|
||||
import { getDefaultMetadata } from "@/utils/metadata";
|
||||
import { sanitizeBlogContentIntoStringPreview } from "@/utils/sanitize";
|
||||
import { Metadata } from "next";
|
||||
import { State } from "country-state-city";
|
||||
|
||||
export async function generateMetadata(props: { params: Promise<{ slug: string }> }): Promise<Metadata> {
|
||||
const metadata = await getDefaultMetadata();
|
||||
@ -67,6 +68,9 @@ export default async function PropertyDetail({ params }: { params: Promise<{ slu
|
||||
if (!propertyDetail) return notFound();
|
||||
|
||||
const { data, formattedData } = propertyDetail;
|
||||
const stateName = !!data?.addressGroup.state_code
|
||||
? State.getStateByCodeAndCountry(data.addressGroup.state_code, "US")?.name
|
||||
: "";
|
||||
const isEmbedMapUrlValid = !!data?.embed_map_url && data.embed_map_url.includes("www.google.com/maps/embed");
|
||||
const headersList = await headers();
|
||||
const fullUrl = headersList.get("x-full-url");
|
||||
@ -207,8 +211,8 @@ export default async function PropertyDetail({ params }: { params: Promise<{ slu
|
||||
<dd>{data?.addressGroup?.address ?? ""}</dd>
|
||||
</dl>
|
||||
<dl className="list-terms-inline">
|
||||
<dt>State/County:</dt>
|
||||
<dd>{data?.addressGroup?.state_code ?? ""}</dd>
|
||||
<dt>State:</dt>
|
||||
<dd>{stateName}</dd>
|
||||
</dl>
|
||||
<dl className="list-terms-inline">
|
||||
<dt>City:</dt>
|
||||
|
@ -21,6 +21,8 @@ import { StrikethroughFeatureClient as StrikethroughFeatureClient_e70f5e05f09f93
|
||||
import { UnderlineFeatureClient as UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { BoldFeatureClient as BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { ItalicFeatureClient as ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
|
||||
import { default as default_4ee76229d13ecca9be829e8a71d2a59d } from '../../../components/payload-custom/InputState'
|
||||
import { default as default_d6f7a60d9f647737f677c5b38081a35f } from '../../../components/payload-custom/InputCity'
|
||||
import { default as default_aa89fa9464216e16b81a3e716c94a23a } from '../../../components/LogoAdmin'
|
||||
import { S3ClientUploadHandler as S3ClientUploadHandler_f97aa6c64367fa259c5bc0567239ef24 } from '@payloadcms/storage-s3/client'
|
||||
|
||||
@ -48,6 +50,8 @@ export const importMap = {
|
||||
"@payloadcms/richtext-lexical/client#UnderlineFeatureClient": UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#BoldFeatureClient": BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"@payloadcms/richtext-lexical/client#ItalicFeatureClient": ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
|
||||
"/components/payload-custom/InputState#default": default_4ee76229d13ecca9be829e8a71d2a59d,
|
||||
"/components/payload-custom/InputCity#default": default_d6f7a60d9f647737f677c5b38081a35f,
|
||||
"/components/LogoAdmin#default": default_aa89fa9464216e16b81a3e716c94a23a,
|
||||
"@payloadcms/storage-s3/client#S3ClientUploadHandler": S3ClientUploadHandler_f97aa6c64367fa259c5bc0567239ef24
|
||||
}
|
||||
|
@ -81,18 +81,25 @@ export const Properties: CollectionConfig = {
|
||||
name: "state_code",
|
||||
label: "State",
|
||||
type: "text",
|
||||
// admin: {
|
||||
// components: {
|
||||
// Field: {
|
||||
// path: "/components/payload-custom/InputCountry",
|
||||
// },
|
||||
// },
|
||||
// },
|
||||
admin: {
|
||||
components: {
|
||||
Field: {
|
||||
path: "/components/payload-custom/InputState",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "city_code",
|
||||
label: "City",
|
||||
type: "text",
|
||||
admin: {
|
||||
components: {
|
||||
Field: {
|
||||
path: "/components/payload-custom/InputCity",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "zip_code",
|
||||
|
34
src/components/payload-custom/InputCity.tsx
Normal file
34
src/components/payload-custom/InputCity.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
"use client";
|
||||
import type { SelectFieldClientComponent } from "payload";
|
||||
|
||||
import { SelectField, useField, useFormFields } from "@payloadcms/ui";
|
||||
import { City } from "country-state-city";
|
||||
import { useEffect } from "react";
|
||||
|
||||
const InputCity: SelectFieldClientComponent = ({ field, ...props }) => {
|
||||
const stateCode = useFormFields(([fields]) => fields["addressGroup.state_code"]);
|
||||
const { setValue } = useField();
|
||||
|
||||
useEffect(() => {
|
||||
if (!stateCode?.value) {
|
||||
setValue("");
|
||||
}
|
||||
}, [stateCode?.value]);
|
||||
|
||||
if (!stateCode?.value) {
|
||||
// @ts-ignore
|
||||
field.admin = { ...field.admin, description: "Please select the state before select the city." };
|
||||
field.options = [];
|
||||
} else {
|
||||
// @ts-ignore
|
||||
field.admin = { ...field.admin, description: "" };
|
||||
field.options = City.getCitiesOfState("US", stateCode.value as string).map((c) => ({
|
||||
value: c.name,
|
||||
label: c.name,
|
||||
}));
|
||||
}
|
||||
|
||||
return <SelectField field={field} {...props} />;
|
||||
};
|
||||
|
||||
export default InputCity;
|
@ -1,37 +0,0 @@
|
||||
"use client";
|
||||
import React from "react";
|
||||
import { useField } from "@payloadcms/ui";
|
||||
import { TextFieldClientComponent } from "payload";
|
||||
|
||||
const InputCountry: TextFieldClientComponent = ({ path, field }) => {
|
||||
const { value, setValue } = useField({ path });
|
||||
const { showError } = useField();
|
||||
|
||||
return (
|
||||
<div className={`field-type select ${showError ? "has-error" : ""}`}>
|
||||
{/* @ts-ignore */}
|
||||
<span>jancok</span>
|
||||
{/* <label htmlFor={field.name} required={field.required}></label> */}
|
||||
<div className="select-input-wrapper">
|
||||
<select
|
||||
name={field.name}
|
||||
// @ts-ignore
|
||||
value={value}
|
||||
onChange={(e) => setValue(e.target.value)}
|
||||
disabled={field.admin?.readOnly}
|
||||
>
|
||||
<option value="">-- Select --</option>
|
||||
{/* {field.map((opt) => (
|
||||
<option key={opt.value} value={opt.value}>
|
||||
{opt.label}
|
||||
</option>
|
||||
))} */}
|
||||
</select>
|
||||
</div>
|
||||
{/* {field.admin && <FieldDescription value={admin.description} />}
|
||||
{showError && <Error message={errorMessage} />} */}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default InputCountry;
|
14
src/components/payload-custom/InputState.tsx
Normal file
14
src/components/payload-custom/InputState.tsx
Normal file
@ -0,0 +1,14 @@
|
||||
"use client";
|
||||
import type { SelectFieldClientComponent } from "payload";
|
||||
|
||||
import { SelectField } from "@payloadcms/ui";
|
||||
import React from "react";
|
||||
import { State } from "country-state-city";
|
||||
|
||||
const InputState: SelectFieldClientComponent = ({ field, ...props }) => {
|
||||
const statesData = State.getStatesOfCountry("US").map((st) => ({ value: st.isoCode, label: st.name }));
|
||||
field.options = statesData;
|
||||
return <SelectField field={field} {...props} />;
|
||||
};
|
||||
|
||||
export default InputState;
|
@ -10,7 +10,10 @@ type FilterPropertyProps = {
|
||||
};
|
||||
|
||||
export default function FilterProperty({ propertyType, searchParams }: FilterPropertyProps) {
|
||||
const statesData = State.getStatesOfCountry("US").map((st) => ({ value: st.name, label: st.name }));
|
||||
const statesData = State.getStatesOfCountry("US").map((st) => ({ value: st.isoCode, label: st.name }));
|
||||
const selectedStateName = !!searchParams?.location
|
||||
? State.getStateByCodeAndCountry(searchParams.location, "US")?.name
|
||||
: "";
|
||||
|
||||
return (
|
||||
<>
|
||||
@ -25,8 +28,9 @@ export default function FilterProperty({ propertyType, searchParams }: FilterPro
|
||||
name="location"
|
||||
placeholder="Choose Location"
|
||||
options={statesData}
|
||||
defaultInputValue={searchParams?.location}
|
||||
defaultValue={searchParams?.location}
|
||||
defaultValue={
|
||||
!!searchParams?.location ? { value: searchParams?.location, label: selectedStateName } : undefined
|
||||
}
|
||||
isSearchable
|
||||
isClearable
|
||||
/>
|
||||
|
Loading…
x
Reference in New Issue
Block a user