This commit is contained in:
David Arranz 2026-05-04 17:26:10 +02:00
parent 1beaa05fa4
commit c91455ffc2
33 changed files with 316 additions and 82 deletions

1
.vscode/launch.json vendored
View File

@ -1,5 +1,4 @@
{ {
"version": "0.6.2",
"configurations": [ "configurations": [
{ {
"name": "WEB: Vite (Chrome)", "name": "WEB: Vite (Chrome)",

View File

@ -1,6 +1,6 @@
{ {
"name": "@erp/factuges-server", "name": "@erp/factuges-server",
"version": "0.6.2", "version": "0.6.3",
"private": true, "private": true,
"scripts": { "scripts": {
"build": "tsup src/index.ts --config tsup.config.ts", "build": "tsup src/index.ts --config tsup.config.ts",

View File

@ -1,7 +1,7 @@
{ {
"name": "@erp/factuges-web", "name": "@erp/factuges-web",
"private": true, "private": true,
"version": "0.6.2", "version": "0.6.3",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite --host --clearScreen false", "dev": "vite --host --clearScreen false",

View File

@ -1,6 +1,6 @@
{ {
"name": "@erp/auth", "name": "@erp/auth",
"version": "0.6.2", "version": "0.6.3",
"private": true, "private": true,
"type": "module", "type": "module",
"sideEffects": false, "sideEffects": false,

View File

@ -1,6 +1,6 @@
{ {
"name": "@erp/core", "name": "@erp/core",
"version": "0.6.2", "version": "0.6.3",
"private": true, "private": true,
"type": "module", "type": "module",
"sideEffects": false, "sideEffects": false,

View File

@ -1,6 +1,6 @@
{ {
"name": "@erp/customer-invoices", "name": "@erp/customer-invoices",
"version": "0.6.2", "version": "0.6.3",
"private": true, "private": true,
"type": "module", "type": "module",
"sideEffects": false, "sideEffects": false,

View File

@ -1,5 +1,6 @@
import { DateHelper, MoneyDTOHelper, PercentageDTOHelper } from "@erp/core"; import { MoneyDTOHelper, PercentageDTOHelper } from "@erp/core";
import type { ISnapshotBuilder, ISnapshotBuilderParams } from "@erp/core/api"; import type { ISnapshotBuilder, ISnapshotBuilderParams } from "@erp/core/api";
import { DateHelper } from "@repo/rdx-utils";
import type { IIssuedInvoiceFullSnapshot } from "../full"; import type { IIssuedInvoiceFullSnapshot } from "../full";

View File

@ -1,4 +1,3 @@
import { NumberHelper } from "@erp/core";
import { DiscountPercentage } from "@erp/core/api"; import { DiscountPercentage } from "@erp/core/api";
import { import {
CurrencyCode, CurrencyCode,
@ -12,7 +11,7 @@ import {
extractOrPushError, extractOrPushError,
maybeFromNullableResult, maybeFromNullableResult,
} from "@repo/rdx-ddd"; } from "@repo/rdx-ddd";
import { Maybe, Result } from "@repo/rdx-utils"; import { Maybe, NumberHelper, Result } from "@repo/rdx-utils";
import type { CreateProformaRequestDTO } from "../../../../common"; import type { CreateProformaRequestDTO } from "../../../../common";
import { import {

View File

@ -1,4 +1,3 @@
import { NumberHelper } from "@erp/core";
import { DiscountPercentage } from "@erp/core/api"; import { DiscountPercentage } from "@erp/core/api";
import { import {
CurrencyCode, CurrencyCode,
@ -12,7 +11,7 @@ import {
extractOrPushError, extractOrPushError,
maybeFromNullableResult, maybeFromNullableResult,
} from "@repo/rdx-ddd"; } from "@repo/rdx-ddd";
import { Result, isNullishOrEmpty, toPatchField } from "@repo/rdx-utils"; import { NumberHelper, Result, isNullishOrEmpty, toPatchField } from "@repo/rdx-utils";
import type { UpdateProformaByIdRequestDTO } from "../../../../common/dto"; import type { UpdateProformaByIdRequestDTO } from "../../../../common/dto";
import { import {

View File

@ -2,7 +2,7 @@ import type { UniqueID } from "@repo/rdx-ddd";
import type { Result } from "@repo/rdx-utils"; import type { Result } from "@repo/rdx-utils";
import type { Proforma } from "../../../domain/proformas"; import type { Proforma } from "../../../domain/proformas";
import type { IProformaFullSnapshot } from "../snapshot-builders"; import type { ProformaFullSnapshot } from "../snapshot-builders";
import type { IProformaCreatorParams } from "./proforma-creator"; import type { IProformaCreatorParams } from "./proforma-creator";
@ -35,7 +35,7 @@ export interface IProformaPublicServices {
getProformaSnapshotById: ( getProformaSnapshotById: (
id: UniqueID, id: UniqueID,
context: IProformaServicesContext context: IProformaServicesContext
) => Promise<Result<IProformaFullSnapshot, Error>>; ) => Promise<Result<ProformaFullSnapshot, Error>>;
generateProformaReport: (id: unknown, options: unknown, context: unknown) => null; generateProformaReport: (id: unknown, options: unknown, context: unknown) => null;
} }

View File

@ -8,8 +8,10 @@ import type { IProformaItemsFullSnapshotBuilder } from "./proforma-items-full-sn
import type { IProformaRecipientFullSnapshotBuilder } from "./proforma-recipient-full-snapshot-builder"; import type { IProformaRecipientFullSnapshotBuilder } from "./proforma-recipient-full-snapshot-builder";
import type { IProformaTaxesFullSnapshotBuilder } from "./proforma-taxes-full-snapshot-builder"; import type { IProformaTaxesFullSnapshotBuilder } from "./proforma-taxes-full-snapshot-builder";
export type ProformaFullSnapshot = GetProformaByIdResponseDTO;
export interface IProformaFullSnapshotBuilder export interface IProformaFullSnapshotBuilder
extends ISnapshotBuilder<Proforma, GetProformaByIdResponseDTO> {} extends ISnapshotBuilder<Proforma, ProformaFullSnapshot> {}
export class ProformaFullSnapshotBuilder implements IProformaFullSnapshotBuilder { export class ProformaFullSnapshotBuilder implements IProformaFullSnapshotBuilder {
constructor( constructor(
@ -19,7 +21,7 @@ export class ProformaFullSnapshotBuilder implements IProformaFullSnapshotBuilder
//private readonly paymentMethodBuilder: IProformaPaymentMethodFullSnapshotBuilder //private readonly paymentMethodBuilder: IProformaPaymentMethodFullSnapshotBuilder
) {} ) {}
toOutput(proforma: Proforma): GetProformaByIdResponseDTO { toOutput(proforma: Proforma): ProformaFullSnapshot {
const items = this.itemsBuilder.toOutput(proforma.items); const items = this.itemsBuilder.toOutput(proforma.items);
const recipient = this.recipientBuilder.toOutput(proforma); const recipient = this.recipientBuilder.toOutput(proforma);
const taxes = this.taxesBuilder.toOutput(proforma.taxes()); const taxes = this.taxesBuilder.toOutput(proforma.taxes());
@ -37,7 +39,7 @@ export class ProformaFullSnapshotBuilder implements IProformaFullSnapshotBuilder
company_id: proforma.companyId.toString(), company_id: proforma.companyId.toString(),
invoice_number: proforma.invoiceNumber.toString(), invoice_number: proforma.invoiceNumber.toString(),
status: proforma.status.toPrimitive() as GetProformaByIdResponseDTO["status"], status: proforma.status.toPrimitive() as ProformaFullSnapshot["status"],
series: maybeToNullable(proforma.series, (value) => value.toString()), series: maybeToNullable(proforma.series, (value) => value.toString()),
invoice_date: proforma.invoiceDate.toDateString(), invoice_date: proforma.invoiceDate.toDateString(),

View File

@ -1,16 +1,16 @@
import { MoneyDTOHelper, PercentageDTOHelper, QuantityDTOHelper } from "@erp/core"; import { MoneyDTOHelper, PercentageDTOHelper, QuantityDTOHelper } from "@erp/core";
import type { ISnapshotBuilder, ISnapshotBuilderParams } from "@erp/core/api"; import type { ISnapshotBuilder, ISnapshotBuilderParams } from "@erp/core/api";
import type { IProformaFullSnapshot } from "../full"; import type { ProformaFullSnapshot } from "../full";
import type { ProformaReportItemSnapshot } from "./proforma-report-item-snapshot.interface"; import type { ProformaReportItemSnapshot } from "./proforma-report-item-snapshot.interface";
export interface IProformaItemReportSnapshotBuilder export interface IProformaItemReportSnapshotBuilder
extends ISnapshotBuilder<IProformaFullSnapshot["items"], ProformaReportItemSnapshot[]> {} extends ISnapshotBuilder<ProformaFullSnapshot["items"], ProformaReportItemSnapshot[]> {}
export class ProformaItemReportSnapshotBuilder implements IProformaItemReportSnapshotBuilder { export class ProformaItemReportSnapshotBuilder implements IProformaItemReportSnapshotBuilder {
toOutput( toOutput(
items: IProformaFullSnapshot["items"], items: ProformaFullSnapshot["items"],
params?: ISnapshotBuilderParams params?: ISnapshotBuilderParams
): ProformaReportItemSnapshot[] { ): ProformaReportItemSnapshot[] {
const locale = params?.locale as string; const locale = params?.locale as string;

View File

@ -1,29 +1,30 @@
import { DateHelper, MoneyDTOHelper, PercentageDTOHelper } from "@erp/core"; import { MoneyDTOHelper, PercentageDTOHelper } from "@erp/core";
import type { ISnapshotBuilder, ISnapshotBuilderParams } from "@erp/core/api"; import type { ISnapshotBuilder, ISnapshotBuilderParams } from "@erp/core/api";
import { DateHelper } from "@repo/rdx-utils";
import type { IProformaFullSnapshot } from "../full"; import type { ProformaFullSnapshot } from "../full";
import type { ProformaReportItemSnapshot } from "./proforma-report-item-snapshot.interface"; import type { ProformaReportItemSnapshot } from "./proforma-report-item-snapshot.interface";
import type { ProformaReportSnapshot } from "./proforma-report-snapshot.interface"; import type { ProformaReportSnapshot } from "./proforma-report-snapshot.interface";
import type { ProformaReportTaxSnapshot } from "./proforma-report-tax-snapshot.interface"; import type { ProformaReportTaxSnapshot } from "./proforma-report-tax-snapshot.interface";
export interface IProformaReportSnapshotBuilder export interface IProformaReportSnapshotBuilder
extends ISnapshotBuilder<IProformaFullSnapshot, ProformaReportSnapshot> {} extends ISnapshotBuilder<ProformaFullSnapshot, ProformaReportSnapshot> {}
export class ProformaReportSnapshotBuilder implements IProformaReportSnapshotBuilder { export class ProformaReportSnapshotBuilder implements IProformaReportSnapshotBuilder {
constructor( constructor(
private readonly itemsBuilder: ISnapshotBuilder< private readonly itemsBuilder: ISnapshotBuilder<
IProformaFullSnapshot["items"], ProformaFullSnapshot["items"],
ProformaReportItemSnapshot[] ProformaReportItemSnapshot[]
>, >,
private readonly taxesBuilder: ISnapshotBuilder< private readonly taxesBuilder: ISnapshotBuilder<
IProformaFullSnapshot["taxes"], ProformaFullSnapshot["taxes"],
ProformaReportTaxSnapshot[] ProformaReportTaxSnapshot[]
> >
) {} ) {}
toOutput( toOutput(
snapshot: IProformaFullSnapshot, snapshot: ProformaFullSnapshot,
params?: ISnapshotBuilderParams params?: ISnapshotBuilderParams
): ProformaReportSnapshot { ): ProformaReportSnapshot {
const locale = params?.locale as string; const locale = params?.locale as string;
@ -90,7 +91,7 @@ export class ProformaReportSnapshotBuilder implements IProformaReportSnapshotBui
}; };
} }
private formatAddress(recipient: IProformaFullSnapshot["recipient"]): string { private formatAddress(recipient: ProformaFullSnapshot["recipient"]): string {
const lines: string[] = []; const lines: string[] = [];
if (recipient.street) lines.push(recipient.street); if (recipient.street) lines.push(recipient.street);

View File

@ -1,5 +1,6 @@
import { DateHelper, MoneyDTOHelper, PercentageDTOHelper } from "@erp/core"; import { MoneyDTOHelper, PercentageDTOHelper } from "@erp/core";
import { Presenter } from "@erp/core/api"; import { Presenter } from "@erp/core/api";
import { DateHelper } from "@repo/rdx-utils";
import type { GetIssuedInvoiceByIdResponseDTO } from "../../../../../common/dto"; import type { GetIssuedInvoiceByIdResponseDTO } from "../../../../../common/dto";

View File

@ -47,28 +47,26 @@ export class ProformaItemsTotalsCalculator {
const amounts = item.totals(); const amounts = item.totals();
// Subtotales // Subtotales
subtotalAmount = subtotalAmount.add(amounts.subtotalAmount.roundUsingScale(2)); subtotalAmount = subtotalAmount.add(amounts.subtotalAmount);
// Descuentos // Descuentos
itemDiscountAmount = itemDiscountAmount.add(amounts.itemDiscountAmount.roundUsingScale(2)); itemDiscountAmount = itemDiscountAmount.add(amounts.itemDiscountAmount);
globalDiscountAmount = globalDiscountAmount.add( globalDiscountAmount = globalDiscountAmount.add(amounts.globalDiscountAmount);
amounts.globalDiscountAmount.roundUsingScale(2) totalDiscountAmount = totalDiscountAmount.add(amounts.totalDiscountAmount);
);
totalDiscountAmount = totalDiscountAmount.add(amounts.totalDiscountAmount.roundUsingScale(2));
// Base imponible // Base imponible
taxableAmount = taxableAmount.add(amounts.taxableAmount.roundUsingScale(2)); taxableAmount = taxableAmount.add(amounts.taxableAmount);
// Impuestos individuales // Impuestos individuales
ivaAmount = ivaAmount.add(amounts.ivaAmount.roundUsingScale(2)); ivaAmount = ivaAmount.add(amounts.ivaAmount);
recAmount = recAmount.add(amounts.recAmount.roundUsingScale(2)); recAmount = recAmount.add(amounts.recAmount);
retentionAmount = retentionAmount.add(amounts.retentionAmount.roundUsingScale(2)); retentionAmount = retentionAmount.add(amounts.retentionAmount);
// Total impuestos del ítem // Total impuestos del ítem
taxesAmount = taxesAmount.add(amounts.taxesAmount.roundUsingScale(2)); taxesAmount = taxesAmount.add(amounts.taxesAmount);
// Total final del ítem // Total final del ítem
totalAmount = totalAmount.add(amounts.totalAmount.roundUsingScale(2)); totalAmount = totalAmount.add(amounts.totalAmount);
} }
return { return {

View File

@ -37,6 +37,7 @@ export class ProformaTaxesCalculator {
const ivaAmount = this.toInvoiceAmount(g.ivaAmount); const ivaAmount = this.toInvoiceAmount(g.ivaAmount);
const recAmount = this.toInvoiceAmount(g.recAmount); const recAmount = this.toInvoiceAmount(g.recAmount);
const retentionAmount = this.toInvoiceAmount(g.retentionAmount); const retentionAmount = this.toInvoiceAmount(g.retentionAmount);
//const taxesAmount = this.toInvoiceAmount(g.taxesAmount);
const taxesAmount = ivaAmount.add(recAmount).subtract(retentionAmount); const taxesAmount = ivaAmount.add(recAmount).subtract(retentionAmount);

View File

@ -5,7 +5,7 @@ import type { Transaction } from "sequelize";
import { import {
type IProformaCreatorParams, type IProformaCreatorParams,
type IProformaFullSnapshot, type ProformaFullSnapshot,
buildProformaCreator, buildProformaCreator,
buildProformaFinder, buildProformaFinder,
buildProformaSnapshotBuilders, buildProformaSnapshotBuilders,
@ -36,7 +36,7 @@ export type ProformaPublicServices = {
getProformaSnapshotById: ( getProformaSnapshotById: (
id: UniqueID, id: UniqueID,
context: ProformaServicesContext context: ProformaServicesContext
) => Promise<Result<IProformaFullSnapshot, Error>>; ) => Promise<Result<ProformaFullSnapshot, Error>>;
createProforma: ( createProforma: (
id: UniqueID, id: UniqueID,

View File

@ -0,0 +1,193 @@
import {
Card,
CardContent,
CardHeader,
CardTitle,
Checkbox,
Field,
FieldContent,
FieldDescription,
FieldGroup,
FieldLabel,
FieldSet,
Input,
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue,
} from "@repo/shadcn-ui/components";
import { FileText } from "lucide-react";
export const ProformaTaxesCard = () => {
return (
<Card className="shadow">
<CardHeader className="px-6 pb-7 pt-3">
<div className="flex items-start gap-3">
<div className="flex size-12 shrink-0 items-center justify-center rounded-lg bg-primary-50 text-primary-600">
<FileText aria-hidden="true" className="size-5" />
</div>
<div className="space-y-1">
<CardTitle className="text-base font-semibold">Impuestos</CardTitle>
<p className="text-sm text-muted-foreground">Configuración fiscal de la proforma</p>
</div>
</div>
</CardHeader>
<CardContent>
<FieldSet>
<FieldGroup className="gap-5">
<SectionIntro
description="Selecciona el régimen fiscal que aplica a esta proforma."
title="1. Régimen fiscal"
variant="primary"
/>
<Field>
<FieldLabel htmlFor="tax-regime">Régimen fiscal</FieldLabel>
<Select defaultValue="general">
<SelectTrigger className="h-9 bg-muted/40 font-medium" id="tax-regime">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="general">01: Operación de régimen general.</SelectItem>
<SelectItem value="exempt">Operación exenta de IVA.</SelectItem>
<SelectItem value="reverse-charge">Inversión del sujeto pasivo.</SelectItem>
</SelectContent>
</Select>
</Field>
</FieldGroup>
</FieldSet>
</CardContent>
<section className="border-y bg-primary-50 px-6 py-4">
<FieldSet>
<FieldGroup className="gap-5">
<SectionIntro
description="Puedes usar un tipo único para todas las líneas de detalle o permitir que cada línea tenga su propio IVA."
title="Configuración de IVA"
variant="primary"
/>
<Field className="items-center gap-3" orientation="horizontal">
<Checkbox defaultChecked id="same-vat" />
<FieldLabel
className="cursor-pointer font-medium text-primary-700"
htmlFor="same-vat"
>
Aplicar el mismo IVA a todas las líneas de la proforma
</FieldLabel>
</Field>
<Field className="w-32">
<FieldLabel className="text-primary-700" htmlFor="default-vat">
IVA por defecto
</FieldLabel>
<Select defaultValue="21">
<SelectTrigger
className="h-9 bg-background/75 font-medium text-primary-700"
id="default-vat"
>
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="21">21%</SelectItem>
<SelectItem value="10">10%</SelectItem>
<SelectItem value="4">4%</SelectItem>
<SelectItem value="0">0%</SelectItem>
</SelectContent>
</Select>
</Field>
</FieldGroup>
</FieldSet>
</section>
<CardContent className="px-6 py-6">
<FieldSet>
<FieldGroup className="gap-5">
<SectionIntro
description="Activa opciones fiscales adicionales como recargo de equivalencia o retenciones (IRPF), según el tipo de cliente y normativa aplicable."
title="Impuestos adicionales"
/>
<div className="space-y-4">
<CheckboxField id="equivalence-surcharge" label="Recargo de equivalencia" />
<CheckboxField id="withholding" label="Incluir retención/IRPF" />
</div>
<Field className="w-36">
<FieldLabel htmlFor="withholding-rate">Retención</FieldLabel>
<div className="relative">
<Input
className="h-9 bg-muted/40 pr-8 text-right font-medium tabular-nums"
defaultValue="0"
id="withholding-rate"
inputMode="decimal"
type="text"
/>
<span
aria-hidden="true"
className="pointer-events-none absolute right-3 top-1/2 -translate-y-1/2 text-sm text-foreground"
>
%
</span>
</div>
</Field>
</FieldGroup>
</FieldSet>
</CardContent>
</Card>
);
};
interface SectionIntroProps {
title: string;
description: string;
variant?: "default" | "primary";
}
const SectionIntro = ({ title, description, variant = "default" }: SectionIntroProps) => {
return (
<Field>
<FieldContent className="space-y-2">
<h3
className={
variant === "primary"
? "text-base font-semibold text-primary-700"
: "text-base font-semibold text-foreground"
}
>
{title}
</h3>
<FieldDescription className="max-w-md text-sm leading-6">{description}</FieldDescription>
</FieldContent>
</Field>
);
};
interface CheckboxFieldProps {
id: string;
label: string;
}
const CheckboxField = ({ id, label }: CheckboxFieldProps) => {
return (
<Field className="items-center gap-3" orientation="horizontal">
<Checkbox id={id} />
<FieldLabel className="cursor-pointer font-medium" htmlFor={id}>
{label}
</FieldLabel>
</Field>
);
};

View File

@ -14,6 +14,7 @@ import type {
} from "../../controllers"; } from "../../controllers";
import { ProformaTotalsSummary } from "../blocks"; import { ProformaTotalsSummary } from "../blocks";
import { ProformaTaxesCard } from "./proforma-taxes-card";
import { ProformaUpdateHeaderEditor } from "./proforma-update-header-editor"; import { ProformaUpdateHeaderEditor } from "./proforma-update-header-editor";
import { ProformaUpdateItemsEditor } from "./proforma-update-items-editor"; import { ProformaUpdateItemsEditor } from "./proforma-update-items-editor";
import { ProformaUpdateTaxEditor } from "./proforma-update-tax-editor"; import { ProformaUpdateTaxEditor } from "./proforma-update-tax-editor";
@ -74,6 +75,10 @@ export const ProformaUpdateEditorForm = ({
<ProformaUpdateItemsEditor disabled={isSubmitting} itemsCtrl={itemsCtrl} taxCtrl={taxCtrl} /> <ProformaUpdateItemsEditor disabled={isSubmitting} itemsCtrl={itemsCtrl} taxCtrl={taxCtrl} />
<div className="grid grid-cols-1">
<ProformaTaxesCard />
</div>
<div className="grid grid-cols-1 gap-4 md:grid-cols-12"> <div className="grid grid-cols-1 gap-4 md:grid-cols-12">
<ProformaUpdateTaxEditor className="md:col-span-6" taxCtrl={taxCtrl} /> <ProformaUpdateTaxEditor className="md:col-span-6" taxCtrl={taxCtrl} />
<ProformaTotalsSummary <ProformaTotalsSummary

View File

@ -1,7 +1,7 @@
{ {
"name": "@erp/customers", "name": "@erp/customers",
"description": "Customers", "description": "Customers",
"version": "0.6.2", "version": "0.6.3",
"private": true, "private": true,
"type": "module", "type": "module",
"sideEffects": false, "sideEffects": false,

View File

@ -1,6 +1,6 @@
{ {
"name": "@erp/factuges", "name": "@erp/factuges",
"version": "0.6.2", "version": "0.6.3",
"private": true, "private": true,
"type": "module", "type": "module",
"sideEffects": false, "sideEffects": false,

View File

@ -1,7 +1,7 @@
{ {
"name": "@erp/supplier-invoices", "name": "@erp/supplier-invoices",
"description": "Supplier invoices", "description": "Supplier invoices",
"version": "0.6.2", "version": "0.6.3",
"private": true, "private": true,
"type": "module", "type": "module",
"sideEffects": false, "sideEffects": false,

View File

@ -1,7 +1,7 @@
{ {
"name": "@erp/suppliers", "name": "@erp/suppliers",
"description": "Suppliers", "description": "Suppliers",
"version": "0.6.2", "version": "0.6.3",
"private": true, "private": true,
"type": "module", "type": "module",
"sideEffects": false, "sideEffects": false,

View File

@ -1,7 +1,7 @@
{ {
"name": "uecko-erp-2025", "name": "uecko-erp-2025",
"private": true, "private": true,
"version": "0.6.2", "version": "0.6.3",
"workspaces": [ "workspaces": [
"apps/*", "apps/*",
"modules/*", "modules/*",

View File

@ -1,6 +1,6 @@
{ {
"name": "@repo/rdx-criteria", "name": "@repo/rdx-criteria",
"version": "0.6.2", "version": "0.6.3",
"private": true, "private": true,
"type": "module", "type": "module",
"sideEffects": false, "sideEffects": false,

View File

@ -1,6 +1,6 @@
{ {
"name": "@repo/rdx-ddd", "name": "@repo/rdx-ddd",
"version": "0.6.2", "version": "0.6.3",
"private": true, "private": true,
"type": "module", "type": "module",
"sideEffects": false, "sideEffects": false,

View File

@ -1,6 +1,6 @@
{ {
"name": "@repo/rdx-logger", "name": "@repo/rdx-logger",
"version": "0.6.2", "version": "0.6.3",
"private": true, "private": true,
"type": "module", "type": "module",
"sideEffects": false, "sideEffects": false,

View File

@ -1,6 +1,6 @@
{ {
"name": "@repo/rdx-ui", "name": "@repo/rdx-ui",
"version": "0.6.2", "version": "0.6.3",
"private": true, "private": true,
"type": "module", "type": "module",
"sideEffects": false, "sideEffects": false,

View File

@ -1,10 +1,9 @@
import { import {
Card, Card,
CardContent, CardContent,
CardDescription,
CardHeader, CardHeader,
FieldDescription, CardTitle,
FieldLegend,
FieldSet,
} from "@repo/shadcn-ui/components"; } from "@repo/shadcn-ui/components";
import { cn } from "@repo/shadcn-ui/lib/utils"; import { cn } from "@repo/shadcn-ui/lib/utils";
import type { ReactNode } from "react"; import type { ReactNode } from "react";
@ -34,7 +33,6 @@ export const FormSectionCard = ({
return ( return (
<Card className={className}> <Card className={className}>
<FieldSet disabled={disabled}>
<CardHeader className={headerClassName}> <CardHeader className={headerClassName}>
<div className="flex items-start gap-3"> <div className="flex items-start gap-3">
{icon ? ( {icon ? (
@ -50,16 +48,15 @@ export const FormSectionCard = ({
) : null} ) : null}
<div className="space-y-1"> <div className="space-y-1">
{title ? <FieldLegend className="font-semibold">{title}</FieldLegend> : null} {title ? <CardTitle className="font-semibold">{title}</CardTitle> : null}
{description ? ( {description ? (
<FieldDescription className="font-medium">{description}</FieldDescription> <CardDescription className="font-medium">{description}</CardDescription>
) : null} ) : null}
</div> </div>
</div> </div>
</CardHeader> </CardHeader>
<CardContent className={contentClassName}>{children}</CardContent> <CardContent className={contentClassName}>{children}</CardContent>
</FieldSet>
</Card> </Card>
); );
}; };

View File

@ -1,6 +1,6 @@
{ {
"name": "@repo/rdx-utils", "name": "@repo/rdx-utils",
"version": "0.6.2", "version": "0.6.3",
"private": true, "private": true,
"type": "module", "type": "module",
"sideEffects": false, "sideEffects": false,

View File

@ -13,14 +13,27 @@
@source "../**/*.{ts,tsx}"; @source "../**/*.{ts,tsx}";
:root { :root {
--primary: #0b7ad0;
--primary-foreground: #ffffff;
--primary-50: #eef8ff;
--primary-100: #d9efff;
--primary-200: #bce4ff;
--primary-300: #8ed3ff;
--primary-400: #58b8f4;
--primary-500: #2e9be4;
--primary-600: #0b7ad0;
--primary-700: #0862a8;
--primary-800: #0a528a;
--primary-900: #0d456f;
--primary-950: #092b49;
--background: #ffffff; --background: #ffffff;
--foreground: #0a0a0a; --foreground: #0a0a0a;
--card: #ffffff; --card: #ffffff;
--card-foreground: #0a0a0a; --card-foreground: #0a0a0a;
--popover: #ffffff; --popover: #ffffff;
--popover-foreground: #0a0a0a; --popover-foreground: #0a0a0a;
--primary: #0b7ad0;
--primary-foreground: #ffffff;
--secondary: #e4e8ef; --secondary: #e4e8ef;
--secondary-foreground: #6a8aa3; --secondary-foreground: #6a8aa3;
--muted: #f5f5f5; --muted: #f5f5f5;
@ -64,14 +77,27 @@
} }
.dark { .dark {
--primary: #125cff;
--primary-foreground: #eff6ff;
--primary-50: #eff6ff;
--primary-100: #dbeafe;
--primary-200: #bfdbfe;
--primary-300: #93c5fd;
--primary-400: #60a5fa;
--primary-500: #3b82f6;
--primary-600: #125cff;
--primary-700: #1d4ed8;
--primary-800: #1e40af;
--primary-900: #1e3a8a;
--primary-950: #172554;
--background: #0a0a0a; --background: #0a0a0a;
--foreground: #fafafa; --foreground: #fafafa;
--card: #171717; --card: #171717;
--card-foreground: #fafafa; --card-foreground: #fafafa;
--popover: #171717; --popover: #171717;
--popover-foreground: #fafafa; --popover-foreground: #fafafa;
--primary: #125cff;
--primary-foreground: #eff6ff;
--secondary: #26262b; --secondary: #26262b;
--secondary-foreground: #fafafa; --secondary-foreground: #fafafa;
--muted: #262626; --muted: #262626;
@ -107,6 +133,18 @@
} }
@theme inline { @theme inline {
--color-primary-50: var(--primary-50);
--color-primary-100: var(--primary-100);
--color-primary-200: var(--primary-200);
--color-primary-300: var(--primary-300);
--color-primary-400: var(--primary-400);
--color-primary-500: var(--primary-500);
--color-primary-600: var(--primary-600);
--color-primary-700: var(--primary-700);
--color-primary-800: var(--primary-800);
--color-primary-900: var(--primary-900);
--color-primary-950: var(--primary-950);
--color-background: var(--background); --color-background: var(--background);
--color-foreground: var(--foreground); --color-foreground: var(--foreground);
--color-card: var(--card); --color-card: var(--card);