### Add Custom Fields via Migration SQL Source: https://directorystack.com/docs/customizations/custom-fields Creates new columns for address, opening_hours, and is_wheelchair_accessible in the listings table using SQL. Requires running the migration in Supabase and committing the changes. ```SQL -- ---\n-- MODULE NAME: Listings Custom Fields\n-- MODULE DATE: 20241215\n-- MODULE SCOPE: Tables\n-- ---\n\nBEGIN;\n\n-- ---\n-- Add Custom Fields to Listings Table\n-- ---\n\n-- Add address field (plain text)\nALTER TABLE public.listings\nADD COLUMN address TEXT;\n\n-- Add opening_hours field (JSON)\nALTER TABLE public.listings\nADD COLUMN opening_hours JSONB;\n\n-- Add is_wheelchair_accessible field (boolean)\nALTER TABLE public.listings\nADD COLUMN is_wheelchair_accessible BOOLEAN DEFAULT FALSE;\n\n-- ---\n-- END OF FILE\n-- ---\n\nCOMMIT; ``` -------------------------------- ### Update Listing Types for Custom Fields Source: https://directorystack.com/docs/customizations/custom-fields Extends the ListingFormSchema and defines OpeningHoursSchema to include new custom fields. Ensures validation for address, opening_hours, and is_wheelchair_accessible. ```TypeScript // Define the opening hours structure\nexport const OpeningHoursSchema = z\n .object({\n monday: z\n .object({\n open: z.string().optional(),\n close: z.string().optional(),\n closed: z.boolean().default(false)\n })\n .optional(),\n tuesday: z\n .object({\n open: z.string().optional(),\n close: z.string().optional(),\n closed: z.boolean().default(false)\n })\n .optional(),\n wednesday: z\n .object({\n open: z.string().optional(),\n close: z.string().optional(),\n closed: z.boolean().default(false)\n })\n .optional(),\n thursday: z\n .object({\n open: z.string().optional(),\n close: z.string().optional(),\n closed: z.boolean().default(false)\n })\n .optional(),\n friday: z\n .object({\n open: z.string().optional(),\n close: z.string().optional(),\n closed: z.boolean().default(false)\n })\n .optional(),\n saturday: z\n .object({\n open: z.string().optional(),\n close: z.string().optional(),\n closed: z.boolean().default(false)\n })\n .optional(),\n sunday: z\n .object({\n open: z.string().optional(),\n close: z.string().optional(),\n closed: z.boolean().default(false)\n })\n .optional()\n })\n .optional();\n\nexport type OpeningHoursType = z.infer;\n\nexport const ListingFormSchema = z.object({\n // Other fields\n\n // Add new custom fields\n address: z.string().optional(),\n opening_hours: OpeningHoursSchema,\n is_wheelchair_accessible: z.boolean().optional()\n}); ``` -------------------------------- ### Update Listing Queries to Include Custom Fields Source: https://directorystack.com/docs/customizations/custom-fields Adds the new custom fields to the FULL_LISTING_PARAMS constant in queries.ts to ensure they are fetched with listing data. ```TypeScript export const FULL_LISTING_PARAMS = `\n /*\n Other params\n */\n\n // Add new custom params\n address,\n opening_hours,\n is_wheelchair_accessible,\n `; ``` -------------------------------- ### Update Listing Overview with Filter Parameter Source: https://directorystack.com/docs/customizations/custom-fields Adds wheelchair accessibility filter parameter to the listing overview component. Passes the filter value from URL params to the data wrapper component. ```TypeScript const wheelchairAccessibleFilter = filterAndSortParams?.wheelchair_accessible === 'true' // Pass it to ListingGridDataWrapper ``` ```TypeScript async function ListingGridDataWrapper({ /* other fields */ // add new field wheelchairAccessibleFilter }: { /* other fields */ // add new field wheelchairAccessibleFilter?: boolean }) { // ... existing code ... const regularSearchData = await getPublishedListings({ inputParams: { /* other fields */ // add new field wheelchairAccessibleFilter } }) // ... rest of the function } ``` -------------------------------- ### Integrate Opening Hours into Public Listing Page Source: https://directorystack.com/docs/customizations/custom-fields Updates the public listing page component to display opening hours alongside other listing information. Includes conditional rendering for custom fields like address, opening hours, and accessibility features. Integrates the OpeningHoursDisplay component for formatted presentation. ```TypeScript/React {/* Add custom fields here */} {listing.address && (
Address
{listing.address}
)} {listing.opening_hours && (
Opening Hours
)} {listing.is_wheelchair_accessible && (
Accessibility
♿ Wheelchair Accessible
)} {/* Existing category and other fields... */}
``` -------------------------------- ### Update Data Fetching with Accessibility Filter Source: https://directorystack.com/docs/customizations/custom-fields Modifies the getPublishedListings function to filter by wheelchair accessibility when the parameter is true. Uses Supabase client to add the filter condition to the database query. ```TypeScript interface InputParams { /* other fields */ // add new field wheelchairAccessibleFilter?: boolean | null } export const getPublishedListings = cache( async ({ inputParams, contextParams }: { inputParams: InputParams contextParams: DataFetchContext }) => { const { /* other fields */ // add new field wheelchairAccessibleFilter } = inputParams // ... existing code ... return withDataFetchErrorHandling("getPublishedListings", async () => { const supabase = createSupabaseBrowserClient() let query = supabase .from(TABLE_NAME_LISTINGS) .select(FULL_LISTING_PARAMS, { count: "exact" }) .match({ is_user_published: true, is_admin_published: true }) // ... existing filters ... if (wheelchairAccessibleFilter) { query = query.eq("is_wheelchair_accessible", true) } // ... rest of the function }) } ) ``` -------------------------------- ### Create Opening Hours Display Component Source: https://directorystack.com/docs/customizations/custom-fields React component for displaying opening hours in a formatted, readable layout on public listing pages. Converts 24-hour time format to 12-hour format with AM/PM indicators, handles closed days, and provides consistent styling for day-by-day hour presentation. ```TypeScript/React // Import External Packages // Import Local Imports import { OpeningHoursType } from "../types/types" // Import Core Dependencies // Import Shared Dependencies // Import Extension Dependencies const DAYS = [ "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday" ] as const export function OpeningHoursDisplay({ hours }: { hours: OpeningHoursType }) { if (!hours) return null const formatTime = (time: string) => { const [hour, minute] = time.split(":") const hourNum = parseInt(hour) const ampm = hourNum >= 12 ? "PM" : "AM" const displayHour = hourNum % 12 || 12 return `${displayHour}:${minute} ${ampm}` } return (
{DAYS.map((day) => { const dayData = hours[day] if (!dayData) return null return (
{day} {dayData.closed ? "Closed" : `${formatTime(dayData.open || "09:00")} - ${formatTime( dayData.close || "17:00" )}`}
) })}
) } ``` -------------------------------- ### Create Opening Hours Editor Component Source: https://directorystack.com/docs/customizations/custom-fields Interactive React component for editing opening hours with day-by-day configuration. Features toggle switches for open/closed states, time input fields, and real-time updates. Uses TypeScript for type safety and integrates with shared UI components from the design system. ```TypeScript/React "use client" // Import External Packages import { useState } from "react" // Import Local Imports import { OpeningHoursType } from "../../types/types" // Import Core Dependencies // Import Shared Dependencies import { Input } from "@shared/ui/input" import { Label } from "@shared/ui/label" import { Switch } from "@shared/ui/switch" import { Card, CardContent, CardHeader, CardTitle } from "@shared/ui/card" // Import Extension Dependencies const DAYS = [ "monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday" ] as const export function OpeningHoursEditor({ value, onChange }: { value?: OpeningHoursType onChange: (value: OpeningHoursType) => void }) { const [hours, setHours] = useState(value ?? {}) const updateDay = (day: (typeof DAYS)[number], dayData: any) => { const newHours = { ...hours, [day]: dayData } setHours(newHours) onChange(newHours) } return ( Opening Hours {DAYS.map((day) => (
{ updateDay(day, { ...hours[day], closed: !checked, open: checked ? hours[day]?.open || "09:00" : undefined, close: checked ? hours[day]?.close || "17:00" : undefined }) }) } /> {!hours[day]?.closed && ( <> updateDay(day, { ...hours[day], open: e.target.value }) } className="w-32" /> to updateDay(day, { ...hours[day], close: e.target.value }) } className="w-32" /> )} {hours[day]?.closed && ( Closed )}
))}
) } ``` -------------------------------- ### Add Internationalization for Accessibility Fields Source: https://directorystack.com/docs/customizations/custom-fields Adds translation strings for accessibility-related UI elements in the English locale file. Includes labels for the filter checkbox, editor fields, and public listing display. ```TypeScript // Add these to the listings section "listings": { "listing-editor": { "section-business-info": { "title": "Business Information", "description": "Additional information about the business location and hours", "field": { "address": { "title": "Address", "description": "The physical address of the business", "placeholder": "123 Main St, City, State 12345" }, "opening-hours": { "title": "Opening Hours", "description": "Business operating hours for each day of the week" }, "wheelchair-accessible": { "title": "Wheelchair Accessible", "description": "Is this location wheelchair accessible?" } } } }, "public-listing-page": { "address": "Address", "opening-hours": "Opening Hours", "accessibility": "Accessibility", "wheelchair-accessible": "Wheelchair Accessible" }, "listings-filter-sidebar": { "accessibility": "Accessibility", "wheelchair-accessible": "Wheelchair Accessible" } } ``` -------------------------------- ### Add Accessibility Filter UI in React Source: https://directorystack.com/docs/customizations/custom-fields Implements a wheelchair accessible checkbox filter in the listings sidebar. Updates URL search parameters when checked/unchecked. Uses Next.js Router for navigation without page reload. ```TypeScript { /* Add this new section after the search section */ } ;

Accessibility

{ const currentUrl = new URL(window.location.href) const currentSearchParams = new URLSearchParams(currentUrl.search) if (checked) { currentSearchParams.set("wheelchair_accessible", "true") } else { currentSearchParams.delete("wheelchair_accessible") } const finalUrl = pathname + "?" + currentSearchParams.toString() Router.push(finalUrl, { scroll: false }) }} />
``` -------------------------------- ### Integrate Form Fields - JSX Source: https://directorystack.com/docs/customizations/custom-fields This code snippet showcases how to integrate the new address, opening hours, and wheelchair accessibility form fields into the user interface using React components and JSX. It utilizes FormField, FormItem, FormLabel, FormDescription, Input, Switch, and OpeningHoursEditor components. ```jsx {/* Add this new section after section-listing-details */} ;

Business Information

Additional information about the business location and hours.

{/* Address Field */} (
Address The physical address of the business
)} /> {/* Opening Hours Field */} (
Opening Hours Business operating hours for each day of the week
)} /> {/* Wheelchair Accessible Field */} (
Wheelchair Accessible Is this location wheelchair accessible?
)} />
``` -------------------------------- ### Update Form Default Values - TypeScript Source: https://directorystack.com/docs/customizations/custom-fields This code snippet demonstrates how to update the default values of a form using React Hook Form and Zod. It includes adding fields for address, opening hours, and wheelchair accessibility. ```typescript const form = useForm( { resolver: zodResolver(ListingFormSchema), defaultValues: { /* Other fields */ // Add new custom fields address: listing?.address ?? "", opening_hours: listing?.opening_hours ?? undefined, is_wheelchair_accessible: listing?.is_wheelchair_accessible ?? false } }) ``` -------------------------------- ### Update Main ListingOverview Function (TypeScript) Source: https://directorystack.com/docs/customizations/custom-fields This snippet shows how to update the main `ListingOverview` function in a TypeScript React component to include a new `wheelchairAccessibleFilter` parameter. It demonstrates passing this filter down to a child component `ListingGridDataWrapper`, enabling new filtering capabilities on the public listing page. Ensure that `filterAndSortParams` is correctly defined and passed to the component. ```typescript export async function ListingOverview({}: // ... existing parameters { // ... existing parameters }) { // ... existing code ... const wheelchairAccessibleFilter = filterAndSortParams?.wheelchair_accessible === "true" return ( {categoryNavigation && {title}} } > {/* ... rest of component */} ) } ``` -------------------------------- ### Configure Supabase Email Template Source: https://directorystack.com/docs/installation/authentication This section demonstrates how to configure the Supabase email template for user signups. The template needs to be updated with the provided HTML code to confirm user signups safely. This ensures the user confirmed signup for the services. ```html

Confirm your signup

Follow this link to confirm your user:

Confirm your mail

``` -------------------------------- ### Back To Top Button Component Implementation Source: https://directorystack.com/docs/general/file-structure A reusable React component that creates a fixed button for scrolling to the top of the page. The component accepts props for customizing button text, icon visibility, styling, and variant type. Uses lucide-react for the arrow icon and includes smooth scrolling behavior. ```jsx 'use client' // Import External Packages import { ArrowUp } from 'lucide-react' // Import Local Imports // Import Core Dependencies // Import Shared Dependencies import { Button, ButtonProps } from '@/ui/Button' import { cn } from '@/lib/utils' // Import Extension Dependencies /** * Renders a button component that scrolls the page to the top when clicked. * * @param buttonText - The text to display on the button. Default is 'Back to top'. * @param showArrowIcon - Determines whether to show an arrow icon next to the button text. Default is true. * @param className - Additional CSS class names to apply to the button. * @param variant - The variant of the button. Default is 'secondary'. */ export default function Button_BackToTop({ buttonText = 'Back to top', showArrowIcon = true, className, variant, }: { buttonText?: string showArrowIcon?: boolean className?: string variant?: ButtonProps['variant'] }) { // Function to scroll the page to the top when the button is clicked const handleClick = () => { window.scrollTo({ top: 0, behavior: 'smooth' }) } return ( ) } ``` -------------------------------- ### File Import Organization Pattern Source: https://directorystack.com/docs/general/file-structure Standardized import section structure that organizes external packages, local imports, and dependencies from core, shared, and extension modules. This pattern allows developers to quickly understand what resources are being used in each file. ```javascript // Import External Packages <- External Packages like React // Import Local Imports <- A module's own components, functions, etc. // Import Core Dependencies <- Files from Core Modules // Import Shared Dependencies <- Files from Shared Modules // Import Extension Dependencies <- Files from Extension Modules ``` -------------------------------- ### Different Fonts for Headings and Body (TypeScript/JSX) Source: https://directorystack.com/docs/customizations/fonts Implements distinct fonts for headings and body text by modifying `layout.tsx`, `globals.css`, and `tailwind.config.js`. This process involves importing and configuring two different fonts, applying them in CSS, and defining them in the Tailwind CSS theme configuration. Dependencies include 'next/font/google' and 'tailwindcss/defaultTheme'. ```typescript // Part 1 import { Bricolage_Grotesque } from 'next/font/google' import { Space_Mono } from 'next/font/google' // Part 2 const fontHeading = Bricolage_Grotesque({ subsets: ['latin'], display: 'swap', variable: '--font-heading', }) const fontBody = Space_Mono({ subsets: ['latin'], display: 'swap', variable: '--font-body', }) // Part 3 ``` ```css @layer base { body { @apply font-body; } h1, h2, h3, h4, h5, h6 { @apply font-heading; } } ``` ```javascript import { fontFamily } from 'tailwindcss/defaultTheme'; export default { theme: { extend: { fontFamily: { heading: ['var(--font-heading)', ...fontFamily.sans], body: ['var(--font-body)', ...fontFamily.mono], }, }, }, }; ``` -------------------------------- ### Change Default Font (TypeScript/JSX) Source: https://directorystack.com/docs/customizations/fonts Modifies the default font for headings and regular text in the application by updating the `layout.tsx` file. This involves importing a new font, instantiating it with specific options, and applying its variable to the html tag. Dependencies include the 'next/font/google' package. ```typescript // Part 1 import { Inter } from 'next/font/google'; // Part 2 const inter = Inter({ variable: '--font-inter', subsets: ['latin'], display: 'swap', }); // Part 3 ``` ```typescript // Part 1 import { Space_Mono } from 'next/font/google' // Part 2 const SpaceMono = Space_Mono({ subsets: ['latin'], display: 'swap', variable: '--font-body', }) // Part 3 ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.