.
This commit is contained in:
parent
1beaa05fa4
commit
c91455ffc2
1
.vscode/launch.json
vendored
1
.vscode/launch.json
vendored
@ -1,5 +1,4 @@
|
||||
{
|
||||
"version": "0.6.2",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "WEB: Vite (Chrome)",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@erp/factuges-server",
|
||||
"version": "0.6.2",
|
||||
"version": "0.6.3",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"build": "tsup src/index.ts --config tsup.config.ts",
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@erp/factuges-web",
|
||||
"private": true,
|
||||
"version": "0.6.2",
|
||||
"version": "0.6.3",
|
||||
"type": "module",
|
||||
"scripts": {
|
||||
"dev": "vite --host --clearScreen false",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@erp/auth",
|
||||
"version": "0.6.2",
|
||||
"version": "0.6.3",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@erp/core",
|
||||
"version": "0.6.2",
|
||||
"version": "0.6.3",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@erp/customer-invoices",
|
||||
"version": "0.6.2",
|
||||
"version": "0.6.3",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -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 { DateHelper } from "@repo/rdx-utils";
|
||||
|
||||
import type { IIssuedInvoiceFullSnapshot } from "../full";
|
||||
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import { NumberHelper } from "@erp/core";
|
||||
import { DiscountPercentage } from "@erp/core/api";
|
||||
import {
|
||||
CurrencyCode,
|
||||
@ -12,7 +11,7 @@ import {
|
||||
extractOrPushError,
|
||||
maybeFromNullableResult,
|
||||
} 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 {
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import { NumberHelper } from "@erp/core";
|
||||
import { DiscountPercentage } from "@erp/core/api";
|
||||
import {
|
||||
CurrencyCode,
|
||||
@ -12,7 +11,7 @@ import {
|
||||
extractOrPushError,
|
||||
maybeFromNullableResult,
|
||||
} 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 {
|
||||
|
||||
@ -2,7 +2,7 @@ import type { UniqueID } from "@repo/rdx-ddd";
|
||||
import type { Result } from "@repo/rdx-utils";
|
||||
|
||||
import type { Proforma } from "../../../domain/proformas";
|
||||
import type { IProformaFullSnapshot } from "../snapshot-builders";
|
||||
import type { ProformaFullSnapshot } from "../snapshot-builders";
|
||||
|
||||
import type { IProformaCreatorParams } from "./proforma-creator";
|
||||
|
||||
@ -35,7 +35,7 @@ export interface IProformaPublicServices {
|
||||
getProformaSnapshotById: (
|
||||
id: UniqueID,
|
||||
context: IProformaServicesContext
|
||||
) => Promise<Result<IProformaFullSnapshot, Error>>;
|
||||
) => Promise<Result<ProformaFullSnapshot, Error>>;
|
||||
|
||||
generateProformaReport: (id: unknown, options: unknown, context: unknown) => null;
|
||||
}
|
||||
|
||||
@ -8,8 +8,10 @@ import type { IProformaItemsFullSnapshotBuilder } from "./proforma-items-full-sn
|
||||
import type { IProformaRecipientFullSnapshotBuilder } from "./proforma-recipient-full-snapshot-builder";
|
||||
import type { IProformaTaxesFullSnapshotBuilder } from "./proforma-taxes-full-snapshot-builder";
|
||||
|
||||
export type ProformaFullSnapshot = GetProformaByIdResponseDTO;
|
||||
|
||||
export interface IProformaFullSnapshotBuilder
|
||||
extends ISnapshotBuilder<Proforma, GetProformaByIdResponseDTO> {}
|
||||
extends ISnapshotBuilder<Proforma, ProformaFullSnapshot> {}
|
||||
|
||||
export class ProformaFullSnapshotBuilder implements IProformaFullSnapshotBuilder {
|
||||
constructor(
|
||||
@ -19,7 +21,7 @@ export class ProformaFullSnapshotBuilder implements IProformaFullSnapshotBuilder
|
||||
//private readonly paymentMethodBuilder: IProformaPaymentMethodFullSnapshotBuilder
|
||||
) {}
|
||||
|
||||
toOutput(proforma: Proforma): GetProformaByIdResponseDTO {
|
||||
toOutput(proforma: Proforma): ProformaFullSnapshot {
|
||||
const items = this.itemsBuilder.toOutput(proforma.items);
|
||||
const recipient = this.recipientBuilder.toOutput(proforma);
|
||||
const taxes = this.taxesBuilder.toOutput(proforma.taxes());
|
||||
@ -37,7 +39,7 @@ export class ProformaFullSnapshotBuilder implements IProformaFullSnapshotBuilder
|
||||
company_id: proforma.companyId.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()),
|
||||
|
||||
invoice_date: proforma.invoiceDate.toDateString(),
|
||||
|
||||
@ -1,16 +1,16 @@
|
||||
import { MoneyDTOHelper, PercentageDTOHelper, QuantityDTOHelper } from "@erp/core";
|
||||
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";
|
||||
|
||||
export interface IProformaItemReportSnapshotBuilder
|
||||
extends ISnapshotBuilder<IProformaFullSnapshot["items"], ProformaReportItemSnapshot[]> {}
|
||||
extends ISnapshotBuilder<ProformaFullSnapshot["items"], ProformaReportItemSnapshot[]> {}
|
||||
|
||||
export class ProformaItemReportSnapshotBuilder implements IProformaItemReportSnapshotBuilder {
|
||||
toOutput(
|
||||
items: IProformaFullSnapshot["items"],
|
||||
items: ProformaFullSnapshot["items"],
|
||||
params?: ISnapshotBuilderParams
|
||||
): ProformaReportItemSnapshot[] {
|
||||
const locale = params?.locale as string;
|
||||
|
||||
@ -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 { 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 { ProformaReportSnapshot } from "./proforma-report-snapshot.interface";
|
||||
import type { ProformaReportTaxSnapshot } from "./proforma-report-tax-snapshot.interface";
|
||||
|
||||
export interface IProformaReportSnapshotBuilder
|
||||
extends ISnapshotBuilder<IProformaFullSnapshot, ProformaReportSnapshot> {}
|
||||
extends ISnapshotBuilder<ProformaFullSnapshot, ProformaReportSnapshot> {}
|
||||
|
||||
export class ProformaReportSnapshotBuilder implements IProformaReportSnapshotBuilder {
|
||||
constructor(
|
||||
private readonly itemsBuilder: ISnapshotBuilder<
|
||||
IProformaFullSnapshot["items"],
|
||||
ProformaFullSnapshot["items"],
|
||||
ProformaReportItemSnapshot[]
|
||||
>,
|
||||
private readonly taxesBuilder: ISnapshotBuilder<
|
||||
IProformaFullSnapshot["taxes"],
|
||||
ProformaFullSnapshot["taxes"],
|
||||
ProformaReportTaxSnapshot[]
|
||||
>
|
||||
) {}
|
||||
|
||||
toOutput(
|
||||
snapshot: IProformaFullSnapshot,
|
||||
snapshot: ProformaFullSnapshot,
|
||||
params?: ISnapshotBuilderParams
|
||||
): ProformaReportSnapshot {
|
||||
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[] = [];
|
||||
|
||||
if (recipient.street) lines.push(recipient.street);
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
import { DateHelper, MoneyDTOHelper, PercentageDTOHelper } from "@erp/core";
|
||||
import { MoneyDTOHelper, PercentageDTOHelper } from "@erp/core";
|
||||
import { Presenter } from "@erp/core/api";
|
||||
import { DateHelper } from "@repo/rdx-utils";
|
||||
|
||||
import type { GetIssuedInvoiceByIdResponseDTO } from "../../../../../common/dto";
|
||||
|
||||
|
||||
@ -47,28 +47,26 @@ export class ProformaItemsTotalsCalculator {
|
||||
const amounts = item.totals();
|
||||
|
||||
// Subtotales
|
||||
subtotalAmount = subtotalAmount.add(amounts.subtotalAmount.roundUsingScale(2));
|
||||
subtotalAmount = subtotalAmount.add(amounts.subtotalAmount);
|
||||
|
||||
// Descuentos
|
||||
itemDiscountAmount = itemDiscountAmount.add(amounts.itemDiscountAmount.roundUsingScale(2));
|
||||
globalDiscountAmount = globalDiscountAmount.add(
|
||||
amounts.globalDiscountAmount.roundUsingScale(2)
|
||||
);
|
||||
totalDiscountAmount = totalDiscountAmount.add(amounts.totalDiscountAmount.roundUsingScale(2));
|
||||
itemDiscountAmount = itemDiscountAmount.add(amounts.itemDiscountAmount);
|
||||
globalDiscountAmount = globalDiscountAmount.add(amounts.globalDiscountAmount);
|
||||
totalDiscountAmount = totalDiscountAmount.add(amounts.totalDiscountAmount);
|
||||
|
||||
// Base imponible
|
||||
taxableAmount = taxableAmount.add(amounts.taxableAmount.roundUsingScale(2));
|
||||
taxableAmount = taxableAmount.add(amounts.taxableAmount);
|
||||
|
||||
// Impuestos individuales
|
||||
ivaAmount = ivaAmount.add(amounts.ivaAmount.roundUsingScale(2));
|
||||
recAmount = recAmount.add(amounts.recAmount.roundUsingScale(2));
|
||||
retentionAmount = retentionAmount.add(amounts.retentionAmount.roundUsingScale(2));
|
||||
ivaAmount = ivaAmount.add(amounts.ivaAmount);
|
||||
recAmount = recAmount.add(amounts.recAmount);
|
||||
retentionAmount = retentionAmount.add(amounts.retentionAmount);
|
||||
|
||||
// Total impuestos del ítem
|
||||
taxesAmount = taxesAmount.add(amounts.taxesAmount.roundUsingScale(2));
|
||||
taxesAmount = taxesAmount.add(amounts.taxesAmount);
|
||||
|
||||
// Total final del ítem
|
||||
totalAmount = totalAmount.add(amounts.totalAmount.roundUsingScale(2));
|
||||
totalAmount = totalAmount.add(amounts.totalAmount);
|
||||
}
|
||||
|
||||
return {
|
||||
|
||||
@ -37,6 +37,7 @@ export class ProformaTaxesCalculator {
|
||||
const ivaAmount = this.toInvoiceAmount(g.ivaAmount);
|
||||
const recAmount = this.toInvoiceAmount(g.recAmount);
|
||||
const retentionAmount = this.toInvoiceAmount(g.retentionAmount);
|
||||
//const taxesAmount = this.toInvoiceAmount(g.taxesAmount);
|
||||
|
||||
const taxesAmount = ivaAmount.add(recAmount).subtract(retentionAmount);
|
||||
|
||||
|
||||
@ -5,7 +5,7 @@ import type { Transaction } from "sequelize";
|
||||
|
||||
import {
|
||||
type IProformaCreatorParams,
|
||||
type IProformaFullSnapshot,
|
||||
type ProformaFullSnapshot,
|
||||
buildProformaCreator,
|
||||
buildProformaFinder,
|
||||
buildProformaSnapshotBuilders,
|
||||
@ -36,7 +36,7 @@ export type ProformaPublicServices = {
|
||||
getProformaSnapshotById: (
|
||||
id: UniqueID,
|
||||
context: ProformaServicesContext
|
||||
) => Promise<Result<IProformaFullSnapshot, Error>>;
|
||||
) => Promise<Result<ProformaFullSnapshot, Error>>;
|
||||
|
||||
createProforma: (
|
||||
id: UniqueID,
|
||||
|
||||
@ -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>
|
||||
);
|
||||
};
|
||||
@ -14,6 +14,7 @@ import type {
|
||||
} from "../../controllers";
|
||||
import { ProformaTotalsSummary } from "../blocks";
|
||||
|
||||
import { ProformaTaxesCard } from "./proforma-taxes-card";
|
||||
import { ProformaUpdateHeaderEditor } from "./proforma-update-header-editor";
|
||||
import { ProformaUpdateItemsEditor } from "./proforma-update-items-editor";
|
||||
import { ProformaUpdateTaxEditor } from "./proforma-update-tax-editor";
|
||||
@ -74,6 +75,10 @@ export const ProformaUpdateEditorForm = ({
|
||||
|
||||
<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">
|
||||
<ProformaUpdateTaxEditor className="md:col-span-6" taxCtrl={taxCtrl} />
|
||||
<ProformaTotalsSummary
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@erp/customers",
|
||||
"description": "Customers",
|
||||
"version": "0.6.2",
|
||||
"version": "0.6.3",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@erp/factuges",
|
||||
"version": "0.6.2",
|
||||
"version": "0.6.3",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@erp/supplier-invoices",
|
||||
"description": "Supplier invoices",
|
||||
"version": "0.6.2",
|
||||
"version": "0.6.3",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "@erp/suppliers",
|
||||
"description": "Suppliers",
|
||||
"version": "0.6.2",
|
||||
"version": "0.6.3",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "uecko-erp-2025",
|
||||
"private": true,
|
||||
"version": "0.6.2",
|
||||
"version": "0.6.3",
|
||||
"workspaces": [
|
||||
"apps/*",
|
||||
"modules/*",
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@repo/rdx-criteria",
|
||||
"version": "0.6.2",
|
||||
"version": "0.6.3",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@repo/rdx-ddd",
|
||||
"version": "0.6.2",
|
||||
"version": "0.6.3",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@repo/rdx-logger",
|
||||
"version": "0.6.2",
|
||||
"version": "0.6.3",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@repo/rdx-ui",
|
||||
"version": "0.6.2",
|
||||
"version": "0.6.3",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -1,10 +1,9 @@
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
FieldDescription,
|
||||
FieldLegend,
|
||||
FieldSet,
|
||||
CardTitle,
|
||||
} from "@repo/shadcn-ui/components";
|
||||
import { cn } from "@repo/shadcn-ui/lib/utils";
|
||||
import type { ReactNode } from "react";
|
||||
@ -34,32 +33,30 @@ export const FormSectionCard = ({
|
||||
|
||||
return (
|
||||
<Card className={className}>
|
||||
<FieldSet disabled={disabled}>
|
||||
<CardHeader className={headerClassName}>
|
||||
<div className="flex items-start gap-3">
|
||||
{icon ? (
|
||||
<div
|
||||
className={cn(
|
||||
"flex size-12 shrink-0 items-center justify-center rounded-md",
|
||||
disabled ? "bg-muted text-muted-foreground" : "bg-primary/10 text-primary"
|
||||
)}
|
||||
>
|
||||
{" "}
|
||||
{icon}{" "}
|
||||
</div>
|
||||
) : null}
|
||||
|
||||
<div className="space-y-1">
|
||||
{title ? <FieldLegend className="font-semibold">{title}</FieldLegend> : null}
|
||||
{description ? (
|
||||
<FieldDescription className="font-medium">{description}</FieldDescription>
|
||||
) : null}
|
||||
<CardHeader className={headerClassName}>
|
||||
<div className="flex items-start gap-3">
|
||||
{icon ? (
|
||||
<div
|
||||
className={cn(
|
||||
"flex size-12 shrink-0 items-center justify-center rounded-md",
|
||||
disabled ? "bg-muted text-muted-foreground" : "bg-primary/10 text-primary"
|
||||
)}
|
||||
>
|
||||
{" "}
|
||||
{icon}{" "}
|
||||
</div>
|
||||
</div>
|
||||
</CardHeader>
|
||||
) : null}
|
||||
|
||||
<CardContent className={contentClassName}>{children}</CardContent>
|
||||
</FieldSet>
|
||||
<div className="space-y-1">
|
||||
{title ? <CardTitle className="font-semibold">{title}</CardTitle> : null}
|
||||
{description ? (
|
||||
<CardDescription className="font-medium">{description}</CardDescription>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
</CardHeader>
|
||||
|
||||
<CardContent className={contentClassName}>{children}</CardContent>
|
||||
</Card>
|
||||
);
|
||||
};
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@repo/rdx-utils",
|
||||
"version": "0.6.2",
|
||||
"version": "0.6.3",
|
||||
"private": true,
|
||||
"type": "module",
|
||||
"sideEffects": false,
|
||||
|
||||
@ -13,14 +13,27 @@
|
||||
@source "../**/*.{ts,tsx}";
|
||||
|
||||
: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;
|
||||
--foreground: #0a0a0a;
|
||||
--card: #ffffff;
|
||||
--card-foreground: #0a0a0a;
|
||||
--popover: #ffffff;
|
||||
--popover-foreground: #0a0a0a;
|
||||
--primary: #0b7ad0;
|
||||
--primary-foreground: #ffffff;
|
||||
--secondary: #e4e8ef;
|
||||
--secondary-foreground: #6a8aa3;
|
||||
--muted: #f5f5f5;
|
||||
@ -64,14 +77,27 @@
|
||||
}
|
||||
|
||||
.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;
|
||||
--foreground: #fafafa;
|
||||
--card: #171717;
|
||||
--card-foreground: #fafafa;
|
||||
--popover: #171717;
|
||||
--popover-foreground: #fafafa;
|
||||
--primary: #125cff;
|
||||
--primary-foreground: #eff6ff;
|
||||
--secondary: #26262b;
|
||||
--secondary-foreground: #fafafa;
|
||||
--muted: #262626;
|
||||
@ -107,6 +133,18 @@
|
||||
}
|
||||
|
||||
@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-foreground: var(--foreground);
|
||||
--color-card: var(--card);
|
||||
|
||||
Binary file not shown.
Binary file not shown.
Loading…
Reference in New Issue
Block a user