Clientes y facturas de cliente
This commit is contained in:
parent
5f2afd0520
commit
a2b5c96cd7
@ -45,14 +45,14 @@ export class CustomerInvoiceReportPDFPresenter extends Presenter<
|
||||
right: "10mm",
|
||||
top: "10mm",
|
||||
},
|
||||
landscape: false,
|
||||
preferCSSPageSize: true,
|
||||
omitBackground: false,
|
||||
printBackground: true,
|
||||
displayHeaderFooter: true,
|
||||
headerTemplate: "<div />",
|
||||
footerTemplate:
|
||||
'<div style="text-align: center;width: 297mm;font-size: 10px;">Página <span style="margin-right: 1cm"><span class="pageNumber"></span> de <span class="totalPages"></span></span></div>',
|
||||
// landscape: false,
|
||||
// preferCSSPageSize: true,
|
||||
// omitBackground: false,
|
||||
// printBackground: true,
|
||||
// displayHeaderFooter: false,
|
||||
// headerTemplate: "<div />",
|
||||
// footerTemplate:
|
||||
// '<div style="text-align: center;width: 297mm;font-size: 10px;">Página <span style="margin-right: 1cm"><span class="pageNumber"></span> de <span class="totalPages"></span></span></div>',
|
||||
});
|
||||
|
||||
await browser.close();
|
||||
|
||||
@ -175,7 +175,7 @@
|
||||
<td>{{description}}</td>
|
||||
<td class="text-right">{{#if quantity}}{{quantity}}{{else}} {{/if}}</td>
|
||||
<td class="text-right">{{#if unit_amount}}{{unit_amount}}{{else}} {{/if}}</td>
|
||||
<td class="text-right">{{#if total_amount}}{{total_amount}}{{else}} {{/if}}</td>
|
||||
<td class="text-right">{{#if subtotal_amount}}{{subtotal_amount}}{{else}} {{/if}}</td>
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
|
||||
@ -110,15 +110,17 @@
|
||||
|
||||
<body>
|
||||
|
||||
<header>
|
||||
<aside class="flex items-start mb-4 w-full">
|
||||
<header id="header">
|
||||
<aside class="flex items-start mb-4 w-full bg-red-600">
|
||||
<!-- Bloque IZQUIERDO: imagen arriba + texto abajo, alineado a la izquierda -->
|
||||
<div class="w-[70%] flex flex-col items-start text-left">
|
||||
<div class="flex flex-col 70% items-start text-left bg-green-700">
|
||||
<img src="https://rodax-software.com/images/logo1.jpg" alt="Logo Rodax" class="block h-14 w-auto mb-1" />
|
||||
<div class="flex w-full">
|
||||
<div class="p-1 ">
|
||||
<p>Factura nº:<strong> {{invoice_number}}</strong></p>
|
||||
<h3 class="text-2xl font-normal">PROFORMA</h3>
|
||||
<p>Nº:<strong> {{invoice_number}}</strong></p>
|
||||
<p><span>Fecha:<strong> {{invoice_date}}</strong></p>
|
||||
<p>Página <span class="pageNumber"></span> de <span class="totalPages"></span></p>
|
||||
</div>
|
||||
<div class="p-1 ml-9">
|
||||
<h2 class="font-semibold uppercase mb-1">{{recipient.name}}</h2>
|
||||
@ -145,7 +147,6 @@
|
||||
|
||||
<main id="main">
|
||||
<section id="details" class="border-b border-black ">
|
||||
|
||||
<div class="relative pt-0 border-b border-black">
|
||||
<!-- Badge TOTAL decorado con imagen -->
|
||||
<div class="absolute -top-9 right-0">
|
||||
@ -175,7 +176,7 @@
|
||||
<td>{{description}}</td>
|
||||
<td class="text-right">{{#if quantity}}{{quantity}}{{else}} {{/if}}</td>
|
||||
<td class="text-right">{{#if unit_amount}}{{unit_amount}}{{else}} {{/if}}</td>
|
||||
<td class="text-right">{{#if total_amount}}{{total_amount}}{{else}} {{/if}}</td>
|
||||
<td class="text-right">{{#if subtotal_amount}}{{subtotal_amount}}{{else}} {{/if}}</td>
|
||||
</td>
|
||||
</tr>
|
||||
{{/each}}
|
||||
|
||||
@ -1,14 +1,12 @@
|
||||
import {
|
||||
AudioWaveform,
|
||||
BookOpen,
|
||||
Bot,
|
||||
Command,
|
||||
FileCheckIcon,
|
||||
Frame,
|
||||
GalleryVerticalEnd,
|
||||
HomeIcon,
|
||||
MapIcon,
|
||||
PieChart,
|
||||
Settings2,
|
||||
SquareTerminal,
|
||||
} from "lucide-react";
|
||||
|
||||
import {
|
||||
@ -23,18 +21,22 @@ import {
|
||||
HelpCircleIcon,
|
||||
LayoutDashboardIcon,
|
||||
ListIcon,
|
||||
SearchIcon,
|
||||
SettingsIcon,
|
||||
UsersIcon,
|
||||
} from "lucide-react";
|
||||
import * as React from "react";
|
||||
|
||||
import { Sidebar, SidebarContent, SidebarFooter, SidebarHeader } from "@repo/shadcn-ui/components";
|
||||
import { NavDocuments } from "./nav-documents.tsx";
|
||||
import {
|
||||
Sidebar,
|
||||
SidebarContent,
|
||||
SidebarFooter,
|
||||
SidebarHeader,
|
||||
SidebarRail,
|
||||
} from "@repo/shadcn-ui/components";
|
||||
import { NavMain } from "./nav-main.tsx";
|
||||
import { NavProjects } from "./nav-projects.tsx";
|
||||
import { NavSecondary } from "./nav-secondary.tsx";
|
||||
import { NavUser } from "./nav-user.tsx";
|
||||
import { SearchForm } from "./search-form.tsx";
|
||||
import { TeamSwitcher } from "./team-switcher.tsx";
|
||||
|
||||
const data = {
|
||||
@ -129,11 +131,6 @@ const data = {
|
||||
url: "#",
|
||||
icon: HelpCircleIcon,
|
||||
},
|
||||
{
|
||||
title: "Buscar",
|
||||
url: "#",
|
||||
icon: SearchIcon,
|
||||
},
|
||||
],
|
||||
documents: [
|
||||
{
|
||||
@ -179,88 +176,48 @@ const data2 = {
|
||||
},
|
||||
],
|
||||
navMain: [
|
||||
{
|
||||
title: "Inicio",
|
||||
url: "/",
|
||||
icon: HomeIcon,
|
||||
isActive: true,
|
||||
},
|
||||
{
|
||||
title: "Clientes",
|
||||
url: "/customers",
|
||||
icon: SquareTerminal,
|
||||
icon: UsersIcon,
|
||||
isActive: true,
|
||||
items: [
|
||||
{
|
||||
title: "History",
|
||||
url: "#",
|
||||
title: "Listado de clientes",
|
||||
url: "/customers",
|
||||
},
|
||||
{
|
||||
title: "Starred",
|
||||
url: "#",
|
||||
},
|
||||
{
|
||||
title: "Settings",
|
||||
url: "#",
|
||||
title: "Añadir un cliente",
|
||||
url: "/customers/create",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Proformas de cliente",
|
||||
url: "/customer-proforma",
|
||||
icon: Bot,
|
||||
title: "Facturas proforma",
|
||||
icon: FileTextIcon,
|
||||
items: [
|
||||
{
|
||||
title: "Genesis",
|
||||
url: "#",
|
||||
title: "Listado de proformas",
|
||||
url: "/customer-proforma",
|
||||
},
|
||||
{
|
||||
title: "Explorer",
|
||||
url: "#",
|
||||
},
|
||||
{
|
||||
title: "Quantum",
|
||||
title: "Enviar a Veri*Factu",
|
||||
url: "#",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Facturas de cliente",
|
||||
icon: FileCheckIcon,
|
||||
items: [
|
||||
{
|
||||
title: "Listado de facturas",
|
||||
url: "/customer-invoices",
|
||||
icon: BookOpen,
|
||||
items: [
|
||||
{
|
||||
title: "Introduction",
|
||||
url: "#",
|
||||
},
|
||||
{
|
||||
title: "Get Started",
|
||||
url: "#",
|
||||
},
|
||||
{
|
||||
title: "Tutorials",
|
||||
url: "#",
|
||||
},
|
||||
{
|
||||
title: "Changelog",
|
||||
url: "#",
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
title: "Settings",
|
||||
url: "#",
|
||||
icon: Settings2,
|
||||
items: [
|
||||
{
|
||||
title: "General",
|
||||
url: "#",
|
||||
},
|
||||
{
|
||||
title: "Team",
|
||||
url: "#",
|
||||
},
|
||||
{
|
||||
title: "Billing",
|
||||
url: "#",
|
||||
},
|
||||
{
|
||||
title: "Limits",
|
||||
url: "#",
|
||||
},
|
||||
],
|
||||
},
|
||||
@ -287,18 +244,18 @@ const data2 = {
|
||||
export function AppSidebar({ ...props }: React.ComponentProps<typeof Sidebar>) {
|
||||
return (
|
||||
<Sidebar collapsible='icon' {...props}>
|
||||
<SidebarHeader>
|
||||
<SidebarHeader className='mb-3'>
|
||||
<TeamSwitcher teams={data2.teams} />
|
||||
<SearchForm />
|
||||
</SidebarHeader>
|
||||
<SidebarContent>
|
||||
<NavMain items={data2.navMain} />
|
||||
<NavProjects projects={data2.projects} />
|
||||
<NavDocuments items={data.documents} />
|
||||
<NavSecondary items={data.navSecondary} className='mt-auto' />
|
||||
</SidebarContent>
|
||||
<SidebarFooter>
|
||||
<NavSecondary items={data.navSecondary} className='mt-auto' />
|
||||
<NavUser user={data.user} />
|
||||
</SidebarFooter>
|
||||
<SidebarRail />
|
||||
</Sidebar>
|
||||
);
|
||||
}
|
||||
|
||||
@ -1,23 +1,35 @@
|
||||
import { type LucideIcon, MailIcon, PlusCircleIcon } from "lucide-react";
|
||||
import { ChevronRightIcon, type LucideIcon, PlusCircleIcon } from "lucide-react";
|
||||
|
||||
import {
|
||||
Button,
|
||||
Collapsible,
|
||||
CollapsibleContent,
|
||||
CollapsibleTrigger,
|
||||
SidebarGroup,
|
||||
SidebarGroupContent,
|
||||
SidebarMenu,
|
||||
SidebarMenuButton,
|
||||
SidebarMenuItem,
|
||||
SidebarMenuSub,
|
||||
SidebarMenuSubButton,
|
||||
SidebarMenuSubItem,
|
||||
} from "@repo/shadcn-ui/components";
|
||||
import { useNavigate } from "react-router";
|
||||
|
||||
type NavMainItem = {
|
||||
title: string;
|
||||
url?: string;
|
||||
icon?: LucideIcon;
|
||||
isActive?: boolean;
|
||||
items?: {
|
||||
title: string;
|
||||
url: string;
|
||||
}[];
|
||||
};
|
||||
|
||||
export function NavMain({
|
||||
items,
|
||||
}: {
|
||||
items: {
|
||||
title: string;
|
||||
url: string;
|
||||
icon?: LucideIcon;
|
||||
}[];
|
||||
items: NavMainItem[];
|
||||
}) {
|
||||
const navigate = useNavigate();
|
||||
|
||||
@ -35,29 +47,34 @@ export function NavMain({
|
||||
<PlusCircleIcon />
|
||||
<span>Quick Create</span>
|
||||
</SidebarMenuButton>
|
||||
<Button
|
||||
size='icon'
|
||||
className='h-9 w-9 shrink-0 group-data-[collapsible=icon]:opacity-0'
|
||||
variant='outline'
|
||||
>
|
||||
<MailIcon />
|
||||
<span className='sr-only'>Inbox</span>
|
||||
</Button>
|
||||
</SidebarMenuItem>
|
||||
</SidebarMenu>
|
||||
<SidebarMenu>
|
||||
{items.map((item) => (
|
||||
<SidebarMenuItem key={item.title}>
|
||||
<SidebarMenuButton
|
||||
isActive={String(window.location.href).includes(item.url)}
|
||||
tooltip={item.title}
|
||||
onClick={() => navigate(item.url)}
|
||||
className='data-[active=true]:bg-accent data-[active=true]:text-accent-foreground cursor-pointer'
|
||||
>
|
||||
<Collapsible key={item.title} asChild defaultOpen={true} className='group/collapsible'>
|
||||
<SidebarMenuItem className='mb-6'>
|
||||
<CollapsibleTrigger asChild>
|
||||
<SidebarMenuButton tooltip={item.title}>
|
||||
{item.icon && <item.icon />}
|
||||
<span>{item.title}</span>
|
||||
<span className='font-semibold'>{item.title}</span>
|
||||
<ChevronRightIcon className='ml-auto transition-transform duration-200 group-data-[state=open]/collapsible:rotate-90' />
|
||||
</SidebarMenuButton>
|
||||
</CollapsibleTrigger>
|
||||
<CollapsibleContent>
|
||||
<SidebarMenuSub>
|
||||
{item.items?.map((subItem) => (
|
||||
<SidebarMenuSubItem key={subItem.title}>
|
||||
<SidebarMenuSubButton asChild>
|
||||
<a href={subItem.url}>
|
||||
<span>{subItem.title}</span>
|
||||
</a>
|
||||
</SidebarMenuSubButton>
|
||||
</SidebarMenuSubItem>
|
||||
))}
|
||||
</SidebarMenuSub>
|
||||
</CollapsibleContent>
|
||||
</SidebarMenuItem>
|
||||
</Collapsible>
|
||||
))}
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
|
||||
38
packages/rdx-ui/src/components/layout/search-form.tsx
Normal file
38
packages/rdx-ui/src/components/layout/search-form.tsx
Normal file
@ -0,0 +1,38 @@
|
||||
import {
|
||||
Button,
|
||||
Label,
|
||||
SidebarGroup,
|
||||
SidebarGroupContent,
|
||||
SidebarInput,
|
||||
SidebarMenu,
|
||||
SidebarMenuItem,
|
||||
} from "@repo/shadcn-ui/components";
|
||||
import { BinocularsIcon, SearchIcon } from "lucide-react";
|
||||
|
||||
export function SearchForm({ ...props }: React.ComponentProps<"form">) {
|
||||
return (
|
||||
<form {...props}>
|
||||
<SidebarGroup className='py-0'>
|
||||
<SidebarGroupContent className='relative'>
|
||||
<SidebarMenu>
|
||||
<SidebarMenuItem className='flex items-center gap-2'>
|
||||
<Label htmlFor='search' className='sr-only'>
|
||||
Search
|
||||
</Label>
|
||||
<SidebarInput id='search' placeholder='Search...' className='pl-8 h-9' />
|
||||
<SearchIcon className='pointer-events-none absolute top-1/2 left-2 size-4 -translate-y-1/2 opacity-50 select-none ' />
|
||||
<Button
|
||||
size='icon'
|
||||
className='h-9 w-9 shrink-0 group-data-[collapsible=icon]:opacity-0'
|
||||
variant='outline'
|
||||
>
|
||||
<BinocularsIcon />
|
||||
<span className='sr-only'>Advanced search</span>
|
||||
</Button>
|
||||
</SidebarMenuItem>
|
||||
</SidebarMenu>
|
||||
</SidebarGroupContent>
|
||||
</SidebarGroup>
|
||||
</form>
|
||||
);
|
||||
}
|
||||
@ -1,13 +1,13 @@
|
||||
import { TrendingDownIcon, TrendingUpIcon } from "lucide-react";
|
||||
|
||||
import { Badge } from "@repo/shadcn-ui/components/badge";
|
||||
import {
|
||||
Card,
|
||||
CardDescription,
|
||||
CardFooter,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "@repo/shadcn-ui/components/card";
|
||||
} from "@repo/shadcn-ui/components";
|
||||
import { Badge } from "@repo/shadcn-ui/components/badge";
|
||||
|
||||
export function SectionCards() {
|
||||
return (
|
||||
|
||||
@ -1,3 +1,5 @@
|
||||
"use client";
|
||||
|
||||
import { ChevronsUpDown, Plus } from "lucide-react";
|
||||
import * as React from "react";
|
||||
|
||||
@ -40,31 +42,31 @@ export function TeamSwitcher({
|
||||
size='lg'
|
||||
className='data-[state=open]:bg-sidebar-accent data-[state=open]:text-sidebar-accent-foreground'
|
||||
>
|
||||
<div className='flex aspect-square size-8 items-center justify-center rounded-lg bg-sidebar-primary text-sidebar-primary-foreground'>
|
||||
<div className='bg-sidebar-primary text-sidebar-primary-foreground flex aspect-square size-8 items-center justify-center rounded-lg'>
|
||||
<activeTeam.logo className='size-4' />
|
||||
</div>
|
||||
<div className='grid flex-1 text-left text-sm leading-tight'>
|
||||
<span className='truncate font-semibold'>{activeTeam.name}</span>
|
||||
<span className='truncate font-medium'>{activeTeam.name}</span>
|
||||
<span className='truncate text-xs'>{activeTeam.plan}</span>
|
||||
</div>
|
||||
<ChevronsUpDown className='ml-auto' />
|
||||
</SidebarMenuButton>
|
||||
</DropdownMenuTrigger>
|
||||
<DropdownMenuContent
|
||||
className='w-[--radix-dropdown-menu-trigger-width] min-w-56 rounded-lg'
|
||||
className='w-(--radix-dropdown-menu-trigger-width) min-w-56 rounded-lg'
|
||||
align='start'
|
||||
side={isMobile ? "bottom" : "right"}
|
||||
sideOffset={4}
|
||||
>
|
||||
<DropdownMenuLabel className='text-xs text-muted-foreground'>Teams</DropdownMenuLabel>
|
||||
<DropdownMenuLabel className='text-muted-foreground text-xs'>Teams</DropdownMenuLabel>
|
||||
{teams.map((team, index) => (
|
||||
<DropdownMenuItem
|
||||
key={team.name}
|
||||
onClick={() => setActiveTeam(team)}
|
||||
className='gap-2 p-2'
|
||||
>
|
||||
<div className='flex size-6 items-center justify-center rounded-sm border'>
|
||||
<team.logo className='size-4 shrink-0' />
|
||||
<div className='flex size-6 items-center justify-center rounded-md border'>
|
||||
<team.logo className='size-3.5 shrink-0' />
|
||||
</div>
|
||||
{team.name}
|
||||
<DropdownMenuShortcut>⌘{index + 1}</DropdownMenuShortcut>
|
||||
@ -72,10 +74,10 @@ export function TeamSwitcher({
|
||||
))}
|
||||
<DropdownMenuSeparator />
|
||||
<DropdownMenuItem className='gap-2 p-2'>
|
||||
<div className='flex size-6 items-center justify-center rounded-md border bg-background'>
|
||||
<div className='flex size-6 items-center justify-center rounded-md border bg-transparent'>
|
||||
<Plus className='size-4' />
|
||||
</div>
|
||||
<div className='font-medium text-muted-foreground'>Add team</div>
|
||||
<div className='text-muted-foreground font-medium'>Add team</div>
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user