ui: modify new crop dialog

This commit is contained in:
Sosokker 2025-02-14 04:16:09 +07:00
parent 215c178249
commit 20c1efa325
4 changed files with 182 additions and 38 deletions

View File

@ -4,9 +4,10 @@ import { Crop } from "@/types";
interface CropCardProps {
crop: Crop;
onClick?: () => void;
}
export function CropCard({ crop }: CropCardProps) {
export function CropCard({ crop, onClick }: CropCardProps) {
const statusColors = {
growing: "text-green-500",
harvested: "text-yellow-500",
@ -14,8 +15,10 @@ export function CropCard({ crop }: CropCardProps) {
};
return (
<Card className="w-full bg-muted/50 hover:bg-muted/80 transition-all cursor-pointer group hover:shadow-lg">
<CardHeader className="p-4 pb-2">
<Card
onClick={onClick}
className="w-full bg-muted/50 hover:bg-muted/80 transition-all cursor-pointer group hover:shadow-lg">
<CardHeader className="p-4 pb-0">
<div className="flex items-center justify-between">
<div className="h-8 w-8 rounded-full bg-primary/10 flex items-center justify-center">
<Sprout className="h-4 w-4 text-primary" />
@ -24,10 +27,10 @@ export function CropCard({ crop }: CropCardProps) {
</div>
</CardHeader>
<CardContent className="p-4">
<div className="space-y-2">
<h3 className="text-lg font-medium truncate">{crop.name}</h3>
<div className="space-y-4">
<h3 className="text-xl font-medium truncate">{crop.name}</h3>
<div className="flex items-center gap-1 text-sm text-muted-foreground">
<Calendar className="h-3 w-3" />
<Calendar className="h-4 w-4" />
<p>Planted: {crop.plantedDate.toLocaleDateString()}</p>
</div>
</div>

View File

@ -0,0 +1,131 @@
"use client";
import { useState } from "react";
import { Dialog, DialogContent } from "@/components/ui/dialog";
import { Button } from "@/components/ui/button";
import { Card } from "@/components/ui/card";
import { Check, MapPin } from "lucide-react";
import { cn } from "@/lib/utils";
import type { Crop } from "@/types";
interface Plant {
id: string;
name: string;
image: string;
growthTime: string;
}
const plants: Plant[] = [
{
id: "durian",
name: "Durian",
image: "/placeholder.svg?height=80&width=80",
growthTime: "4-5 months",
},
{
id: "mango",
name: "Mango",
image: "/placeholder.svg?height=80&width=80",
growthTime: "3-4 months",
},
{
id: "coconut",
name: "Coconut",
image: "/placeholder.svg?height=80&width=80",
growthTime: "5-6 months",
},
];
interface CropDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
onSubmit: (data: Partial<Crop>) => Promise<void>;
}
export function CropDialog({ open, onOpenChange, onSubmit }: CropDialogProps) {
const [selectedPlant, setSelectedPlant] = useState<string | null>(null);
const [location, setLocation] = useState({ lat: 13.7563, lng: 100.5018 }); // Bangkok coordinates
const handleSubmit = async () => {
if (!selectedPlant) return;
await onSubmit({
name: plants.find((p) => p.id === selectedPlant)?.name || "",
plantedDate: new Date(),
status: "planned",
});
setSelectedPlant(null);
onOpenChange(false);
};
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:max-w-[900px] p-0">
<div className="grid md:grid-cols-2 h-[600px]">
{/* Left side - Plant Selection */}
<div className="p-6 overflow-y-auto border-r">
<h2 className="text-lg font-semibold mb-4">Select Plant to Grow</h2>
<div className="space-y-4">
{plants.map((plant) => (
<Card
key={plant.id}
className={cn(
"p-4 cursor-pointer hover:bg-muted/50 transition-colors",
selectedPlant === plant.id && "border-primary bg-primary/5"
)}
onClick={() => setSelectedPlant(plant.id)}>
<div className="flex items-center gap-4">
<img
src={plant.image || "/placeholder.svg"}
alt={plant.name}
className="w-20 h-20 rounded-lg object-cover"
/>
<div className="flex-1">
<div className="flex items-center justify-between">
<h3 className="font-medium">{plant.name}</h3>
{selectedPlant === plant.id && <Check className="h-4 w-4 text-primary" />}
</div>
<p className="text-sm text-muted-foreground">Growth time: {plant.growthTime}</p>
</div>
</div>
</Card>
))}
</div>
</div>
{/* Right side - Map */}
<div className="relative">
<div className="absolute inset-0 bg-muted/10">
{/* Placeholder map - Replace with your map component */}
<div className="h-full w-full bg-muted/20 flex items-center justify-center">
<div className="text-center space-y-2">
<MapPin className="h-8 w-8 mx-auto text-muted-foreground" />
<p className="text-sm text-muted-foreground">
Map placeholder
<br />
Lat: {location.lat.toFixed(4)}
<br />
Lng: {location.lng.toFixed(4)}
</p>
</div>
</div>
</div>
</div>
{/* Footer */}
<div className="absolute bottom-0 left-0 right-0 p-4 bg-background border-t">
<div className="flex justify-end gap-2">
<Button variant="outline" onClick={() => onOpenChange(false)}>
Cancel
</Button>
<Button onClick={handleSubmit} disabled={!selectedPlant}>
Plant Crop
</Button>
</div>
</div>
</div>
</DialogContent>
</Dialog>
);
}

View File

@ -6,29 +6,28 @@ import { ArrowLeft, MapPin, Plus, Sprout } from "lucide-react";
import { Card, CardContent, CardHeader } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Separator } from "@/components/ui/separator";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "@/components/ui/dialog";
import { AddCropForm } from "./add-crop-form";
import { CropDialog } from "./crop-dialog";
import { CropCard } from "./crop-card";
import { Farm, Crop } from "@/types";
import React from "react";
const crops: Crop[] = [
{
id: "crop1",
id: "1",
farmId: "1",
name: "Monthong Durian",
plantedDate: new Date("2023-03-15"),
status: "growing",
},
{
id: "crop2",
id: "2",
farmId: "1",
name: "Chanee Durian",
plantedDate: new Date("2023-02-20"),
status: "planned",
},
{
id: "crop3",
id: "3",
farmId: "2",
name: "Kradum Durian",
plantedDate: new Date("2022-11-05"),
@ -76,6 +75,7 @@ export default function FarmDetailPage({ params }: { params: Promise<{ farmId: s
status: data.status!,
};
setCrops((prevCrops) => [...prevCrops, newCrop]);
// When the crop gets added, close the dialog
setIsDialogOpen(false);
};
@ -121,33 +121,34 @@ export default function FarmDetailPage({ params }: { params: Promise<{ farmId: s
<h2 className="text-xl font-bold mb-4">Crops</h2>
<Separator className="my-4" />
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
<Dialog open={isDialogOpen} onOpenChange={setIsDialogOpen}>
<Card
className="w-full bg-muted/50 hover:bg-muted/80 transition-all cursor-pointer group hover:shadow-lg"
onClick={() => setIsDialogOpen(true)}>
<CardContent className="p-6">
<div className="flex flex-col gap-6">
<div className="h-8 w-8 rounded-full bg-primary/10 flex items-center justify-center group-hover:bg-primary/20 transition-colors">
<Plus className="h-5 w-5 text-primary" />
</div>
<div className="space-y-1">
<h3 className="text-xl font-medium">Add Crop</h3>
<p className="text-sm text-muted-foreground">Plant a new crop</p>
</div>
{/* Clickable "Add Crop" Card */}
<Card
className="w-full bg-muted/50 hover:bg-muted/80 transition-all cursor-pointer group hover:shadow-lg"
onClick={() => setIsDialogOpen(true)}>
<CardContent className="p-6">
<div className="flex flex-col gap-6">
<div className="h-8 w-8 rounded-full bg-primary/10 flex items-center justify-center group-hover:bg-primary/20 transition-colors">
<Plus className="h-5 w-5 text-primary" />
</div>
</CardContent>
</Card>
<DialogContent className="sm:max-w-[425px]">
<DialogHeader>
<DialogTitle>Add New Crop</DialogTitle>
<DialogDescription>Fill out the form to add a new crop to your farm.</DialogDescription>
</DialogHeader>
<AddCropForm onSubmit={handleAddCrop} onCancel={() => setIsDialogOpen(false)} />
</DialogContent>
</Dialog>
<div className="space-y-1">
<h3 className="text-xl font-medium">Add Crop</h3>
<p className="text-sm text-muted-foreground">Plant a new crop</p>
</div>
</div>
</CardContent>
</Card>
{/* New Crop Dialog */}
<CropDialog open={isDialogOpen} onOpenChange={setIsDialogOpen} onSubmit={handleAddCrop} />
{crops.map((crop) => (
<CropCard key={crop.id} crop={crop} />
<CropCard
key={crop.id}
crop={crop}
onClick={() => {
router.push(`/farms/${crop.farmId}/crops/${crop.id}`);
}}
/>
))}
</div>
</div>

View File

@ -4,12 +4,14 @@ import { useState } from "react";
import { Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription } from "@/components/ui/dialog";
import { Separator } from "@/components/ui/separator";
import { Input } from "@/components/ui/input";
import { Search } from "lucide-react";
import { Link, Search } from "lucide-react";
import { FarmCard } from "./farm-card";
import { AddFarmForm } from "./add-farm-form";
import { useRouter } from "next/navigation";
import type { Farm } from "@/types";
export default function FarmSetupPage() {
const router = useRouter();
const [isDialogOpen, setIsDialogOpen] = useState(false);
const [searchQuery, setSearchQuery] = useState("");
const [farms, setFarms] = useState<Farm[]>([
@ -17,7 +19,7 @@ export default function FarmSetupPage() {
id: "1",
name: "Green Valley Farm",
location: "Bangkok",
type: "durian",
type: "Durian",
createdAt: new Date(),
},
]);
@ -70,7 +72,14 @@ export default function FarmSetupPage() {
</Dialog>
{filteredFarms.map((farm) => (
<FarmCard key={farm.id} variant="farm" farm={farm} />
<FarmCard
key={farm.id}
variant="farm"
farm={farm}
onClick={() => {
router.push(`/farms/${farm.id}`);
}}
/>
))}
</div>
</div>