Better form control and profile page
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { useState, useRef, useEffect } from "react";
|
||||
import ExcelJS from "exceljs";
|
||||
import { chemicalsApi } from "../lib/api";
|
||||
import { validateCAS, validateNumber, validatePhoneOrEmail } from "../lib/validators";
|
||||
import type { ChemicalInventory } from "../shared/types";
|
||||
import { Card } from "./ui/card";
|
||||
import { Button } from "./ui/button";
|
||||
@@ -199,6 +200,30 @@ export function Inventory() {
|
||||
setFormError("Please fill in all required fields.");
|
||||
return;
|
||||
}
|
||||
if (!validateCAS(String(form.casNumber || ""))) {
|
||||
setFormError("CAS # must be in the format ##-##-# (e.g. 67-56-1).");
|
||||
return;
|
||||
}
|
||||
if (!validateNumber(form.numberOfContainers, { min: 1, integer: true })) {
|
||||
setFormError("# of containers must be a whole number of 1 or more.");
|
||||
return;
|
||||
}
|
||||
if (!validateNumber(form.amountPerContainer, { min: 0 })) {
|
||||
setFormError("Amount per container must be a number.");
|
||||
return;
|
||||
}
|
||||
if (form.molecularWeight && !validateNumber(form.molecularWeight, { min: 0 })) {
|
||||
setFormError("Molecular weight must be a number.");
|
||||
return;
|
||||
}
|
||||
if (form.percentageFull != null && !validateNumber(form.percentageFull, { min: 0, max: 100 })) {
|
||||
setFormError("% full must be between 0 and 100.");
|
||||
return;
|
||||
}
|
||||
if (form.contact && !validatePhoneOrEmail(String(form.contact))) {
|
||||
setFormError("Contact must be a valid phone number or email address.");
|
||||
return;
|
||||
}
|
||||
setFormError("");
|
||||
setIsSaving(true);
|
||||
try {
|
||||
@@ -963,7 +988,14 @@ export function Inventory() {
|
||||
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs">CAS # <span className="text-red-500">*</span></Label>
|
||||
<Input value={form.casNumber || ""} onChange={e => setField("casNumber", e.target.value)} placeholder="e.g. 67-56-1" />
|
||||
<Input
|
||||
value={form.casNumber || ""}
|
||||
onChange={e => setField("casNumber", e.target.value)}
|
||||
placeholder="e.g. 67-56-1"
|
||||
inputMode="numeric"
|
||||
pattern="\d{2,7}-\d{2}-\d"
|
||||
title="CAS format: digits-digits-digit (e.g. 67-56-1)"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-1">
|
||||
@@ -1009,7 +1041,14 @@ export function Inventory() {
|
||||
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs">Amount / Container <span className="text-red-500">*</span></Label>
|
||||
<Input value={form.amountPerContainer || ""} onChange={e => setField("amountPerContainer", e.target.value)} placeholder="e.g. 500" />
|
||||
<Input
|
||||
type="number"
|
||||
min={0}
|
||||
step="any"
|
||||
value={form.amountPerContainer || ""}
|
||||
onChange={e => setField("amountPerContainer", e.target.value)}
|
||||
placeholder="e.g. 500"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="space-y-1 col-span-2">
|
||||
@@ -1045,7 +1084,14 @@ export function Inventory() {
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs">Molecular Weight</Label>
|
||||
<Input value={form.molecularWeight || ""} onChange={e => setField("molecularWeight", e.target.value)} placeholder="g/mol" />
|
||||
<Input
|
||||
type="number"
|
||||
min={0}
|
||||
step="any"
|
||||
value={form.molecularWeight || ""}
|
||||
onChange={e => setField("molecularWeight", e.target.value)}
|
||||
placeholder="g/mol"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs">Concentration</Label>
|
||||
@@ -1077,7 +1123,11 @@ export function Inventory() {
|
||||
</div>
|
||||
<div className="space-y-1">
|
||||
<Label className="text-xs">Contact</Label>
|
||||
<Input value={form.contact || ""} onChange={e => setField("contact", e.target.value)} />
|
||||
<Input
|
||||
value={form.contact || ""}
|
||||
onChange={e => setField("contact", e.target.value)}
|
||||
placeholder="Phone (e.g. 555-123-4567) or email"
|
||||
/>
|
||||
</div>
|
||||
<div className="space-y-1 col-span-2">
|
||||
<Label className="text-xs">Comments</Label>
|
||||
|
||||
Reference in New Issue
Block a user