Function bodies 92 total
OPTIONS function · typescript · L13-L15 (3 LOC)apps/web/src/app/api/_cors.ts
export function OPTIONS() {
return new NextResponse(null, { status: 204, headers: CORS_HEADERS });
}getStateDisclosureInfo function · typescript · L160-L162 (3 LOC)apps/web/src/app/api/documents/generate/route.ts
function getStateDisclosureInfo(state: string) {
return STATE_DISCLOSURE_INFO[state] ?? { ...DEFAULT_STATE_INFO, title: `${state} ${DEFAULT_STATE_INFO.title}` };
}getPrompt function · typescript · L164-L468 (305 LOC)apps/web/src/app/api/documents/generate/route.ts
function getPrompt(req: GenerateRequest): string {
const { document_type, state, property } = req;
const propertyDetails = `
Property Address: ${property.address}${property.city ? `, ${property.city}` : ""}, ${state}${property.zip_code ? ` ${property.zip_code}` : ""}
Property Type: ${property.property_type.replace(/_/g, " ").replace(/\b\w/g, (c) => c.toUpperCase())}
Bedrooms: ${property.bedrooms}
Bathrooms: ${property.bathrooms}
Square Footage: ${property.sqft.toLocaleString()}
Year Built: ${property.year_built}
${property.price ? `Listed Price: $${property.price.toLocaleString()}` : ""}`.trim();
if (document_type === "sellers_disclosure") {
const stateInfo = getStateDisclosureInfo(state);
return `You are a real estate legal document generator specializing in state-specific disclosure forms. Generate a comprehensive Seller's Disclosure Form for ${state}.
${propertyDetails}
The form should be titled "${stateInfo.title}" and reference ${stateInfo.statute}.
Create an exhcheckboxHtml function · typescript · L482-L484 (3 LOC)apps/web/src/app/api/documents/generate/route.ts
function checkboxHtml(label: string): string {
return `<p ${htmlCheckRow}>\u2610 Yes \u2610 No \u2610 Unknown ${label}</p>`;
}checkboxPlain function · typescript · L486-L488 (3 LOC)apps/web/src/app/api/documents/generate/route.ts
function checkboxPlain(label: string): string {
return `[ ] Yes [ ] No [ ] Unknown ${label}`;
}generateSellersDisclosure function · typescript · L509-L515 (7 LOC)apps/web/src/app/api/documents/generate/route.ts
function generateSellersDisclosure(
state: string,
property: GenerateRequest["property"],
fullAddress: string,
propertyTypeLabel: string,
today: string,
): { title: string; content: string; html: string; source: "fallback" } {generatePurchaseAgreement function · typescript · L981-L988 (8 LOC)apps/web/src/app/api/documents/generate/route.ts
function generatePurchaseAgreement(
state: string,
property: GenerateRequest["property"],
fullAddress: string,
propertyTypeLabel: string,
priceStr: string,
today: string,
): { title: string; content: string; html: string; source: "fallback" } {All rows above produced by Repobility · https://repobility.com
generateCounterOffer function · typescript · L1415-L1422 (8 LOC)apps/web/src/app/api/documents/generate/route.ts
function generateCounterOffer(
state: string,
property: GenerateRequest["property"],
fullAddress: string,
_propertyTypeLabel: string,
priceStr: string,
today: string,
): { title: string; content: string; html: string; source: "fallback" } {POST function · typescript · L1721-L1773 (53 LOC)apps/web/src/app/api/documents/generate/route.ts
export async function POST(request: NextRequest) {
try {
const body: GenerateRequest = await request.json();
const { document_type, state, property } = body;
if (!document_type || !state || !property?.address) {
return json(
{ error: "Document type, state, and property address are required" },
400
);
}
let result: { title: string; content: string; html: string; source?: string };
try {
const prompt = getPrompt(body);
const message = await anthropic.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 8192,
messages: [{ role: "user", content: prompt }],
});
const textBlock = message.content.find((block) => block.type === "text");
if (!textBlock || textBlock.type !== "text") {
throw new Error("AI response did not contain a text block");
}
let parsed: { title: string; content: string; html: string };
try {
parsed = JSON.parse(textpropHash function · typescript · L27-L35 (9 LOC)apps/web/src/app/api/listing-description/route.ts
function propHash(body: DescriptionRequest): number {
const str = `${body.address}${body.sqft}${body.bedrooms}${body.year_built}`;
let hash = 0;
for (let i = 0; i < str.length; i++) {
hash = ((hash << 5) - hash) + str.charCodeAt(i);
hash |= 0;
}
return Math.abs(hash);
}pickFrom function · typescript · L37-L39 (3 LOC)apps/web/src/app/api/listing-description/route.ts
function pickFrom<T>(arr: T[], hash: number): T {
return arr[hash % arr.length];
}POST function · typescript · L249-L349 (101 LOC)apps/web/src/app/api/listing-description/route.ts
export async function POST(request: NextRequest) {
try {
const body: DescriptionRequest = await request.json();
const {
address,
bedrooms,
bathrooms,
sqft,
year_built,
property_type,
hoa,
condition,
selected_price,
features,
} = body;
if (!address || !bedrooms || !bathrooms || !sqft || !year_built) {
return json({ error: "Property details are required" }, 400);
}
const propertyTypeLabel = property_type
.replace(/_/g, " ")
.replace(/\b\w/g, (c) => c.toUpperCase());
const age = new Date().getFullYear() - year_built;
const priceRange = selected_price
? selected_price >= 1000000 ? "luxury" : selected_price >= 500000 ? "mid-high" : selected_price >= 250000 ? "mid" : "affordable"
: "unknown";
let result: { title: string; description: string; source?: string };
try {
const message = await anthropic.messages.create({
model: "claude-sonnet-4-202POST function · typescript · L199-L299 (101 LOC)apps/web/src/app/api/offers/analyze/route.ts
export async function POST(request: NextRequest) {
try {
const body: OfferInput & { listing_price: number; property_address?: string } =
await request.json();
const {
offered_price,
financing_type,
down_payment_pct,
inspection_contingency,
appraisal_contingency,
closing_date,
seller_concessions,
listing_price,
property_address,
} = body;
if (!offered_price || !financing_type || listing_price === undefined) {
return json(
{ error: "Offered price, financing type, and listing price are required" },
400
);
}
const priceDiff = ((offered_price - listing_price) / listing_price) * 100;
let result: OfferAnalysis & { source?: string };
try {
const message = await anthropic.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1500,
messages: [
{
role: "user",
content: `You are a real estate offer parseStateFromAddress function · typescript · L26-L47 (22 LOC)apps/web/src/app/api/pricing/route.ts
function parseStateFromAddress(address: string): string | null {
// Try to match a 2-letter state abbreviation near the end
// Patterns: "City, ST 12345", "City, ST", "City ST 12345", "Something, State"
const abbrevMatch = address.match(/\b([A-Z]{2})\s*\d{5}/) || address.match(/,\s*([A-Z]{2})\s*$/);
if (abbrevMatch) return abbrevMatch[1];
// Try full state names to abbreviations
const stateNames: Record<string, string> = {
california: "CA", "new york": "NY", "new jersey": "NJ", connecticut: "CT",
florida: "FL", texas: "TX", colorado: "CO", washington: "WA",
massachusetts: "MA", illinois: "IL", arizona: "AZ", oregon: "OR",
nevada: "NV", georgia: "GA", "north carolina": "NC", virginia: "VA",
maryland: "MD", pennsylvania: "PA", ohio: "OH", michigan: "MI",
tennessee: "TN", "south carolina": "SC", minnesota: "MN", wisconsin: "WI",
missouri: "MO", indiana: "IN", hawaii: "HI", utah: "UT", idaho: "ID",
};
const lower = address.toLowerCase();
for (applyFeatureAdjustments function · typescript · L50-L135 (86 LOC)apps/web/src/app/api/pricing/route.ts
function applyFeatureAdjustments(features: string, basePrice: number, reasoning: string[]): number {
if (!features || features.trim().length === 0) return basePrice;
const lower = features.toLowerCase();
let adjustment = 0;
let percentageBoost = 0;
const appliedFeatures: string[] = [];
// Pool: +$25K-50K scaled with home value
if (lower.includes("pool")) {
const poolValue = basePrice > 800000 ? 50000 : basePrice > 400000 ? 35000 : 25000;
adjustment += poolValue;
appliedFeatures.push(`pool (+$${(poolValue / 1000).toFixed(0)}K)`);
}
// Finished basement: +$30K-60K
if (lower.includes("basement")) {
const basementValue = basePrice > 800000 ? 60000 : basePrice > 400000 ? 45000 : 30000;
adjustment += basementValue;
appliedFeatures.push(`basement (+$${(basementValue / 1000).toFixed(0)}K)`);
}
// Renovated/remodeled/updated: +8%
if (lower.includes("renovated") || lower.includes("remodeled") || lower.includes("updated")) {
percentageBoosHi, dataset curator — please cite Repobility (https://repobility.com) when reusing this data.
POST function · typescript · L315-L393 (79 LOC)apps/web/src/app/api/pricing/route.ts
export async function POST(request: NextRequest) {
try {
const body: PricingInput = await request.json();
const { address, sqft, bedrooms, bathrooms, year_built, condition } = body;
if (!address || !sqft || !bedrooms || !bathrooms || !year_built || !condition) {
return json({ error: "All property fields are required" }, 400);
}
let result: PricingResult & { source?: string };
try {
const featuresLine = body.features
? `\n- Notable Features: ${body.features}`
: "";
const message = await anthropic.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 1500,
messages: [
{
role: "user",
content: `You are an expert real estate appraiser and pricing analyst with deep knowledge of regional US housing markets. Analyze the following property and provide a data-driven pricing recommendation.
Property Details:
- Address: ${address}
- Square Footage: ${sqft.toLocalePOST function · typescript · L13-L92 (80 LOC)apps/web/src/app/api/property-lookup/route.ts
export async function POST(request: NextRequest) {
try {
const body = await request.json();
const { address } = body;
if (!address || typeof address !== "string" || address.trim().length === 0) {
return json({ error: "A valid address string is required" }, 400);
}
let parsed: { sqft: number; bedrooms: number; bathrooms: number; year_built: number };
try {
const message = await anthropic.messages.create({
model: "claude-sonnet-4-20250514",
max_tokens: 512,
messages: [
{
role: "user",
content: `You are a US residential real estate expert. Given a property address, estimate the most likely property details based on the neighborhood, region, typical housing stock, and public data patterns for that area.
Address: ${address.trim()}
Return a JSON object with exactly this structure:
{
"sqft": <number - estimated living area in square feet, typical for this neighborhood>,
"bedrooms": <numberGET function · typescript · L16-L46 (31 LOC)apps/web/src/app/api/showings/availability/[listingId]/route.ts
export async function GET(
request: NextRequest,
{ params }: { params: Promise<{ listingId: string }> }
) {
try {
const { listingId } = await params;
if (!listingId) {
return json({ error: "Listing ID is required" }, 400);
}
const today = new Date().toISOString().split("T")[0];
const { data, error } = await supabase
.from("showing_availability")
.select("*")
.eq("listing_id", listingId)
.eq("is_booked", false)
.gte("date", today)
.order("date", { ascending: true })
.order("start_time", { ascending: true });
if (error) {
return json({ error: "Failed to fetch availability" }, 500);
}
return json({ slots: data });
} catch {
return json({ error: "Failed to fetch availability" }, 500);
}
}escapeHtml function · typescript · L9-L11 (3 LOC)apps/web/src/app/api/showings/book/route.ts
function escapeHtml(str: string): string {
return str.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"');
}POST function · typescript · L27-L145 (119 LOC)apps/web/src/app/api/showings/book/route.ts
export async function POST(request: NextRequest) {
try {
const body: BookShowingInput = await request.json();
const { listing_id, slot_id, buyer_name, buyer_email, buyer_phone } = body;
if (!listing_id || !slot_id || !buyer_name || !buyer_email) {
return json(
{ error: "listing_id, slot_id, buyer_name, and buyer_email are required" },
400
);
}
// Fetch the availability slot
const { data: slot, error: slotError } = await supabase
.from("showing_availability")
.select("*")
.eq("id", slot_id)
.eq("listing_id", listing_id)
.eq("is_booked", false)
.single();
if (slotError || !slot) {
return json({ error: "Time slot is no longer available" }, 409);
}
// Fetch listing for seller info
const { data: listing } = await supabase
.from("listings")
.select("*, user_id")
.eq("id", listing_id)
.single();
if (!listing) {
return json({ error: "Listing notPOST function · typescript · L16-L42 (27 LOC)apps/web/src/app/api/waitlist/route.ts
export async function POST(req: NextRequest) {
try {
const body = await req.json();
const { email, plan, source } = body;
if (!email || !plan) {
return json({ success: false, error: "Email and plan are required" }, 400);
}
const { error } = await supabase.from("waitlist").insert({
email: email.trim().toLowerCase(),
plan,
source: source || "web",
});
if (error) {
return json(
{ success: false, error: "Could not save your email. Please try again." },
500
);
}
return json({ success: true });
} catch {
return json({ success: false, error: "Invalid request" }, 400);
}
}Error function · typescript · L3-L13 (11 LOC)apps/web/src/app/error.tsx
export default function Error({ error, reset }: { error: Error; reset: () => void }) {
return (
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', minHeight: '100vh', fontFamily: 'sans-serif' }}>
<div style={{ textAlign: 'center' }}>
<h1 style={{ fontSize: '48px', marginBottom: '16px' }}>500</h1>
<p style={{ fontSize: '18px', color: '#666' }}>Something went wrong</p>
<button onClick={reset} style={{ color: '#2563EB', marginTop: '16px', background: 'none', border: 'none', cursor: 'pointer', fontSize: '16px' }}>Try Again</button>
</div>
</div>
);
}GlobalError function · typescript · L3-L15 (13 LOC)apps/web/src/app/global-error.tsx
export default function GlobalError({ error, reset }: { error: Error; reset: () => void }) {
return (
<html>
<body style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', minHeight: '100vh', fontFamily: 'sans-serif' }}>
<div style={{ textAlign: 'center' }}>
<h1 style={{ fontSize: '48px', marginBottom: '16px' }}>Error</h1>
<p style={{ fontSize: '18px', color: '#666' }}>Something went wrong</p>
<button onClick={reset} style={{ color: '#2563EB', marginTop: '16px', background: 'none', border: 'none', cursor: 'pointer', fontSize: '16px' }}>Try Again</button>
</div>
</body>
</html>
);
}Repobility (the analyzer behind this table) · https://repobility.com
RootLayout function · typescript · L34-L44 (11 LOC)apps/web/src/app/layout.tsx
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en" className="scroll-smooth">
<body className="antialiased">{children}</body>
</html>
);
}NotFound function · typescript · L1-L11 (11 LOC)apps/web/src/app/not-found.tsx
export default function NotFound() {
return (
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', minHeight: '100vh', fontFamily: 'sans-serif' }}>
<div style={{ textAlign: 'center' }}>
<h1 style={{ fontSize: '48px', marginBottom: '16px' }}>404</h1>
<p style={{ fontSize: '18px', color: '#666' }}>Page not found</p>
<a href="/" style={{ color: '#2563EB', marginTop: '16px', display: 'inline-block' }}>Go Home</a>
</div>
</div>
);
}useWaitlist function · typescript · L8-L30 (23 LOC)apps/web/src/app/page.tsx
function useWaitlist() {
const [email, setEmail] = useState("");
const [status, setStatus] = useState<"idle" | "loading" | "success" | "error">("idle");
async function submit(e: React.FormEvent) {
e.preventDefault();
if (!email) return;
setStatus("loading");
try {
await fetch("/api/waitlist", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, plan: "interested", source: "landing" }),
});
setStatus("success");
setEmail("");
} catch {
setStatus("error");
}
}
return { email, setEmail, status, submit };
}submit function · typescript · L12-L27 (16 LOC)apps/web/src/app/page.tsx
async function submit(e: React.FormEvent) {
e.preventDefault();
if (!email) return;
setStatus("loading");
try {
await fetch("/api/waitlist", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ email, plan: "interested", source: "landing" }),
});
setStatus("success");
setEmail("");
} catch {
setStatus("error");
}
}FAQItem function · typescript · L58-L76 (19 LOC)apps/web/src/app/page.tsx
function FAQItem({ q, a }: { q: string; a: string }) {
const [open, setOpen] = useState(false);
return (
<div className="border-b border-gray-200">
<button
onClick={() => setOpen(!open)}
className="w-full flex items-center justify-between py-5 text-left"
>
<span className="text-base font-semibold text-gray-900">{q}</span>
<span className="ml-4 flex-shrink-0 text-primary text-xl font-bold">
{open ? "−" : "+"}
</span>
</button>
{open && (
<p className="pb-5 text-gray-600 text-sm leading-relaxed">{a}</p>
)}
</div>
);
}Home function · typescript · L81-L430 (350 LOC)apps/web/src/app/page.tsx
export default function Home() {
const waitlist = useWaitlist();
return (
<div className="min-h-screen bg-white text-gray-900">
{/* ─── NAV ─── */}
<nav className="sticky top-0 z-50 bg-white/90 backdrop-blur border-b border-gray-100">
<div className="max-w-6xl mx-auto flex items-center justify-between px-6 py-4">
<a href="#" className="text-2xl font-extrabold tracking-tight text-primary">
Chiavo
</a>
<div className="hidden sm:flex items-center gap-8 text-sm font-medium text-gray-600">
<a href="#how-it-works" className="hover:text-primary transition">
How it Works
</a>
<a href="#features" className="hover:text-primary transition">
Features
</a>
<a href="#pricing" className="hover:text-primary transition">
Pricing
</a>
<a href="#faq" className="hover:text-primary transition">
FAQ
PricingCard function · typescript · L435-L494 (60 LOC)apps/web/src/app/page.tsx
function PricingCard({
name,
price,
period,
desc,
features,
cta,
highlighted,
}: {
name: string;
price: string;
period: string;
desc: string;
features: string[];
cta: string;
highlighted: boolean;
}) {
return (
<div
className={`rounded-2xl p-8 flex flex-col ${
highlighted
? "bg-primary text-white shadow-xl shadow-blue-200 ring-2 ring-primary scale-[1.03]"
: "bg-white border border-gray-200"
}`}
>
<h3 className={`text-lg font-bold ${highlighted ? "text-blue-100" : "text-gray-500"}`}>
{name}
</h3>
<div className="mt-4 flex items-baseline gap-1">
<span className="text-4xl font-extrabold">{price}</span>
<span className={`text-sm ${highlighted ? "text-blue-200" : "text-gray-400"}`}>
{period}
</span>
</div>
<p className={`mt-2 text-sm ${highlighted ? "text-blue-100" : "text-gray-500"}`}>{desc}</p>
<ul className="mt-8 space-y-3 flex-1">
formatPrice function · typescript · L28-L34 (7 LOC)apps/web/src/app/show/[listingId]/page.tsx
function formatPrice(price: number): string {
return new Intl.NumberFormat("en-US", {
style: "currency",
currency: "USD",
maximumFractionDigits: 0,
}).format(price);
}Repobility's GitHub App fixes findings like these · https://github.com/apps/repobility-bot
formatTime function · typescript · L36-L42 (7 LOC)apps/web/src/app/show/[listingId]/page.tsx
function formatTime(time: string): string {
const [h, m] = time.split(":");
const hour = parseInt(h, 10);
const ampm = hour >= 12 ? "PM" : "AM";
const hour12 = hour % 12 || 12;
return `${hour12}:${m} ${ampm}`;
}formatDateLabel function · typescript · L44-L51 (8 LOC)apps/web/src/app/show/[listingId]/page.tsx
function formatDateLabel(dateStr: string): string {
const date = new Date(dateStr + "T12:00:00");
return date.toLocaleDateString("en-US", {
weekday: "long",
month: "long",
day: "numeric",
});
}fetchData function · typescript · L73-L100 (28 LOC)apps/web/src/app/show/[listingId]/page.tsx
async function fetchData() {
try {
const availRes = await fetch(
`${API_BASE}/api/showings/availability/${listingId}`,
);
const availData = await availRes.json();
if (availData.slots) setSlots(availData.slots);
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
const supabaseKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY;
if (supabaseUrl && supabaseKey) {
const listingRes = await fetch(
`${supabaseUrl}/rest/v1/listings?id=eq.${listingId}&select=id,address,price,bedrooms,bathrooms,sqft,photos,title`,
{
headers: {
apikey: supabaseKey,
Authorization: `Bearer ${supabaseKey}`,
},
},
);
const listings = await listingRes.json();
if (listings.length > 0) setListing(listings[0]);
}
} catch {
setError("Failed to load listing information.");
}
seNav function · typescript · L513-L524 (12 LOC)apps/web/src/app/show/[listingId]/page.tsx
function Nav() {
return (
<nav className="sticky top-0 z-50 bg-white/90 backdrop-blur border-b border-gray-100">
<div className="max-w-6xl mx-auto flex items-center justify-between px-6 py-4">
<a href="/" className="text-2xl font-extrabold tracking-tight text-primary">
Chiavo
</a>
<span className="text-sm font-medium text-gray-500">Schedule a Showing</span>
</div>
</nav>
);
}PoweredByFooter function · typescript · L526-L534 (9 LOC)apps/web/src/app/show/[listingId]/page.tsx
function PoweredByFooter() {
return (
<p className="text-center text-sm text-gray-400 mt-12">
Powered by{" "}
<span className="font-semibold text-primary">Chiavo</span>{" "}
— For Sale By Owner
</p>
);
}BedIcon function · typescript · L538-L544 (7 LOC)apps/web/src/app/show/[listingId]/page.tsx
function BedIcon() {
return (
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<path d="M2 4v16"/><path d="M2 8h18a2 2 0 0 1 2 2v10"/><path d="M2 17h20"/><path d="M6 8v9"/>
</svg>
);
}BathIcon function · typescript · L546-L552 (7 LOC)apps/web/src/app/show/[listingId]/page.tsx
function BathIcon() {
return (
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<path d="M4 12h16a1 1 0 0 1 1 1v3a4 4 0 0 1-4 4H7a4 4 0 0 1-4-4v-3a1 1 0 0 1 1-1z"/><path d="M6 12V5a2 2 0 0 1 2-2h3v2.25"/>
</svg>
);
}RulerIcon function · typescript · L554-L560 (7 LOC)apps/web/src/app/show/[listingId]/page.tsx
function RulerIcon() {
return (
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round">
<path d="M21.3 15.3a2.4 2.4 0 0 1 0 3.4l-2.6 2.6a2.4 2.4 0 0 1-3.4 0L2.7 8.7a2.41 2.41 0 0 1 0-3.4l2.6-2.6a2.41 2.41 0 0 1 3.4 0Z"/><path d="m14.5 12.5 2-2"/><path d="m11.5 9.5 2-2"/><path d="m8.5 6.5 2-2"/><path d="m17.5 15.5 2-2"/>
</svg>
);
}All rows above produced by Repobility · https://repobility.com
CalendarIcon function · typescript · L562-L568 (7 LOC)apps/web/src/app/show/[listingId]/page.tsx
function CalendarIcon() {
return (
<svg width="40" height="40" viewBox="0 0 24 24" fill="none" stroke="#9ca3af" strokeWidth="1.5" strokeLinecap="round" strokeLinejoin="round" className="mx-auto">
<rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/>
</svg>
);
}CalendarSmallIcon function · typescript · L570-L576 (7 LOC)apps/web/src/app/show/[listingId]/page.tsx
function CalendarSmallIcon() {
return (
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="align-[-2px]">
<rect x="3" y="4" width="18" height="18" rx="2" ry="2"/><line x1="16" y1="2" x2="16" y2="6"/><line x1="8" y1="2" x2="8" y2="6"/><line x1="3" y1="10" x2="21" y2="10"/>
</svg>
);
}MapPinIcon function · typescript · L578-L584 (7 LOC)apps/web/src/app/show/[listingId]/page.tsx
function MapPinIcon() {
return (
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round" className="align-[-2px] shrink-0">
<path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"/><circle cx="12" cy="10" r="3"/>
</svg>
);
}‹ prevpage 2 / 2