initialising for ci-cd pipeline
CI/CD - ERP Core / scripts (pull_request) Failing after 12m21s
CI/CD - ERP Core / e2e-typecheck (pull_request) Failing after 13m13s
CI/CD - ERP Core / frontend (pull_request) Failing after 14m5s
CI/CD - ERP Core / backend (pull_request) Failing after 14m57s
CI/CD - ERP Core / detect (pull_request) Failing after 13m42s
CI/CD - ERP Core / Build & Deploy (pull_request) Failing after 12m47s
CI/CD - ERP Core / ci-ok (pull_request) Failing after 14m58s
CI/CD - ERP Core / scripts (pull_request) Failing after 12m21s
CI/CD - ERP Core / e2e-typecheck (pull_request) Failing after 13m13s
CI/CD - ERP Core / frontend (pull_request) Failing after 14m5s
CI/CD - ERP Core / backend (pull_request) Failing after 14m57s
CI/CD - ERP Core / detect (pull_request) Failing after 13m42s
CI/CD - ERP Core / Build & Deploy (pull_request) Failing after 12m47s
CI/CD - ERP Core / ci-ok (pull_request) Failing after 14m58s
This commit is contained in:
@@ -112,6 +112,17 @@ function NewPurchaseInvoiceContent() {
|
||||
[vendors]
|
||||
)
|
||||
|
||||
// Deep-linked from a GRN detail page's "Create Purchase Invoice" prompt — that GRN is the
|
||||
// whole reason this page was opened, so show only it rather than the vendor's full eligible
|
||||
// list (which could pull in unrelated GRNs the user never meant to consolidate here).
|
||||
// Declared before toggleAll, which reads it: referencing it ahead of its declaration stopped
|
||||
// the React Compiler from preserving this memo (react-hooks/preserve-manual-memoization).
|
||||
const deepLinkedGrnId = grnIdFromQuery ? Number(grnIdFromQuery) : null
|
||||
const visibleGrns = useMemo(
|
||||
() => (deepLinkedGrnId === null ? (eligibleGrns ?? []) : (eligibleGrns ?? []).filter((g) => g.grnId === deepLinkedGrnId)),
|
||||
[eligibleGrns, deepLinkedGrnId]
|
||||
)
|
||||
|
||||
function toggleGrn(grnId: number, checked: boolean) {
|
||||
setSelectedGrnIds((prev) => {
|
||||
const next = new Set(prev)
|
||||
@@ -125,15 +136,6 @@ function NewPurchaseInvoiceContent() {
|
||||
setSelectedGrnIds(checked ? new Set(visibleGrns.map((g) => g.grnId)) : new Set())
|
||||
}
|
||||
|
||||
// Deep-linked from a GRN detail page's "Create Purchase Invoice" prompt — that GRN is the
|
||||
// whole reason this page was opened, so show only it rather than the vendor's full eligible
|
||||
// list (which could pull in unrelated GRNs the user never meant to consolidate here).
|
||||
const deepLinkedGrnId = grnIdFromQuery ? Number(grnIdFromQuery) : null
|
||||
const visibleGrns = useMemo(
|
||||
() => (deepLinkedGrnId === null ? (eligibleGrns ?? []) : (eligibleGrns ?? []).filter((g) => g.grnId === deepLinkedGrnId)),
|
||||
[eligibleGrns, deepLinkedGrnId]
|
||||
)
|
||||
|
||||
const selectedGrns = useMemo(
|
||||
() => (eligibleGrns ?? []).filter((g) => selectedGrnIds.has(g.grnId)),
|
||||
[eligibleGrns, selectedGrnIds]
|
||||
|
||||
@@ -88,7 +88,7 @@ export default function SalesDayEndPage() {
|
||||
<div>
|
||||
<h1 className="text-2xl font-bold text-foreground">Day End</h1>
|
||||
<p className="text-base text-muted-foreground">
|
||||
Close a cashier's business day — locks their posted sales slips and bundle sales, and posts one consolidated journal entry to the ledger.
|
||||
Close a cashier's business day — locks their posted sales slips and bundle sales, and posts one consolidated journal entry to the ledger.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -149,14 +149,14 @@ export default function InvoiceTemplatePage() {
|
||||
<Switch checked={showBankDetails} onCheckedChange={setShowBankDetails} className="mt-1 shrink-0" aria-label="Show bank details" />
|
||||
<div className="flex flex-col gap-1">
|
||||
<span className="text-base font-medium text-foreground">Show bank details</span>
|
||||
<span className="text-sm text-muted-foreground">Prints the company's bank name, account and SWIFT code on invoices.</span>
|
||||
<span className="text-sm text-muted-foreground">Prints the company's bank name, account and SWIFT code on invoices.</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex items-start gap-4 py-4">
|
||||
<Switch checked={showTaxRegNo} onCheckedChange={setShowTaxRegNo} className="mt-1 shrink-0" aria-label="Show tax registration no." />
|
||||
<div className="flex flex-col gap-1">
|
||||
<span className="text-base font-medium text-foreground">Show tax registration no.</span>
|
||||
<span className="text-sm text-muted-foreground">Prints the company's tax registration number in the invoice header.</span>
|
||||
<span className="text-sm text-muted-foreground">Prints the company's tax registration number in the invoice header.</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -32,7 +32,7 @@ export default function ForgotOtpPage() {
|
||||
</div>
|
||||
<h1 className="text-2xl font-bold text-foreground text-center">Verify your email</h1>
|
||||
</div>
|
||||
<p className="text-sm text-muted-foreground text-center mb-8">We've sent a verification code to your email address. Enter it below to continue.</p>
|
||||
<p className="text-sm text-muted-foreground text-center mb-8">We've sent a verification code to your email address. Enter it below to continue.</p>
|
||||
|
||||
<div className="space-y-6">
|
||||
<div className="flex justify-center">
|
||||
@@ -48,7 +48,7 @@ export default function ForgotOtpPage() {
|
||||
}}
|
||||
className="text-sm font-medium text-foreground hover:text-foreground/80 transition-colors"
|
||||
>
|
||||
Didn't receive the code? Resend
|
||||
Didn't receive the code? Resend
|
||||
</button>
|
||||
) : (
|
||||
<p className="text-sm text-muted-foreground">Resend code available in <span className="font-semibold text-foreground">{Math.max(0, secondsLeft)}s</span></p>
|
||||
|
||||
@@ -22,7 +22,7 @@ export default function ForgotEmailPage() {
|
||||
<div className="w-full max-w-2xl rounded-xl bg-card p-8 pl-10 shadow-lg border border-border">
|
||||
<div className="mb-8 text-center">
|
||||
<h1 className="text-2xl font-bold text-foreground">Reset your password</h1>
|
||||
<p className="mt-2 text-sm text-muted-foreground">Enter the email address associated with your account and we'll send you a one-time code to verify your identity.</p>
|
||||
<p className="mt-2 text-sm text-muted-foreground">Enter the email address associated with your account and we'll send you a one-time code to verify your identity.</p>
|
||||
</div>
|
||||
|
||||
<div className="space-y-6">
|
||||
|
||||
@@ -13,6 +13,19 @@ import {
|
||||
} from "@/components/ui/dialog"
|
||||
import { Check, Eye, EyeOff } from "lucide-react"
|
||||
|
||||
// Declared at module scope: a component defined inside the page body is a new type on every
|
||||
// render, so React would remount (and reset) each requirement row on each keystroke.
|
||||
function PasswordRequirement({ met, label }: { met: boolean; label: string }) {
|
||||
return (
|
||||
<div className="flex items-center gap-3">
|
||||
<div className={`flex items-center justify-center w-5 h-5 rounded-full shrink-0 text-sm font-semibold ${met ? 'bg-success/10 text-success' : 'bg-muted text-muted-foreground'}`}>
|
||||
{met ? <Check className="size-4" /> : <span>○</span>}
|
||||
</div>
|
||||
<span className={`text-sm ${met ? 'text-foreground font-medium' : 'text-muted-foreground'}`}>{label}</span>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default function ForgotResetPage() {
|
||||
const router = useRouter()
|
||||
const [password, setPassword] = useState("")
|
||||
@@ -28,15 +41,6 @@ export default function ForgotResetPage() {
|
||||
const passwordsMatch = password === confirm && password.length > 0
|
||||
const allValid = meetsLength && hasUpper && hasNumber && hasSpecial && passwordsMatch
|
||||
|
||||
const PasswordRequirement = ({ met, label }: { met: boolean; label: string }) => (
|
||||
<div className="flex items-center gap-3">
|
||||
<div className={`flex items-center justify-center w-5 h-5 rounded-full shrink-0 text-sm font-semibold ${met ? 'bg-success/10 text-success' : 'bg-muted text-muted-foreground'}`}>
|
||||
{met ? <Check className="size-4" /> : <span>○</span>}
|
||||
</div>
|
||||
<span className={`text-sm ${met ? 'text-foreground font-medium' : 'text-muted-foreground'}`}>{label}</span>
|
||||
</div>
|
||||
)
|
||||
|
||||
return (
|
||||
<div className="min-h-screen flex items-center justify-center bg-gradient-to-br from-background to-background/95 p-4">
|
||||
<div className="w-full max-w-xl rounded-xl bg-card p-8 shadow-lg border border-border">
|
||||
@@ -97,7 +101,7 @@ export default function ForgotResetPage() {
|
||||
</div>
|
||||
|
||||
{!passwordsMatch && confirm.length > 0 && (
|
||||
<p className="text-sm text-error font-medium">Passwords don't match.</p>
|
||||
<p className="text-sm text-error font-medium">Passwords don't match.</p>
|
||||
)}
|
||||
|
||||
<div className="flex gap-3">
|
||||
|
||||
Reference in New Issue
Block a user