@apptimate/ui 2.7.0 → 2.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@apptimate/ui",
3
- "version": "2.7.0",
3
+ "version": "2.9.0",
4
4
  "main": "src/index.tsx",
5
5
  "types": "src/index.tsx",
6
6
  "dependencies": {
@@ -113,9 +113,9 @@ export function DashboardLayout({
113
113
  : 'Select Org';
114
114
 
115
115
  return (
116
- <div className="flex h-screen bg-[#F4F5F7] overflow-hidden font-sans">
116
+ <div className="flex h-screen bg-[#F4F5F7] overflow-hidden font-sans print:h-auto print:overflow-visible print:bg-white">
117
117
  {/* Desktop Global Sidebar */}
118
- <aside className="hidden md:flex w-[80px] bg-white border-r border-gray-200 flex-col items-center py-6 shrink-0 z-20">
118
+ <aside className="hidden md:flex print:hidden w-[80px] bg-white border-r border-gray-200 flex-col items-center py-6 shrink-0 z-20">
119
119
  <div className="w-12 h-12 flex items-center justify-center mb-8">
120
120
  {logo}
121
121
  </div>
@@ -173,7 +173,7 @@ export function DashboardLayout({
173
173
 
174
174
  {/* Desktop Secondary Sidebar */}
175
175
  {activeMenu && activeMenu.groups.length > 0 && (
176
- <aside className="hidden md:flex w-[210px] bg-white border-gray-200 flex-col py-8 shrink-0 z-10">
176
+ <aside className="hidden md:flex print:hidden w-[210px] bg-white border-gray-200 flex-col py-8 shrink-0 z-10">
177
177
  <h2 className="px-6 text-xl font-bold text-[#2D3142]/80 mb-6">{activeMenu.label}</h2>
178
178
  <div className="flex-1 overflow-y-auto px-4 space-y-6">
179
179
  {activeMenu.groups.map((group) => (
@@ -234,9 +234,9 @@ export function DashboardLayout({
234
234
  )}
235
235
 
236
236
  {/* Main Content Area & Mobile Header */}
237
- <div className="flex-1 flex flex-col min-w-0 overflow-hidden">
237
+ <div className="flex-1 flex flex-col min-w-0 overflow-hidden print:overflow-visible">
238
238
  {/* Mobile Header */}
239
- <header className="md:hidden flex items-center justify-between p-4 bg-white border-b border-gray-200 shrink-0 z-10">
239
+ <header className="md:hidden print:hidden flex items-center justify-between p-4 bg-white border-b border-gray-200 shrink-0 z-10">
240
240
  <div className="flex items-center justify-center w-8 h-8">
241
241
  {logo}
242
242
  </div>
@@ -267,8 +267,8 @@ export function DashboardLayout({
267
267
  </header>
268
268
 
269
269
  {/* Main Content Scrollable Area */}
270
- <main className="flex-1 p-4 md:p-6 lg:p-8 overflow-hidden min-h-0">
271
- <div className="bg-white rounded-2xl h-full p-4 md:p-8 flex flex-col overflow-y-auto">
270
+ <main className="flex-1 p-4 md:p-6 lg:p-8 overflow-hidden min-h-0 print:overflow-visible print:p-0">
271
+ <div className="bg-white rounded-2xl h-full p-4 md:p-8 flex flex-col overflow-y-auto print:h-auto print:overflow-visible print:p-0 print:bg-transparent print:rounded-none">
272
272
  {children}
273
273
  </div>
274
274
  </main>
@@ -1,6 +1,6 @@
1
1
  "use client";
2
2
 
3
- import React, { useState, useEffect, useCallback, useMemo } from "react";
3
+ import React, { useState, useEffect, useCallback, useMemo, useRef } from "react";
4
4
  import { cn } from "@apptimate/core-lib";
5
5
  import { CreditCard, Banknote, Building, Trash2, Loader2, Split, Check, AlertCircle } from "lucide-react";
6
6
 
@@ -70,6 +70,12 @@ export function PaymentSection({ totalAmount, payments, onPaymentsChange, compac
70
70
  const [bankAccounts, setBankAccounts] = useState<BankAccount[]>([]);
71
71
  const [isLoading, setIsLoading] = useState(false);
72
72
  const [selectionMode, setSelectionMode] = useState<"single" | "split">("single");
73
+ const paymentsRef = useRef(payments);
74
+
75
+ // Keep ref in sync
76
+ useEffect(() => {
77
+ paymentsRef.current = payments;
78
+ }, [payments]);
73
79
 
74
80
  // ── Load payment modes on mount ──
75
81
  useEffect(() => {
@@ -84,7 +90,7 @@ export function PaymentSection({ totalAmount, payments, onPaymentsChange, compac
84
90
  if (bankRes.is_success) setBankAccounts(bankRes.result || []);
85
91
 
86
92
  // Auto-select cash if no payments yet
87
- if (payments.length === 0 && modes.length > 0) {
93
+ if (paymentsRef.current.length === 0 && modes.length > 0) {
88
94
  const cashMode = modes.find((m) => m.code === "cash" && m.is_active);
89
95
  if (cashMode) {
90
96
  onPaymentsChange([{
@@ -92,12 +98,21 @@ export function PaymentSection({ totalAmount, payments, onPaymentsChange, compac
92
98
  amount: totalAmount, metadata: {},
93
99
  }]);
94
100
  }
101
+ } else if (paymentsRef.current.length > 1) {
102
+ setSelectionMode("split");
95
103
  }
96
104
  } finally { setIsLoading(false); }
97
105
  };
98
106
  load();
99
107
  }, []);
100
108
 
109
+ // Also sync selectionMode if payments change from outside
110
+ useEffect(() => {
111
+ if (payments.length > 1 && selectionMode === "single") {
112
+ setSelectionMode("split");
113
+ }
114
+ }, [payments.length, selectionMode]);
115
+
101
116
  // ── Calculations ──
102
117
  const isCreditPayment = useCallback((payment: PaymentEntry) => payment.mode_code === "credit", []);
103
118
  const totalPaid = useMemo(() => payments.reduce((s, p) => s + (isCreditPayment(p) ? 0 : p.amount), 0), [payments, isCreditPayment]);