Add UI components for labels, inputs, tabs, and report views; update package dependencies
This commit is contained in:
parent
6fd0d7bdba
commit
a02d1921ac
ventaboletos
|
@ -9,8 +9,10 @@
|
|||
"version": "0.1.0",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-dialog": "^1.1.6",
|
||||
"@radix-ui/react-label": "^2.1.2",
|
||||
"@radix-ui/react-select": "^2.1.6",
|
||||
"@radix-ui/react-slot": "^1.1.2",
|
||||
"@radix-ui/react-tabs": "^1.1.3",
|
||||
"@supabase/ssr": "^0.5.2",
|
||||
"@supabase/supabase-js": "^2.49.1",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
|
@ -1065,6 +1067,28 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-label": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-label/-/react-label-2.1.2.tgz",
|
||||
"integrity": "sha512-zo1uGMTaNlHehDyFQcDZXRJhUPDuukcnHz0/jnrup0JA6qL+AFpAnty+7VKa9esuU5xTblAZzTGYJKSKaBxBhw==",
|
||||
"dependencies": {
|
||||
"@radix-ui/react-primitive": "2.0.2"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-popper": {
|
||||
"version": "1.2.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-popper/-/react-popper-1.2.2.tgz",
|
||||
|
@ -1164,6 +1188,36 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-roving-focus": {
|
||||
"version": "1.1.2",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-roving-focus/-/react-roving-focus-1.1.2.tgz",
|
||||
"integrity": "sha512-zgMQWkNO169GtGqRvYrzb0Zf8NhMHS2DuEB/TiEmVnpr5OqPU3i8lfbxaAmC2J/KYuIQxyoQQ6DxepyXp61/xw==",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.1",
|
||||
"@radix-ui/react-collection": "1.1.2",
|
||||
"@radix-ui/react-compose-refs": "1.1.1",
|
||||
"@radix-ui/react-context": "1.1.1",
|
||||
"@radix-ui/react-direction": "1.1.0",
|
||||
"@radix-ui/react-id": "1.1.0",
|
||||
"@radix-ui/react-primitive": "2.0.2",
|
||||
"@radix-ui/react-use-callback-ref": "1.1.0",
|
||||
"@radix-ui/react-use-controllable-state": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-select": {
|
||||
"version": "2.1.6",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-select/-/react-select-2.1.6.tgz",
|
||||
|
@ -1223,6 +1277,35 @@
|
|||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-tabs": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-tabs/-/react-tabs-1.1.3.tgz",
|
||||
"integrity": "sha512-9mFyI30cuRDImbmFF6O2KUJdgEOsGh9Vmx9x/Dh9tOhL7BngmQPQfwW4aejKm5OHpfWIdmeV6ySyuxoOGjtNng==",
|
||||
"dependencies": {
|
||||
"@radix-ui/primitive": "1.1.1",
|
||||
"@radix-ui/react-context": "1.1.1",
|
||||
"@radix-ui/react-direction": "1.1.0",
|
||||
"@radix-ui/react-id": "1.1.0",
|
||||
"@radix-ui/react-presence": "1.1.2",
|
||||
"@radix-ui/react-primitive": "2.0.2",
|
||||
"@radix-ui/react-roving-focus": "1.1.2",
|
||||
"@radix-ui/react-use-controllable-state": "1.1.0"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@types/react": "*",
|
||||
"@types/react-dom": "*",
|
||||
"react": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc",
|
||||
"react-dom": "^16.8 || ^17.0 || ^18.0 || ^19.0 || ^19.0.0-rc"
|
||||
},
|
||||
"peerDependenciesMeta": {
|
||||
"@types/react": {
|
||||
"optional": true
|
||||
},
|
||||
"@types/react-dom": {
|
||||
"optional": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"node_modules/@radix-ui/react-use-callback-ref": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/@radix-ui/react-use-callback-ref/-/react-use-callback-ref-1.1.0.tgz",
|
||||
|
|
|
@ -10,8 +10,10 @@
|
|||
},
|
||||
"dependencies": {
|
||||
"@radix-ui/react-dialog": "^1.1.6",
|
||||
"@radix-ui/react-label": "^2.1.2",
|
||||
"@radix-ui/react-select": "^2.1.6",
|
||||
"@radix-ui/react-slot": "^1.1.2",
|
||||
"@radix-ui/react-tabs": "^1.1.3",
|
||||
"@supabase/ssr": "^0.5.2",
|
||||
"@supabase/supabase-js": "^2.49.1",
|
||||
"class-variance-authority": "^0.7.1",
|
||||
|
|
|
@ -0,0 +1,19 @@
|
|||
import * as React from "react"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const Input = React.forwardRef(({ className, type, ...props }, ref) => {
|
||||
return (
|
||||
(<input
|
||||
type={type}
|
||||
className={cn(
|
||||
"flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-base shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium file:text-foreground placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",
|
||||
className
|
||||
)}
|
||||
ref={ref}
|
||||
{...props} />)
|
||||
);
|
||||
})
|
||||
Input.displayName = "Input"
|
||||
|
||||
export { Input }
|
|
@ -0,0 +1,16 @@
|
|||
import * as React from "react"
|
||||
import * as LabelPrimitive from "@radix-ui/react-label"
|
||||
import { cva } from "class-variance-authority";
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const labelVariants = cva(
|
||||
"text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
|
||||
)
|
||||
|
||||
const Label = React.forwardRef(({ className, ...props }, ref) => (
|
||||
<LabelPrimitive.Root ref={ref} className={cn(labelVariants(), className)} {...props} />
|
||||
))
|
||||
Label.displayName = LabelPrimitive.Root.displayName
|
||||
|
||||
export { Label }
|
|
@ -0,0 +1,41 @@
|
|||
import * as React from "react"
|
||||
import * as TabsPrimitive from "@radix-ui/react-tabs"
|
||||
|
||||
import { cn } from "@/lib/utils"
|
||||
|
||||
const Tabs = TabsPrimitive.Root
|
||||
|
||||
const TabsList = React.forwardRef(({ className, ...props }, ref) => (
|
||||
<TabsPrimitive.List
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"inline-flex h-9 items-center justify-center rounded-lg bg-muted p-1 text-muted-foreground",
|
||||
className
|
||||
)}
|
||||
{...props} />
|
||||
))
|
||||
TabsList.displayName = TabsPrimitive.List.displayName
|
||||
|
||||
const TabsTrigger = React.forwardRef(({ className, ...props }, ref) => (
|
||||
<TabsPrimitive.Trigger
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"inline-flex items-center justify-center whitespace-nowrap rounded-md px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow",
|
||||
className
|
||||
)}
|
||||
{...props} />
|
||||
))
|
||||
TabsTrigger.displayName = TabsPrimitive.Trigger.displayName
|
||||
|
||||
const TabsContent = React.forwardRef(({ className, ...props }, ref) => (
|
||||
<TabsPrimitive.Content
|
||||
ref={ref}
|
||||
className={cn(
|
||||
"mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",
|
||||
className
|
||||
)}
|
||||
{...props} />
|
||||
))
|
||||
TabsContent.displayName = TabsPrimitive.Content.displayName
|
||||
|
||||
export { Tabs, TabsList, TabsTrigger, TabsContent }
|
|
@ -0,0 +1,94 @@
|
|||
import { useState, useEffect } from "react";
|
||||
import { supabaseClient } from "@/utils/supabase";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { Button } from "@/components/ui/button";
|
||||
|
||||
function Informacion() {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [conciertos, setConciertos] = useState([]);
|
||||
const [selectedConcierto, setSelectedConcierto] = useState(null);
|
||||
const [seatType, setSeatType] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
fetchConciertos();
|
||||
}, []);
|
||||
|
||||
const fetchConciertos = async () => {
|
||||
let { data: conciertos, error } = await supabaseClient
|
||||
.from("conciertos")
|
||||
.select("*");
|
||||
if (error) {
|
||||
console.error(error);
|
||||
} else {
|
||||
setConciertos(conciertos);
|
||||
console.log(conciertos);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelect = (concierto) => {
|
||||
setSelectedConcierto(concierto);
|
||||
setOpen(true);
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<div className="space-y-4">
|
||||
{conciertos.map((concierto) => (
|
||||
<div
|
||||
key={concierto.id}
|
||||
className="flex items-center gap-4 p-4 border rounded-lg"
|
||||
>
|
||||
<div className="w-16 h-16 bg-gray-300" />
|
||||
<div>
|
||||
<p className="text-lg font-semibold">{concierto.nombre}</p>
|
||||
<p className="text-sm text-gray-600">{concierto.fecha}</p>
|
||||
</div>
|
||||
<Button className="ml-auto" onClick={() => handleSelect(concierto)}>
|
||||
Seleccionar
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>{selectedConcierto?.name}</DialogTitle>
|
||||
<p className="text-sm text-gray-600">
|
||||
{selectedConcierto?.location}
|
||||
</p>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4">
|
||||
<Select onValueChange={setSeatType}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Selecciona un tipo de asiento" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="premium">Premium</SelectItem>
|
||||
<SelectItem value="standard">Standard</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="flex justify-end gap-2 mt-4">
|
||||
<Button variant="outline" onClick={() => setOpen(false)}>
|
||||
Cancelar
|
||||
</Button>
|
||||
<Button> Aceptar</Button>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
export default Informacion;
|
|
@ -1,104 +1,51 @@
|
|||
import { useState, useEffect } from "react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { supabaseClient } from "@/utils/supabase";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
|
||||
/*const concerts = [
|
||||
{ id: 1, name: "Concierto Fake", location: "Arena Xalapa" },
|
||||
{ id: 2, name: "Concierto Fake", location: "Arena Xalapa" },
|
||||
{ id: 3, name: "Concierto Fake", location: "Arena Xalapa" },
|
||||
];*/
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@/components/ui/card";
|
||||
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs";
|
||||
import Informacion from "@/components/vistas/Informacion";
|
||||
import Reporte from "@/components/vistas/Reporte";
|
||||
|
||||
export default function ConcertList() {
|
||||
const [open, setOpen] = useState(false);
|
||||
const [conciertos, setConciertos] = useState([]);
|
||||
const [selectedConcierto, setSelectedConcierto] = useState(null);
|
||||
const [seatType, setSeatType] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
fetchConciertos();
|
||||
}, []);
|
||||
|
||||
const fetchConciertos = async () => {
|
||||
let { data: conciertos, error } = await supabaseClient
|
||||
.from("conciertos")
|
||||
.select("*");
|
||||
if (error) {
|
||||
console.error(error);
|
||||
} else {
|
||||
setConciertos(conciertos);
|
||||
console.log(conciertos);
|
||||
}
|
||||
};
|
||||
|
||||
const handleSelect = (concierto) => {
|
||||
setSelectedConcierto(concierto);
|
||||
setOpen(true);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-6">
|
||||
<h1 className="text-2xl font-bold text-center mb-4">Boletera Bodoques</h1>
|
||||
<div className="flex gap-2 justify-center mb-4">
|
||||
<Button variant="outline">Información</Button>
|
||||
<Button variant="outline">Reportes</Button>
|
||||
<div className="w-screen flex flex-col items-center pt-10">
|
||||
<div className="flex flex-col items-center w-[80%]">
|
||||
<Tabs defaultValue="account" className="w-full">
|
||||
<TabsList className="grid w-full grid-cols-2">
|
||||
<TabsTrigger value="info">Información</TabsTrigger>
|
||||
<TabsTrigger value="reportes">Reportes</TabsTrigger>
|
||||
</TabsList>
|
||||
<TabsContent value="info">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle></CardTitle>
|
||||
<CardDescription></CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-2">
|
||||
<Informacion />
|
||||
</CardContent>
|
||||
<CardFooter></CardFooter>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
<TabsContent value="reportes">
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle></CardTitle>
|
||||
<CardDescription></CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="space-y-2">
|
||||
<Reporte />
|
||||
</CardContent>
|
||||
<CardFooter></CardFooter>
|
||||
</Card>
|
||||
</TabsContent>
|
||||
</Tabs>
|
||||
</div>
|
||||
<div className="space-y-4">
|
||||
{conciertos.map((concierto) => (
|
||||
<div
|
||||
key={concierto.id}
|
||||
className="flex items-center gap-4 p-4 border rounded-lg"
|
||||
>
|
||||
<div className="w-16 h-16 bg-gray-300" />
|
||||
<div>
|
||||
<p className="text-lg font-semibold">{concierto.nombre}</p>
|
||||
<p className="text-sm text-gray-600">{concierto.fecha}</p>
|
||||
</div>
|
||||
<Button className="ml-auto" onClick={() => handleSelect(concierto)}>
|
||||
Seleccionar
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<Dialog open={open} onOpenChange={setOpen}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>{selectedConcierto?.name}</DialogTitle>
|
||||
<p className="text-sm text-gray-600">
|
||||
{selectedConcierto?.location}
|
||||
</p>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4">
|
||||
<Select onValueChange={setSeatType}>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="Selecciona un tipo de asiento" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="premium">Premium</SelectItem>
|
||||
<SelectItem value="standard">Standard</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="flex justify-end gap-2 mt-4">
|
||||
<Button variant="outline" onClick={() => setOpen(false)}>
|
||||
Cancelar
|
||||
</Button>
|
||||
<Button> Aceptar</Button>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue