Skip to main content

UI Components

Core UI components for building consistent interfaces throughout the GIMA application.

Card Components

A set of composable card components for displaying content in structured containers.
import {
  Card,
  CardHeader,
  CardTitle,
  CardDescription,
  CardAction,
  CardContent,
  CardFooter
} from "@/components/ui/Card"

Description

The Card component system provides a flexible way to create content containers with consistent styling and structure. All components accept standard React props for div elements.

Components

Card

Base card container with rounded corners, border, and shadow.
className
string
Additional CSS classes to apply
...props
React.ComponentProps<'div'>
All standard div element props
Default Styles:
  • Rounded corners (rounded-xl)
  • White background with border
  • Shadow and padding
  • Flexbox column layout

CardHeader

Header section with grid layout for title and optional action button.
className
string
Additional CSS classes to apply
Features:
  • Grid layout with auto-placement
  • Container queries support
  • Automatic action button positioning

CardTitle

Title text with semibold font weight.
className
string
Additional CSS classes to apply

CardDescription

Muted description text below title.
className
string
Additional CSS classes to apply

CardAction

Action button container positioned in header.
className
string
Additional CSS classes to apply

CardContent

Main content area with horizontal padding.
className
string
Additional CSS classes to apply

CardFooter

Footer section with optional top border.
className
string
Additional CSS classes to apply

TypeScript Signature

function Card({ className, ...props }: React.ComponentProps<"div">): JSX.Element
function CardHeader({ className, ...props }: React.ComponentProps<"div">): JSX.Element
function CardTitle({ className, ...props }: React.ComponentProps<"div">): JSX.Element
function CardDescription({ className, ...props }: React.ComponentProps<"div">): JSX.Element
function CardAction({ className, ...props }: React.ComponentProps<"div">): JSX.Element
function CardContent({ className, ...props }: React.ComponentProps<"div">): JSX.Element
function CardFooter({ className, ...props }: React.ComponentProps<"div">): JSX.Element

Usage Example

import {
  Card,
  CardHeader,
  CardTitle,
  CardDescription,
  CardContent,
  CardFooter
} from "@/components/ui/Card"

export default function AssetCard() {
  return (
    <Card>
      <CardHeader>
        <CardTitle>Asset Details</CardTitle>
        <CardDescription>Information about this asset</CardDescription>
      </CardHeader>
      <CardContent>
        <p>Asset content goes here</p>
      </CardContent>
      <CardFooter>
        <button>View Details</button>
      </CardFooter>
    </Card>
  )
}

Data Slots

Each component includes a data-slot attribute for targeted styling:
  • card
  • card-header
  • card-title
  • card-description
  • card-action
  • card-content
  • card-footer

ChartPlaceholder

Animated chart visualization component with period selector.
import { ChartPlaceholder } from "@/components/ui/ChartPlaceholder"

Description

A simple bar chart visualization component with animated bars that grow on mount. Includes a dropdown to select different time periods.

Props

title
string
required
Chart title displayed in header
period
string
default:"Últimos 6 meses"
Default selected period in the dropdown

TypeScript Interface

interface ChartPlaceholderProps {
  title: string
  period?: string
}

Features

  • Animated Bars: Bars animate from 0 to full height on mount
  • Period Selector: Dropdown with predefined time periods
  • Responsive: Adapts to container width
  • Weekly Data: Shows 7 bars for days of the week

Usage Example

import { ChartPlaceholder } from "@/components/ui/ChartPlaceholder"

export default function Dashboard() {
  return (
    <div className="grid grid-cols-2 gap-4">
      <ChartPlaceholder 
        title="Mantenimientos Completados"
        period="Últimos 3 meses"
      />
      <ChartPlaceholder 
        title="Activos Registrados"
      />
    </div>
  )
}

Period Options

Default dropdown includes:
  • Últimos 6 meses (default)
  • Últimos 3 meses
  • Último mes
  • Última semana

Animation

Bars use CSS transitions:
style={{
  height: isLoaded ? `${heights[idx]}%` : "0%",
  opacity: isLoaded ? 1 : 0.5,
}}

DeleteAlerta

Confirmation modal for destructive actions.
import DeleteAlert from "@/components/ui/DeleteAlerta"

Description

A modal dialog that prompts the user to confirm deletion actions. Features a warning icon, customizable text, and cancel/confirm buttons.

Props

isOpen
boolean
required
Controls whether the modal is visible
onClose
() => void
required
Callback function when user cancels or clicks outside
onConfirm
() => void
required
Callback function when user confirms deletion
title
string
required
Modal title text
description
string
required
Description text explaining the action

TypeScript Interface

interface DeleteAlertProps {
  isOpen: boolean
  onClose: () => void
  onConfirm: () => void
  title: string
  description: string
}

Features

  • Backdrop: Semi-transparent backdrop with blur effect
  • Click Outside: Clicking backdrop closes modal
  • Warning Icon: Red alert triangle icon
  • Close Button: X button in top-right corner
  • Action Buttons: Cancel and confirm buttons

Usage Example

"use client"

import { useState } from "react"
import DeleteAlert from "@/components/ui/DeleteAlerta"

export default function AssetList() {
  const [showDeleteAlert, setShowDeleteAlert] = useState(false)
  const [selectedAsset, setSelectedAsset] = useState<string | null>(null)

  const handleDelete = async () => {
    // Perform deletion
    await deleteAsset(selectedAsset)
    setShowDeleteAlert(false)
  }

  return (
    <div>
      <button onClick={() => {
        setSelectedAsset("asset-123")
        setShowDeleteAlert(true)
      }}>
        Delete Asset
      </button>

      <DeleteAlert
        isOpen={showDeleteAlert}
        onClose={() => setShowDeleteAlert(false)}
        onConfirm={handleDelete}
        title="¿Eliminar este activo?"
        description="Esta acción no se puede deshacer. El activo será eliminado permanentemente."
      />
    </div>
  )
}

Styling

  • Modal: White rounded card with shadow
  • Backdrop: Black with 40% opacity and blur
  • Confirm Button: Red with hover effect and shadow
  • Cancel Button: White with gray border
  • Z-index: z-60 to appear above other content

SidebarContext

Context provider and hook for sidebar state management.
import { SidebarProvider, useSidebar } from "@/components/ui/sidebarContext"

Description

Provides global sidebar state management using React Context. Must be used as a wrapper for components that need to control or read sidebar state.

SidebarProvider

children
ReactNode
required
Child components that will have access to sidebar context

useSidebar Hook

Returns sidebar state and control functions.

Return Type

type SidebarContextType = {
  isOpen: boolean      // Current sidebar state
  toggle: () => void   // Toggle sidebar open/closed
  open: () => void     // Open sidebar
  close: () => void    // Close sidebar
}

TypeScript Interfaces

type SidebarContextType = {
  isOpen: boolean
  toggle: () => void
  open: () => void
  close: () => void
}

function SidebarProvider({ children }: { children: ReactNode }): JSX.Element
function useSidebar(): SidebarContextType

Usage Example

"use client"

import { SidebarProvider, useSidebar } from "@/components/ui/sidebarContext"

// Provider at root level
export default function Layout({ children }) {
  return (
    <SidebarProvider>
      <div className="flex">
        <Sidebar />
        <main>{children}</main>
      </div>
    </SidebarProvider>
  )
}

// Consumer component
function ToggleButton() {
  const { isOpen, toggle } = useSidebar()
  
  return (
    <button onClick={toggle}>
      {isOpen ? "Close" : "Open"} Sidebar
    </button>
  )
}

Error Handling

The useSidebar hook throws an error if used outside of SidebarProvider:
if (!ctx) throw new Error("useSidebar debe usarse dentro de SidebarProvider")

Default State

Sidebar is closed by default (isOpen: false).

TablaDeCategorias

A specialized table component for displaying and managing asset categories.
import TablaDeCategorias from "@/components/configuracion/TablaDeCategorias"

Description

The TablaDeCategorias component renders a styled table displaying all asset categories with their details. It automatically fetches category data and renders rows for each category.

Props

This component has no props - it fetches data internally from @/data/categories.

Usage

import TablaDeCategorias from "@/components/configuracion/TablaDeCategorias"

export default function CategoriasPage() {
  return (
    <div className="p-8">
      <TablaDeCategorias />
    </div>
  )
}

Data Source

The component imports categories from the data file:
import { categories } from "@/data/categories";

Table Structure

The table displays the following columns:
  1. ID Categoría - Category identifier (e.g., CAT-001)
  2. Nombre - Category name (e.g., COMPUTO, INFRAESTRUCTURA)
  3. Descripción - Category description
  4. Total Activos - Number of assets in the category
  5. Acciones - Action buttons (edit/delete)

Styling

  • Container: White background with rounded corners (rounded-3xl), border, and shadow
  • Table: Full width with left-aligned text
  • Header:
    • Background: bg-background
    • Text: Uppercase, bold, small (text-xs), gray color
    • Tracking: Wide letter spacing (tracking-wider)
    • Rounded corners on first and last header cells
  • Body: Divided rows with light gray dividers (divide-gray-50)

Implementation Details

export default function TablaDeCategorias() {
  return (
    <div className="overflow-hidden bg-white rounded-3xl border border-gray-100 shadow-sm">
      <table className="w-full text-left border-collapse">
        <thead className="bg-background">
          <tr>
            <th className="py-4 px-6 text-xs font-bold text-gray-500 uppercase tracking-wider rounded-tl-3xl">
              ID Categoría
            </th>
            <th className="py-4 px-6 text-xs font-bold text-gray-500 uppercase tracking-wider">
              Nombre
            </th>
            <th className="py-4 px-6 text-xs font-bold text-gray-500 uppercase tracking-wider">
              Descripción
            </th>
            <th className="py-4 px-6 text-xs font-bold text-gray-500 uppercase tracking-wider text-center">
              Total Activos
            </th>
            <th className="py-4 px-6 text-xs font-bold text-gray-500 uppercase tracking-wider text-center rounded-tr-3xl">
              Acciones
            </th>
          </tr>
        </thead>
        <tbody className="divide-y divide-gray-50">
          {categories.map((category, index) => (
            <FilaDeCategorias
              key={index}
              id={category.id}
              name={category.name}
              description={category.description}
              total={category.total}
            />
          ))}
        </tbody>
      </table>
    </div>
  );
}

FilaDeCategorias Component

The component imports FilaDeCategorias from ./filaDeCategorias, but this file doesn’t exist as a separate component in the source code. This appears to be a missing implementation. The row rendering logic should be implemented directly in TablaDeCategorias or the missing component should be created.

Source File

src/components/configuracion/TablaDeCategorias.tsx

Build docs developers (and LLMs) love