From a02d1921acbbd0e034c34c5136782b78ec3d9f67 Mon Sep 17 00:00:00 2001
From: SirRobert-1 <rviverosgonzalez@gmail.com>
Date: Wed, 5 Mar 2025 07:43:11 -0600
Subject: [PATCH] Add UI components for labels, inputs, tabs, and report views;
 update package dependencies

---
 ventaboletos/package-lock.json                |  83 +++++++++++
 ventaboletos/package.json                     |   2 +
 ventaboletos/src/components/ui/input.jsx      |  19 +++
 ventaboletos/src/components/ui/label.jsx      |  16 ++
 ventaboletos/src/components/ui/tabs.jsx       |  41 ++++++
 .../src/components/vistas/Informacion.jsx     |  94 ++++++++++++
 .../{reportes => vistas}/Reporte.jsx          |   0
 ventaboletos/src/pages/index.js               | 137 ++++++------------
 8 files changed, 297 insertions(+), 95 deletions(-)
 create mode 100644 ventaboletos/src/components/ui/input.jsx
 create mode 100644 ventaboletos/src/components/ui/label.jsx
 create mode 100644 ventaboletos/src/components/ui/tabs.jsx
 create mode 100644 ventaboletos/src/components/vistas/Informacion.jsx
 rename ventaboletos/src/components/{reportes => vistas}/Reporte.jsx (100%)

diff --git a/ventaboletos/package-lock.json b/ventaboletos/package-lock.json
index 0169161..3f76544 100644
--- a/ventaboletos/package-lock.json
+++ b/ventaboletos/package-lock.json
@@ -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",
diff --git a/ventaboletos/package.json b/ventaboletos/package.json
index cdb6117..db9137e 100644
--- a/ventaboletos/package.json
+++ b/ventaboletos/package.json
@@ -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",
diff --git a/ventaboletos/src/components/ui/input.jsx b/ventaboletos/src/components/ui/input.jsx
new file mode 100644
index 0000000..41ec05e
--- /dev/null
+++ b/ventaboletos/src/components/ui/input.jsx
@@ -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 }
diff --git a/ventaboletos/src/components/ui/label.jsx b/ventaboletos/src/components/ui/label.jsx
new file mode 100644
index 0000000..a1f4099
--- /dev/null
+++ b/ventaboletos/src/components/ui/label.jsx
@@ -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 }
diff --git a/ventaboletos/src/components/ui/tabs.jsx b/ventaboletos/src/components/ui/tabs.jsx
new file mode 100644
index 0000000..b674eb9
--- /dev/null
+++ b/ventaboletos/src/components/ui/tabs.jsx
@@ -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 }
diff --git a/ventaboletos/src/components/vistas/Informacion.jsx b/ventaboletos/src/components/vistas/Informacion.jsx
new file mode 100644
index 0000000..8a1ca4c
--- /dev/null
+++ b/ventaboletos/src/components/vistas/Informacion.jsx
@@ -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;
diff --git a/ventaboletos/src/components/reportes/Reporte.jsx b/ventaboletos/src/components/vistas/Reporte.jsx
similarity index 100%
rename from ventaboletos/src/components/reportes/Reporte.jsx
rename to ventaboletos/src/components/vistas/Reporte.jsx
diff --git a/ventaboletos/src/pages/index.js b/ventaboletos/src/pages/index.js
index 39d7425..6af3ecf 100644
--- a/ventaboletos/src/pages/index.js
+++ b/ventaboletos/src/pages/index.js
@@ -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>
   );
 }