From 8882cb6d763ed270266cf809886b3f199ae31d14 Mon Sep 17 00:00:00 2001 From: Pattadon Date: Tue, 8 Apr 2025 14:03:56 +0700 Subject: [PATCH 01/19] feat: add property detail and listings pages with filtering options - Implemented PropertyDetailPage to display detailed information about a specific property, including images, features, amenities, and analytics. - Created PropertiesPage for listing properties with filtering options such as price range, property type, bedrooms, bathrooms, area, and location. - Added loading state component for properties. - Introduced reusable components for property cards in both grid and list views. - Enhanced user experience with navigation links and breadcrumb trails. --- .../app/{(routes) => (topbar)}/data-pipeline/create/page.tsx | 0 frontend/app/{(routes) => (topbar)}/data-pipeline/page.tsx | 0 .../data-pipeline/property-listings/page.tsx | 0 frontend/app/{(routes) => (topbar)}/documentation/loading.tsx | 0 .../app/{(routes) => (topbar)}/documentation/models/page.tsx | 0 frontend/app/{(routes) => (topbar)}/documentation/page.tsx | 0 frontend/app/{(routes) => (topbar)}/maps/page.tsx | 0 frontend/app/{(routes) => (topbar)}/models/page.tsx | 0 frontend/app/{(routes) => (topbar)}/price-prediction/page.tsx | 0 frontend/app/{(routes) => (topbar)}/properties/[id]/page.tsx | 0 frontend/app/{(routes) => (topbar)}/properties/loading.tsx | 0 frontend/app/{(routes) => (topbar)}/properties/page.tsx | 0 frontend/components/navigation/top-navigation.tsx | 3 ++- 13 files changed, 2 insertions(+), 1 deletion(-) rename frontend/app/{(routes) => (topbar)}/data-pipeline/create/page.tsx (100%) rename frontend/app/{(routes) => (topbar)}/data-pipeline/page.tsx (100%) rename frontend/app/{(routes) => (topbar)}/data-pipeline/property-listings/page.tsx (100%) rename frontend/app/{(routes) => (topbar)}/documentation/loading.tsx (100%) rename frontend/app/{(routes) => (topbar)}/documentation/models/page.tsx (100%) rename frontend/app/{(routes) => (topbar)}/documentation/page.tsx (100%) rename frontend/app/{(routes) => (topbar)}/maps/page.tsx (100%) rename frontend/app/{(routes) => (topbar)}/models/page.tsx (100%) rename frontend/app/{(routes) => (topbar)}/price-prediction/page.tsx (100%) rename frontend/app/{(routes) => (topbar)}/properties/[id]/page.tsx (100%) rename frontend/app/{(routes) => (topbar)}/properties/loading.tsx (100%) rename frontend/app/{(routes) => (topbar)}/properties/page.tsx (100%) diff --git a/frontend/app/(routes)/data-pipeline/create/page.tsx b/frontend/app/(topbar)/data-pipeline/create/page.tsx similarity index 100% rename from frontend/app/(routes)/data-pipeline/create/page.tsx rename to frontend/app/(topbar)/data-pipeline/create/page.tsx diff --git a/frontend/app/(routes)/data-pipeline/page.tsx b/frontend/app/(topbar)/data-pipeline/page.tsx similarity index 100% rename from frontend/app/(routes)/data-pipeline/page.tsx rename to frontend/app/(topbar)/data-pipeline/page.tsx diff --git a/frontend/app/(routes)/data-pipeline/property-listings/page.tsx b/frontend/app/(topbar)/data-pipeline/property-listings/page.tsx similarity index 100% rename from frontend/app/(routes)/data-pipeline/property-listings/page.tsx rename to frontend/app/(topbar)/data-pipeline/property-listings/page.tsx diff --git a/frontend/app/(routes)/documentation/loading.tsx b/frontend/app/(topbar)/documentation/loading.tsx similarity index 100% rename from frontend/app/(routes)/documentation/loading.tsx rename to frontend/app/(topbar)/documentation/loading.tsx diff --git a/frontend/app/(routes)/documentation/models/page.tsx b/frontend/app/(topbar)/documentation/models/page.tsx similarity index 100% rename from frontend/app/(routes)/documentation/models/page.tsx rename to frontend/app/(topbar)/documentation/models/page.tsx diff --git a/frontend/app/(routes)/documentation/page.tsx b/frontend/app/(topbar)/documentation/page.tsx similarity index 100% rename from frontend/app/(routes)/documentation/page.tsx rename to frontend/app/(topbar)/documentation/page.tsx diff --git a/frontend/app/(routes)/maps/page.tsx b/frontend/app/(topbar)/maps/page.tsx similarity index 100% rename from frontend/app/(routes)/maps/page.tsx rename to frontend/app/(topbar)/maps/page.tsx diff --git a/frontend/app/(routes)/models/page.tsx b/frontend/app/(topbar)/models/page.tsx similarity index 100% rename from frontend/app/(routes)/models/page.tsx rename to frontend/app/(topbar)/models/page.tsx diff --git a/frontend/app/(routes)/price-prediction/page.tsx b/frontend/app/(topbar)/price-prediction/page.tsx similarity index 100% rename from frontend/app/(routes)/price-prediction/page.tsx rename to frontend/app/(topbar)/price-prediction/page.tsx diff --git a/frontend/app/(routes)/properties/[id]/page.tsx b/frontend/app/(topbar)/properties/[id]/page.tsx similarity index 100% rename from frontend/app/(routes)/properties/[id]/page.tsx rename to frontend/app/(topbar)/properties/[id]/page.tsx diff --git a/frontend/app/(routes)/properties/loading.tsx b/frontend/app/(topbar)/properties/loading.tsx similarity index 100% rename from frontend/app/(routes)/properties/loading.tsx rename to frontend/app/(topbar)/properties/loading.tsx diff --git a/frontend/app/(routes)/properties/page.tsx b/frontend/app/(topbar)/properties/page.tsx similarity index 100% rename from frontend/app/(routes)/properties/page.tsx rename to frontend/app/(topbar)/properties/page.tsx diff --git a/frontend/components/navigation/top-navigation.tsx b/frontend/components/navigation/top-navigation.tsx index 3b6548d..553d21c 100644 --- a/frontend/components/navigation/top-navigation.tsx +++ b/frontend/components/navigation/top-navigation.tsx @@ -16,6 +16,7 @@ import Link from "next/link"; import { Button } from "@/components/ui/button"; import { useTopNavigationStore } from "@/store/top-navgation-store"; import { useShallow } from "zustand/react/shallow"; +import { Input } from "../ui/input"; export function TopNavigation() { const { selectedModel, setSelectedModel, models } = useTopNavigationStore( @@ -35,7 +36,7 @@ export function TopNavigation() {
- Date: Tue, 8 Apr 2025 14:14:36 +0700 Subject: [PATCH 02/19] feat: add property detail page with comprehensive property information and analytics - Implemented PropertyDetailPage component to display detailed information about a selected property, including images, features, amenities, and market trends. - Added SimilarPropertyCard component for showcasing similar properties. - Created loading state for property detail page. - Developed PropertiesPage component with filtering options and property listings in grid and list views. - Introduced PropertyCard and PropertyCardList components for displaying property information in different layouts. - Integrated UI components such as buttons, cards, badges, and tabs for enhanced user experience. --- .../data-pipeline/create/page.tsx | 0 .../data-pipeline/page.tsx | 0 .../data-pipeline/property-listings/page.tsx | 0 .../documentation/loading.tsx | 0 .../documentation/models/page.tsx | 0 .../documentation/page.tsx | 0 frontend/app/(sidebar)/layout.tsx | 16 ++++++++++++++++ .../app/{(topbar) => (sidebar)}/maps/page.tsx | 0 .../app/{(topbar) => (sidebar)}/models/page.tsx | 0 .../price-prediction/page.tsx | 0 .../properties/[id]/page.tsx | 0 .../properties/loading.tsx | 0 .../{(topbar) => (sidebar)}/properties/page.tsx | 0 frontend/app/layout.tsx | 2 -- 14 files changed, 16 insertions(+), 2 deletions(-) rename frontend/app/{(topbar) => (sidebar)}/data-pipeline/create/page.tsx (100%) rename frontend/app/{(topbar) => (sidebar)}/data-pipeline/page.tsx (100%) rename frontend/app/{(topbar) => (sidebar)}/data-pipeline/property-listings/page.tsx (100%) rename frontend/app/{(topbar) => (sidebar)}/documentation/loading.tsx (100%) rename frontend/app/{(topbar) => (sidebar)}/documentation/models/page.tsx (100%) rename frontend/app/{(topbar) => (sidebar)}/documentation/page.tsx (100%) create mode 100644 frontend/app/(sidebar)/layout.tsx rename frontend/app/{(topbar) => (sidebar)}/maps/page.tsx (100%) rename frontend/app/{(topbar) => (sidebar)}/models/page.tsx (100%) rename frontend/app/{(topbar) => (sidebar)}/price-prediction/page.tsx (100%) rename frontend/app/{(topbar) => (sidebar)}/properties/[id]/page.tsx (100%) rename frontend/app/{(topbar) => (sidebar)}/properties/loading.tsx (100%) rename frontend/app/{(topbar) => (sidebar)}/properties/page.tsx (100%) diff --git a/frontend/app/(topbar)/data-pipeline/create/page.tsx b/frontend/app/(sidebar)/data-pipeline/create/page.tsx similarity index 100% rename from frontend/app/(topbar)/data-pipeline/create/page.tsx rename to frontend/app/(sidebar)/data-pipeline/create/page.tsx diff --git a/frontend/app/(topbar)/data-pipeline/page.tsx b/frontend/app/(sidebar)/data-pipeline/page.tsx similarity index 100% rename from frontend/app/(topbar)/data-pipeline/page.tsx rename to frontend/app/(sidebar)/data-pipeline/page.tsx diff --git a/frontend/app/(topbar)/data-pipeline/property-listings/page.tsx b/frontend/app/(sidebar)/data-pipeline/property-listings/page.tsx similarity index 100% rename from frontend/app/(topbar)/data-pipeline/property-listings/page.tsx rename to frontend/app/(sidebar)/data-pipeline/property-listings/page.tsx diff --git a/frontend/app/(topbar)/documentation/loading.tsx b/frontend/app/(sidebar)/documentation/loading.tsx similarity index 100% rename from frontend/app/(topbar)/documentation/loading.tsx rename to frontend/app/(sidebar)/documentation/loading.tsx diff --git a/frontend/app/(topbar)/documentation/models/page.tsx b/frontend/app/(sidebar)/documentation/models/page.tsx similarity index 100% rename from frontend/app/(topbar)/documentation/models/page.tsx rename to frontend/app/(sidebar)/documentation/models/page.tsx diff --git a/frontend/app/(topbar)/documentation/page.tsx b/frontend/app/(sidebar)/documentation/page.tsx similarity index 100% rename from frontend/app/(topbar)/documentation/page.tsx rename to frontend/app/(sidebar)/documentation/page.tsx diff --git a/frontend/app/(sidebar)/layout.tsx b/frontend/app/(sidebar)/layout.tsx new file mode 100644 index 0000000..39c730d --- /dev/null +++ b/frontend/app/(sidebar)/layout.tsx @@ -0,0 +1,16 @@ +"use client"; +import Sidebar from "@/components/sidebar"; + +export default function AppLayout({ + children, +}: Readonly<{ + children: React.ReactNode; +}>) { + return ( +
+ +
{children}
+
+ ); + +} \ No newline at end of file diff --git a/frontend/app/(topbar)/maps/page.tsx b/frontend/app/(sidebar)/maps/page.tsx similarity index 100% rename from frontend/app/(topbar)/maps/page.tsx rename to frontend/app/(sidebar)/maps/page.tsx diff --git a/frontend/app/(topbar)/models/page.tsx b/frontend/app/(sidebar)/models/page.tsx similarity index 100% rename from frontend/app/(topbar)/models/page.tsx rename to frontend/app/(sidebar)/models/page.tsx diff --git a/frontend/app/(topbar)/price-prediction/page.tsx b/frontend/app/(sidebar)/price-prediction/page.tsx similarity index 100% rename from frontend/app/(topbar)/price-prediction/page.tsx rename to frontend/app/(sidebar)/price-prediction/page.tsx diff --git a/frontend/app/(topbar)/properties/[id]/page.tsx b/frontend/app/(sidebar)/properties/[id]/page.tsx similarity index 100% rename from frontend/app/(topbar)/properties/[id]/page.tsx rename to frontend/app/(sidebar)/properties/[id]/page.tsx diff --git a/frontend/app/(topbar)/properties/loading.tsx b/frontend/app/(sidebar)/properties/loading.tsx similarity index 100% rename from frontend/app/(topbar)/properties/loading.tsx rename to frontend/app/(sidebar)/properties/loading.tsx diff --git a/frontend/app/(topbar)/properties/page.tsx b/frontend/app/(sidebar)/properties/page.tsx similarity index 100% rename from frontend/app/(topbar)/properties/page.tsx rename to frontend/app/(sidebar)/properties/page.tsx diff --git a/frontend/app/layout.tsx b/frontend/app/layout.tsx index 0d482f4..b494cda 100644 --- a/frontend/app/layout.tsx +++ b/frontend/app/layout.tsx @@ -3,7 +3,6 @@ import type { Metadata } from "next"; import { Poppins } from "next/font/google"; import "./globals.css"; import { ThemeProvider } from "@/components/theme-provider"; -import Sidebar from "@/components/sidebar"; const poppins = Poppins({ subsets: ["latin"], @@ -26,7 +25,6 @@ export default function RootLayout({
-
{children}
From 4e5fba24592280d636625b3a84931cd4bd0b4c82 Mon Sep 17 00:00:00 2001 From: Pattadon Date: Tue, 8 Apr 2025 14:26:33 +0700 Subject: [PATCH 03/19] feat: implement PipelineCard component and StatusBadge for data pipelines --- frontend/app/(sidebar)/data-pipeline/page.tsx | 118 +--------------- frontend/app/(sidebar)/maps/page.tsx | 2 +- frontend/components/pipeline/badge.tsx | 18 +++ frontend/components/pipeline/card.tsx | 132 ++++++++++++++++++ 4 files changed, 158 insertions(+), 112 deletions(-) create mode 100644 frontend/components/pipeline/badge.tsx create mode 100644 frontend/components/pipeline/card.tsx diff --git a/frontend/app/(sidebar)/data-pipeline/page.tsx b/frontend/app/(sidebar)/data-pipeline/page.tsx index 2acdf94..44d3a88 100644 --- a/frontend/app/(sidebar)/data-pipeline/page.tsx +++ b/frontend/app/(sidebar)/data-pipeline/page.tsx @@ -1,10 +1,9 @@ -import { Button } from "@/components/ui/button" -import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card" -import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" -import { Badge } from "@/components/ui/badge" -import { Clock, Database, Play, Plus, RefreshCw, Pause, AlertTriangle, Copy } from "lucide-react" -import Link from "next/link" -import PageHeader from "@/components/page-header" +import { Button } from "@/components/ui/button"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { Plus } from "lucide-react"; +import Link from "next/link"; +import PageHeader from "@/components/page-header"; +import { PipelineCard } from "@/components/pipeline/card"; export default function DataPipelinePage() { return ( @@ -135,108 +134,5 @@ export default function DataPipelinePage() {
- ) + ); } - -interface PipelineCardProps { - title: string - description: string - status: "active" | "paused" | "error" - lastRun: string - nextRun: string - sources: number - records: number - error?: string - aiPowered?: boolean -} - -function PipelineCard({ - title, - description, - status, - lastRun, - nextRun, - sources, - records, - error, - aiPowered, -}: PipelineCardProps) { - return ( - - -
- {title} - -
- {description} -
- -
-
- - Last run: - {lastRun} -
-
- - Next run: - {nextRun} -
-
- - Sources: - {sources} - - Records: - {records} -
- {error && ( -
- - {error} -
- )} -
-
- - - - -
- - {status === "active" ? ( - - ) : ( - - )} - -
-
-
- ) -} - -function StatusBadge({ status }: { status: "active" | "paused" | "error" }) { - if (status === "active") { - return ( - - Active - - ) - } else if (status === "paused") { - return Paused - } else { - return Error - } -} - diff --git a/frontend/app/(sidebar)/maps/page.tsx b/frontend/app/(sidebar)/maps/page.tsx index a1f6c89..65630b2 100644 --- a/frontend/app/(sidebar)/maps/page.tsx +++ b/frontend/app/(sidebar)/maps/page.tsx @@ -83,7 +83,7 @@ export default function MapsPage() { return (
{/* Map Container */} -
+
{/* Map Placeholder - In a real implementation, this would be a map component */}
Map View
diff --git a/frontend/components/pipeline/badge.tsx b/frontend/components/pipeline/badge.tsx new file mode 100644 index 0000000..afc435d --- /dev/null +++ b/frontend/components/pipeline/badge.tsx @@ -0,0 +1,18 @@ +import { Badge } from "@/components/ui/badge"; + +export function StatusBadge({ status }: { status: "active" | "paused" | "error" }) { + if (status === "active") { + return ( + + Active + + ); + } else if (status === "paused") { + return Paused; + } else { + return Error; + } +} diff --git a/frontend/components/pipeline/card.tsx b/frontend/components/pipeline/card.tsx new file mode 100644 index 0000000..8302bf9 --- /dev/null +++ b/frontend/components/pipeline/card.tsx @@ -0,0 +1,132 @@ +import { + Clock, + Database, + Play, + RefreshCw, + Pause, + AlertTriangle, + Copy, +} from "lucide-react"; +import { + Card, + CardContent, + CardDescription, + CardFooter, + CardHeader, + CardTitle, +} from "@/components/ui/card"; +import { StatusBadge } from "./badge"; +import Link from "next/link"; +import { Button } from "@/components/ui/button"; + + +interface PipelineCardProps { + title: string; + description: string; + status: "active" | "paused" | "error"; + lastRun: string; + nextRun: string; + sources: number; + records: number; + error?: string; + aiPowered?: boolean; +} + +export function PipelineCard({ + title, + description, + status, + lastRun, + nextRun, + sources, + records, + error, +}: PipelineCardProps) { + return ( + + +
+ {title} + +
+ {description} +
+ +
+
+ + Last run: + {lastRun} +
+
+ + Next run: + {nextRun} +
+
+ + Sources: + {sources} + + Records: + {records} +
+ {error && ( +
+ + {error} +
+ )} +
+
+ + + + +
+ + {status === "active" ? ( + + ) : ( + + )} + +
+
+
+ ); +} From 668847edc3aeea0f5cf29c4ee61c8ae136008a2b Mon Sep 17 00:00:00 2001 From: Pattadon Date: Tue, 8 Apr 2025 14:31:30 +0700 Subject: [PATCH 04/19] feat: add PipelineStatus component and integrate it into PipelineDetailsPage --- frontend/app/(sidebar)/data-pipeline/page.tsx | 1 + .../data-pipeline/property-listings/page.tsx | 36 +--------------- frontend/components/pipeline/status.tsx | 41 +++++++++++++++++++ 3 files changed, 44 insertions(+), 34 deletions(-) create mode 100644 frontend/components/pipeline/status.tsx diff --git a/frontend/app/(sidebar)/data-pipeline/page.tsx b/frontend/app/(sidebar)/data-pipeline/page.tsx index 44d3a88..7e5a135 100644 --- a/frontend/app/(sidebar)/data-pipeline/page.tsx +++ b/frontend/app/(sidebar)/data-pipeline/page.tsx @@ -98,6 +98,7 @@ export default function DataPipelinePage() { aiPowered={true} /> + {/* mock pipeline card with data */}
- - - Pipeline Status - - -
-
- Status: - - Active - -
-
- Last Run: - 2 hours ago -
-
- Next Run: - Tomorrow at 9:00 AM -
-
- Run Frequency: - Daily -
-
- Total Records: - 1,240 -
-
-
-
+ diff --git a/frontend/components/pipeline/status.tsx b/frontend/components/pipeline/status.tsx new file mode 100644 index 0000000..4266684 --- /dev/null +++ b/frontend/components/pipeline/status.tsx @@ -0,0 +1,41 @@ +import { Badge } from "../ui/badge"; +import { Card, CardHeader, CardTitle, CardContent } from "../ui/card"; + +export function PipelineStatus() { + return ( + + + Pipeline Status + + +
+
+ Status: + + Active + +
+
+ Last Run: + 2 hours ago +
+
+ Next Run: + Tomorrow at 9:00 AM +
+
+ Run Frequency: + Daily +
+
+ Total Records: + 1,240 +
+
+
+
+ ); +} \ No newline at end of file From 7783d00f5680c1fdb33b5e0d72dbec6e4a1f43c6 Mon Sep 17 00:00:00 2001 From: Pattadon Date: Tue, 8 Apr 2025 14:51:37 +0700 Subject: [PATCH 05/19] feat: add PipelineDataSource, PipelineExportData, PipelineDataSchema, and PipelineDataPreview components to enhance data pipeline details page --- .../data-pipeline/property-listings/page.tsx | 360 +----------------- frontend/components/pipeline/data-preview.tsx | 70 ++++ frontend/components/pipeline/data-schema.tsx | 246 ++++++++++++ frontend/components/pipeline/data-source.tsx | 48 +++ frontend/components/pipeline/export-data.tsx | 119 ++++++ 5 files changed, 495 insertions(+), 348 deletions(-) create mode 100644 frontend/components/pipeline/data-preview.tsx create mode 100644 frontend/components/pipeline/data-schema.tsx create mode 100644 frontend/components/pipeline/data-source.tsx create mode 100644 frontend/components/pipeline/export-data.tsx diff --git a/frontend/app/(sidebar)/data-pipeline/property-listings/page.tsx b/frontend/app/(sidebar)/data-pipeline/property-listings/page.tsx index 93d4f06..91ad715 100644 --- a/frontend/app/(sidebar)/data-pipeline/property-listings/page.tsx +++ b/frontend/app/(sidebar)/data-pipeline/property-listings/page.tsx @@ -2,13 +2,17 @@ import { Button } from "@/components/ui/button" import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" import { Badge } from "@/components/ui/badge" -import { ArrowLeft, Download, Edit, Play, Trash, Copy, Check, Plus } from "lucide-react" +import { ArrowLeft, Download, Edit, Play, Trash, Copy, Check } from "lucide-react" import Link from "next/link" import PageHeader from "@/components/page-header" -import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion" + import { Input } from "@/components/ui/input" import { Label } from "@/components/ui/label" import { PipelineStatus } from "@/components/pipeline/status" +import { PipelineDataSource } from "@/components/pipeline/data-source" +import { PipelineExportData } from "@/components/pipeline/export-data" +import { PipelineDataSchema } from "@/components/pipeline/data-schema" +import { PipelineDataPreview } from "@/components/pipeline/data-preview" export default function PipelineDetailsPage() { return ( @@ -51,133 +55,8 @@ export default function PipelineDetailsPage() {
- - - - Data Sources - - -
-
-
- example-realty.com - Website -
-

Last updated: 2 hours ago

-

540 records

-
- -
-
- property-listings.com - Website -
-

Last updated: 2 hours ago

-

420 records

-
- -
-
- real-estate-api.com - API -
-

Last updated: 2 hours ago

-

280 records

-
-
-
-
- - - - Export Options - - -
- - -
- -
- - Export as JSON -
-
- -
-
- - -
- -
-
-
-
- - -
- -
- - Export as CSV -
-
- -
-
- - -
- -
-
-
-
- - -
- -
- - Export as SQLite -
-
- - - -
-
- - -
- -
- - Export as YAML -
-
- - - -
-
-
-
-
-
+ +
@@ -191,226 +70,11 @@ export default function PipelineDetailsPage() { - - -
-
- Data Schema & Field Management - Customize fields detected from your data sources -
-
-
- -
-
-

Detected Fields

- -
+ + -
-
-
- -
-
- - Auto-detected -
-

Property title or name

-
- -
- -
- -
-
- - Auto-detected -
-

Property price

-
- -
- -
- -
-
- - Auto-detected -
-

Property location

-
- -
- -
- -
-
- - Auto-detected -
-

Number of bedrooms

-
- -
- -
- -
-
- - Auto-detected -
-

Number of bathrooms

-
- -
- -
- -
- -
- -
-
-
- -
- - - - Create calculated fields - Use formulas to generate new fields from existing data - - -
-
-
- - Derived -
-
- Formula: - price / squareFeet -
-
- - -
-
-
-
- -
- - -
-
-
-
-
- - - - - Data Preview - Sample of the collected data - - -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IDTitlePriceBedroomsBathroomsLocationSq. Ft.
P001Modern Apartment$350,00022Downtown1,200
P002Luxury Villa$1,250,00054Suburbs3,500
P003Cozy Studio$180,00011City Center650
-
-
-
+ + diff --git a/frontend/components/pipeline/data-preview.tsx b/frontend/components/pipeline/data-preview.tsx new file mode 100644 index 0000000..7d526a8 --- /dev/null +++ b/frontend/components/pipeline/data-preview.tsx @@ -0,0 +1,70 @@ +import { Card, CardHeader, CardTitle, CardDescription, CardContent } from "../ui/card"; + +export function PipelineDataPreview() { + return ( + + + Data Preview + Sample of the collected data + + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
ID + Title + + Price + + Bedrooms + + Bathrooms + + Location + + Sq. Ft. +
P001Modern Apartment$350,00022Downtown1,200
P002Luxury Villa$1,250,00054Suburbs3,500
P003Cozy Studio$180,00011City Center650
+
+
+
+ ); +} \ No newline at end of file diff --git a/frontend/components/pipeline/data-schema.tsx b/frontend/components/pipeline/data-schema.tsx new file mode 100644 index 0000000..ea57a40 --- /dev/null +++ b/frontend/components/pipeline/data-schema.tsx @@ -0,0 +1,246 @@ +import { Plus } from "lucide-react"; +import { Button } from "../ui/button"; +import { Label } from "../ui/label"; +import { + Card, + CardHeader, + CardTitle, + CardDescription, + CardContent, +} from "../ui/card"; +import { Input } from "../ui/input"; +import { Badge } from "../ui/badge"; + +export function PipelineDataSchema() { + return ( + + +
+
+ Data Schema & Field Management + + Customize fields detected from your data sources + +
+
+
+ +
+
+

Detected Fields

+ +
+ +
+
+
+ +
+
+ + + Auto-detected + +
+

+ Property title or name +

+
+ +
+ +
+ +
+
+ + + Auto-detected + +
+

+ Property price +

+
+ +
+ +
+ +
+
+ + + Auto-detected + +
+

+ Property location +

+
+ +
+ +
+ +
+
+ + + Auto-detected + +
+

+ Number of bedrooms +

+
+ +
+ +
+ +
+
+ + + Auto-detected + +
+

+ Number of bathrooms +

+
+ +
+ +
+ +
+ +
+ +
+
+
+ +
+ + + + + Create calculated fields + + + Use formulas to generate new fields from existing data + + + +
+
+
+ + Derived +
+
+ + Formula: + + + price / squareFeet + +
+
+ + +
+
+
+
+ +
+ + +
+
+
+
+ ); +} diff --git a/frontend/components/pipeline/data-source.tsx b/frontend/components/pipeline/data-source.tsx new file mode 100644 index 0000000..7087059 --- /dev/null +++ b/frontend/components/pipeline/data-source.tsx @@ -0,0 +1,48 @@ +import { Badge } from "../ui/badge"; +import { Card, CardHeader, CardTitle, CardContent } from "../ui/card"; + +export function PipelineDataSource(){ + return ( + + + Data Sources + + +
+
+
+ example-realty.com + Website +
+

+ Last updated: 2 hours ago +

+

540 records

+
+ +
+
+ property-listings.com + Website +
+

+ Last updated: 2 hours ago +

+

420 records

+
+ +
+
+ real-estate-api.com + API +
+

+ Last updated: 2 hours ago +

+

280 records

+
+
+
+
+ ); +} \ No newline at end of file diff --git a/frontend/components/pipeline/export-data.tsx b/frontend/components/pipeline/export-data.tsx new file mode 100644 index 0000000..b22cb69 --- /dev/null +++ b/frontend/components/pipeline/export-data.tsx @@ -0,0 +1,119 @@ +import { + Accordion, + AccordionContent, + AccordionItem, + AccordionTrigger, +} from "@/components/ui/accordion"; +import { Download } from "lucide-react"; +import { Button } from "../ui/button"; +import { Card, CardHeader, CardTitle, CardContent } from "../ui/card"; + +export function PipelineExportData() { + return ( + + + Export Options + + +
+ + +
+ +
+ + Export as JSON +
+
+ +
+
+ + +
+ +
+
+
+
+ + +
+ +
+ + Export as CSV +
+
+ +
+
+ + +
+ +
+
+
+
+ + +
+ +
+ + Export as SQLite +
+
+ + + +
+
+ + +
+ +
+ + Export as YAML +
+
+ + + +
+
+
+
+
+
+ ); +} From 173defcb44609907aea108ab8823947ba695c585 Mon Sep 17 00:00:00 2001 From: Pattadon Date: Tue, 8 Apr 2025 15:00:54 +0700 Subject: [PATCH 06/19] feat: enhance PipelineDetailsPage with new components for output configuration, run history, and settings --- .../data-pipeline/property-listings/page.tsx | 288 +++--------------- frontend/components/pipeline/badge.tsx | 6 +- frontend/components/pipeline/card.tsx | 1 - frontend/components/pipeline/data-preview.tsx | 10 +- frontend/components/pipeline/data-source.tsx | 86 +++--- .../components/pipeline/output-config.tsx | 96 ++++++ frontend/components/pipeline/run-history.tsx | 109 +++++++ frontend/components/pipeline/settings.tsx | 100 ++++++ frontend/components/pipeline/status.tsx | 72 ++--- 9 files changed, 434 insertions(+), 334 deletions(-) create mode 100644 frontend/components/pipeline/output-config.tsx create mode 100644 frontend/components/pipeline/run-history.tsx create mode 100644 frontend/components/pipeline/settings.tsx diff --git a/frontend/app/(sidebar)/data-pipeline/property-listings/page.tsx b/frontend/app/(sidebar)/data-pipeline/property-listings/page.tsx index 91ad715..58ac495 100644 --- a/frontend/app/(sidebar)/data-pipeline/property-listings/page.tsx +++ b/frontend/app/(sidebar)/data-pipeline/property-listings/page.tsx @@ -1,18 +1,16 @@ -import { Button } from "@/components/ui/button" -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" -import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs" -import { Badge } from "@/components/ui/badge" -import { ArrowLeft, Download, Edit, Play, Trash, Copy, Check } from "lucide-react" -import Link from "next/link" -import PageHeader from "@/components/page-header" - -import { Input } from "@/components/ui/input" -import { Label } from "@/components/ui/label" -import { PipelineStatus } from "@/components/pipeline/status" -import { PipelineDataSource } from "@/components/pipeline/data-source" -import { PipelineExportData } from "@/components/pipeline/export-data" -import { PipelineDataSchema } from "@/components/pipeline/data-schema" -import { PipelineDataPreview } from "@/components/pipeline/data-preview" +import { Button } from "@/components/ui/button"; +import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; +import { ArrowLeft, Edit, Play, Trash, Copy } from "lucide-react"; +import Link from "next/link"; +import PageHeader from "@/components/page-header"; +import { PipelineStatus } from "@/components/pipeline/status"; +import { PipelineDataSource } from "@/components/pipeline/data-source"; +import { PipelineExportData } from "@/components/pipeline/export-data"; +import { PipelineDataSchema } from "@/components/pipeline/data-schema"; +import { PipelineDataPreview } from "@/components/pipeline/data-preview"; +import { PipelineOutputConfig } from "@/components/pipeline/output-config"; +import { PipelineRunHistory } from "@/components/pipeline/run-history"; +import { PipelineSettings } from "@/components/pipeline/settings"; export default function PipelineDetailsPage() { return ( @@ -22,7 +20,10 @@ export default function PipelineDetailsPage() { breadcrumb={[ { title: "Home", href: "/" }, { title: "Data Pipeline", href: "/data-pipeline" }, - { title: "Property Listings", href: "/data-pipeline/property-listings" }, + { + title: "Property Listings", + href: "/data-pipeline/property-listings", + }, ]} /> @@ -35,15 +36,24 @@ export default function PipelineDetailsPage() {
- - - @@ -70,250 +80,26 @@ export default function PipelineDetailsPage() { - - + + - - + + - - - Output Configuration - Configure how your data will be structured and exported - - -
-
- -
-
-
- JSON - -
-

Structured data format

-
-
- CSV -

Spreadsheet compatible

-
-
- SQLite -

Portable database

-
-
- YAML -

Human-readable format

-
-
-
- -
-
- - Sample Data -
-
-
-                        {`{
-  "properties": [
-    {
-      "id": "P001",
-      "title": "Modern Apartment",
-      "price": 350000,
-      "bedrooms": 2,
-      "location": "Downtown"
-    },
-    {
-      "id": "P002",
-      "title": "Luxury Villa",
-      "price": 1250000,
-      "bedrooms": 5,
-      "location": "Suburbs"
-    }
-  ]
-}`}
-                      
-
-
- -
- -
-
-
-
+
- - - Run History - History of pipeline executions - - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Run IDDateStatusDurationRecordsActions
RUN-123Today, 10:30 AM - - Success - - 2m 15s1,240 - -
RUN-122Yesterday, 10:30 AM - - Success - - 2m 10s1,235 - -
RUN-1212 days ago, 10:30 AM - - Success - - 2m 05s1,228 - -
-
-
-
-
+
- - - Pipeline Settings - Configure pipeline behavior - - -
-
-

Scheduling

-
-
- - -
- -
- - -
-
-
- -
-

Data Collection

-
-
- - -
- -
- - -
-
-
- -
-

Notifications

-
-
- - -
-
- - -
-
-
- -
- -
-
-
-
+
- ) + ); } - diff --git a/frontend/components/pipeline/badge.tsx b/frontend/components/pipeline/badge.tsx index afc435d..50b1442 100644 --- a/frontend/components/pipeline/badge.tsx +++ b/frontend/components/pipeline/badge.tsx @@ -1,6 +1,10 @@ import { Badge } from "@/components/ui/badge"; -export function StatusBadge({ status }: { status: "active" | "paused" | "error" }) { +export function StatusBadge({ + status, +}: { + status: "active" | "paused" | "error"; +}) { if (status === "active") { return (
); -} \ No newline at end of file +} diff --git a/frontend/components/pipeline/data-source.tsx b/frontend/components/pipeline/data-source.tsx index 7087059..1ad4316 100644 --- a/frontend/components/pipeline/data-source.tsx +++ b/frontend/components/pipeline/data-source.tsx @@ -1,48 +1,48 @@ import { Badge } from "../ui/badge"; import { Card, CardHeader, CardTitle, CardContent } from "../ui/card"; -export function PipelineDataSource(){ - return ( - - - Data Sources - - -
-
-
- example-realty.com - Website -
-

- Last updated: 2 hours ago -

-

540 records

-
- -
-
- property-listings.com - Website -
-

- Last updated: 2 hours ago -

-

420 records

-
- -
-
- real-estate-api.com - API -
-

- Last updated: 2 hours ago -

-

280 records

+export function PipelineDataSource() { + return ( + + + Data Sources + + +
+
+
+ example-realty.com + Website
+

+ Last updated: 2 hours ago +

+

540 records

- - - ); -} \ No newline at end of file + +
+
+ property-listings.com + Website +
+

+ Last updated: 2 hours ago +

+

420 records

+
+ +
+
+ real-estate-api.com + API +
+

+ Last updated: 2 hours ago +

+

280 records

+
+
+
+
+ ); +} diff --git a/frontend/components/pipeline/output-config.tsx b/frontend/components/pipeline/output-config.tsx new file mode 100644 index 0000000..0a136c4 --- /dev/null +++ b/frontend/components/pipeline/output-config.tsx @@ -0,0 +1,96 @@ +import { Check, Download } from "lucide-react"; +import { Badge } from "../ui/badge"; +import { Button } from "../ui/button"; +import { Label } from "../ui/label"; +import { + Card, + CardHeader, + CardTitle, + CardDescription, + CardContent, +} from "../ui/card"; + +export function PipelineOutputConfig() { + return ( + + + Output Configuration + + Configure how your data will be structured and exported + + + +
+
+ +
+
+
+ JSON + +
+

+ Structured data format +

+
+
+ CSV +

+ Spreadsheet compatible +

+
+
+ SQLite +

+ Portable database +

+
+
+ YAML +

+ Human-readable format +

+
+
+
+ +
+
+ + Sample Data +
+
+
+                {`{
+  "properties": [
+    {
+      "id": "P001",
+      "title": "Modern Apartment",
+      "price": 350000,
+      "bedrooms": 2,
+      "location": "Downtown"
+    },
+    {
+      "id": "P002",
+      "title": "Luxury Villa",
+      "price": 1250000,
+      "bedrooms": 5,
+      "location": "Suburbs"
+    }
+  ]
+}`}
+              
+
+
+ +
+ +
+
+
+
+ ); +} diff --git a/frontend/components/pipeline/run-history.tsx b/frontend/components/pipeline/run-history.tsx new file mode 100644 index 0000000..7807dcf --- /dev/null +++ b/frontend/components/pipeline/run-history.tsx @@ -0,0 +1,109 @@ +import { Badge } from "../ui/badge"; +import { Button } from "../ui/button"; +import { + Card, + CardHeader, + CardTitle, + CardDescription, + CardContent, +} from "../ui/card"; + +export function PipelineRunHistory() { + return ( + + + Run History + History of pipeline executions + + +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ Run ID + + Date + + Status + + Duration + + Records + + Actions +
RUN-123Today, 10:30 AM + + Success + + 2m 15s1,240 + +
RUN-122Yesterday, 10:30 AM + + Success + + 2m 10s1,235 + +
RUN-1212 days ago, 10:30 AM + + Success + + 2m 05s1,228 + +
+
+
+
+
+ ); +} diff --git a/frontend/components/pipeline/settings.tsx b/frontend/components/pipeline/settings.tsx new file mode 100644 index 0000000..fb76b03 --- /dev/null +++ b/frontend/components/pipeline/settings.tsx @@ -0,0 +1,100 @@ +import { Button } from "../ui/button"; +import { Label } from "../ui/label"; +import { + Card, + CardHeader, + CardTitle, + CardDescription, + CardContent, +} from "../ui/card"; +import { Input } from "../ui/input"; + +export function PipelineSettings() { + return ( + + + Pipeline Settings + Configure pipeline behavior + + +
+
+

Scheduling

+
+
+ + +
+ +
+ + +
+
+
+ +
+

Data Collection

+
+
+ + +
+ +
+ + +
+
+
+ +
+

Notifications

+
+
+ + +
+
+ + +
+
+
+ +
+ +
+
+
+
+ ); +} diff --git a/frontend/components/pipeline/status.tsx b/frontend/components/pipeline/status.tsx index 4266684..63f9e7e 100644 --- a/frontend/components/pipeline/status.tsx +++ b/frontend/components/pipeline/status.tsx @@ -2,40 +2,40 @@ import { Badge } from "../ui/badge"; import { Card, CardHeader, CardTitle, CardContent } from "../ui/card"; export function PipelineStatus() { - return ( - - - Pipeline Status - - -
-
- Status: - - Active - -
-
- Last Run: - 2 hours ago -
-
- Next Run: - Tomorrow at 9:00 AM -
-
- Run Frequency: - Daily -
-
- Total Records: - 1,240 -
+ return ( + + + Pipeline Status + + +
+
+ Status: + + Active +
- - - ); -} \ No newline at end of file +
+ Last Run: + 2 hours ago +
+
+ Next Run: + Tomorrow at 9:00 AM +
+
+ Run Frequency: + Daily +
+
+ Total Records: + 1,240 +
+
+
+
+ ); +} From 6443f5e8937ddf684a3a69ef2a4a19fcaea20e1d Mon Sep 17 00:00:00 2001 From: Pattadon Date: Tue, 8 Apr 2025 15:42:00 +0700 Subject: [PATCH 07/19] feat: add PipelineDetails and PipelineAiAssistant components to CreatePipelinePage for enhanced data pipeline configuration --- .../(sidebar)/data-pipeline/create/page.tsx | 261 +++++++++--------- frontend/components/pipeline/ai-assistant.tsx | 76 +++++ frontend/components/pipeline/details.tsx | 45 +++ 3 files changed, 258 insertions(+), 124 deletions(-) create mode 100644 frontend/components/pipeline/ai-assistant.tsx create mode 100644 frontend/components/pipeline/details.tsx diff --git a/frontend/app/(sidebar)/data-pipeline/create/page.tsx b/frontend/app/(sidebar)/data-pipeline/create/page.tsx index a382632..a920c96 100644 --- a/frontend/app/(sidebar)/data-pipeline/create/page.tsx +++ b/frontend/app/(sidebar)/data-pipeline/create/page.tsx @@ -1,14 +1,33 @@ -import { Button } from "@/components/ui/button" -import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card" -import { Input } from "@/components/ui/input" -import { Label } from "@/components/ui/label" -import { Textarea } from "@/components/ui/textarea" -import { ArrowLeft, Globe, FileUp, DatabaseIcon, Plus, Trash2, BrainCircuit } from "lucide-react" -import Link from "next/link" -import PageHeader from "@/components/page-header" -import { Badge } from "@/components/ui/badge" -import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion" -import { Switch } from "@/components/ui/switch" +import { Button } from "@/components/ui/button"; +import { + Card, + CardContent, + CardDescription, + CardHeader, + CardTitle, +} from "@/components/ui/card"; +import { Input } from "@/components/ui/input"; +import { Label } from "@/components/ui/label"; +import { Textarea } from "@/components/ui/textarea"; +import { + ArrowLeft, + Globe, + FileUp, + DatabaseIcon, + Plus, + Trash2, +} from "lucide-react"; +import Link from "next/link"; +import PageHeader from "@/components/page-header"; +import { Badge } from "@/components/ui/badge"; +import { + Accordion, + AccordionContent, + AccordionItem, + AccordionTrigger, +} from "@/components/ui/accordion"; +import { PipelineDetails } from "@/components/pipeline/details"; +import { PipelineAiAssistant } from "@/components/pipeline/ai-assistant"; export default function CreatePipelinePage() { return ( @@ -33,102 +52,29 @@ export default function CreatePipelinePage() {
- - - Pipeline Details - Basic information about your data pipeline - - -
-
- - -
- -
- -