Skip to content

Commit 093d7e2

Browse files
committed
fix zod validation & don't write empty values when parsing
1 parent e66414d commit 093d7e2

File tree

2 files changed

+28
-83
lines changed

2 files changed

+28
-83
lines changed

src/components/server.tsx

Lines changed: 16 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,8 @@ const serverFormSchema = z.object({
7474
const obj = JSON.parse(s)
7575
return PublicNoteSchema.safeParse(obj).success
7676
} catch {
77-
return false
77+
// skip check if not JSON
78+
return true
7879
}
7980
},
8081
{ message: "Invalid Public Note JSON" },
@@ -209,26 +210,12 @@ export const ServerCard: React.FC<ServerCardProps> = ({ data, mutate }) => {
209210
const bd = publicNoteObj.billingDataMod
210211
const pd = publicNoteObj.planDataMod
211212
const pnNormalized: PublicNote = {
212-
billingDataMod: bd
213-
? {
214-
autoRenewal: bd.autoRenewal ?? "",
215-
cycle: bd.cycle ?? "",
216-
amount: bd.amount ?? "",
217-
startDate: normalizeISO(bd.startDate),
218-
endDate: normalizeISO(bd.endDate),
219-
}
220-
: undefined,
221-
planDataMod: pd
222-
? {
223-
bandwidth: pd.bandwidth ?? "",
224-
trafficVol: pd.trafficVol ?? "",
225-
trafficType: pd.trafficType ?? "",
226-
IPv4: pd.IPv4 ?? "0",
227-
IPv6: pd.IPv6 ?? "0",
228-
networkRoute: pd.networkRoute ?? "",
229-
extra: pd.extra ?? "",
230-
}
231-
: undefined,
213+
billingDataMod: bd && {
214+
...bd,
215+
startDate: normalizeISO(bd.startDate),
216+
endDate: normalizeISO(bd.endDate),
217+
},
218+
planDataMod: pd,
232219
}
233220
const jsonStr = JSON.stringify(pnNormalized)
234221
values.public_note = jsonStr.length > 2 ? jsonStr : undefined
@@ -672,7 +659,7 @@ export const ServerCard: React.FC<ServerCardProps> = ({ data, mutate }) => {
672659
onCheckedChange={(checked) =>
673660
patchPublicNote(
674661
"billingDataMod.autoRenewal",
675-
checked ? "1" : "0",
662+
checked ? "1" : undefined,
676663
)
677664
}
678665
/>
@@ -705,7 +692,7 @@ export const ServerCard: React.FC<ServerCardProps> = ({ data, mutate }) => {
705692
onClick={() =>
706693
patchPublicNote(
707694
"billingDataMod.cycle",
708-
"",
695+
undefined,
709696
)
710697
}
711698
>
@@ -720,8 +707,7 @@ export const ServerCard: React.FC<ServerCardProps> = ({ data, mutate }) => {
720707
)
721708
}
722709
value={
723-
publicNoteObj.billingDataMod
724-
?.cycle ?? ""
710+
publicNoteObj.billingDataMod?.cycle
725711
}
726712
>
727713
<SelectTrigger>
@@ -760,7 +746,7 @@ export const ServerCard: React.FC<ServerCardProps> = ({ data, mutate }) => {
760746
onClick={() =>
761747
patchPublicNote(
762748
"billingDataMod.amount",
763-
"0",
749+
undefined,
764750
)
765751
}
766752
>
@@ -783,8 +769,7 @@ export const ServerCard: React.FC<ServerCardProps> = ({ data, mutate }) => {
783769
<Input
784770
placeholder="200EUR"
785771
value={
786-
publicNoteObj.billingDataMod
787-
?.amount ?? ""
772+
publicNoteObj.billingDataMod?.amount
788773
}
789774
onChange={(e) =>
790775
patchPublicNote(
@@ -809,8 +794,7 @@ export const ServerCard: React.FC<ServerCardProps> = ({ data, mutate }) => {
809794
<Input
810795
placeholder="30Mbps"
811796
value={
812-
publicNoteObj.planDataMod
813-
?.bandwidth ?? ""
797+
publicNoteObj.planDataMod?.bandwidth
814798
}
815799
onChange={(e) =>
816800
patchPublicNote(
@@ -828,7 +812,7 @@ export const ServerCard: React.FC<ServerCardProps> = ({ data, mutate }) => {
828812
placeholder="1TB/Month"
829813
value={
830814
publicNoteObj.planDataMod
831-
?.trafficVol ?? ""
815+
?.trafficVol
832816
}
833817
onChange={(e) =>
834818
patchPublicNote(
@@ -850,7 +834,7 @@ export const ServerCard: React.FC<ServerCardProps> = ({ data, mutate }) => {
850834
onClick={() =>
851835
patchPublicNote(
852836
"planDataMod.trafficType",
853-
"",
837+
undefined,
854838
)
855839
}
856840
>

src/lib/public-note.ts

Lines changed: 12 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -15,44 +15,27 @@ export const PublicNoteSchema = z.object({
1515
.object({
1616
startDate: z.string().optional(),
1717
endDate: z.string().optional(),
18-
autoRenewal: z.string().optional().default(""),
19-
cycle: z.string().optional().default(""),
20-
amount: z.string().optional().default(""),
18+
autoRenewal: z.string().optional(),
19+
cycle: z.string().optional(),
20+
amount: z.string().optional(),
2121
})
2222
.optional(),
2323
planDataMod: z
2424
.object({
25-
bandwidth: z.string().optional().default(""),
26-
trafficVol: z.string().optional().default(""),
27-
trafficType: z.string().optional().default(""),
28-
IPv4: z.string().optional().default("0"),
29-
IPv6: z.string().optional().default("0"),
30-
networkRoute: z.string().optional().default(""),
31-
extra: z.string().optional().default(""),
25+
bandwidth: z.string().optional(),
26+
trafficVol: z.string().optional(),
27+
trafficType: z.string().optional(),
28+
IPv4: z.string().optional(),
29+
IPv6: z.string().optional(),
30+
networkRoute: z.string().optional(),
31+
extra: z.string().optional(),
3232
})
3333
.optional(),
3434
})
3535

3636
export type PublicNote = z.infer<typeof PublicNoteSchema>
3737

38-
export const defaultPublicNote: PublicNote = {
39-
billingDataMod: {
40-
startDate: "",
41-
endDate: "",
42-
autoRenewal: "",
43-
cycle: "",
44-
amount: "",
45-
},
46-
planDataMod: {
47-
bandwidth: "",
48-
trafficVol: "",
49-
trafficType: "",
50-
IPv4: "0",
51-
IPv6: "0",
52-
networkRoute: "",
53-
extra: "",
54-
},
55-
}
38+
export const defaultPublicNote: PublicNote = {}
5639

5740
export const isValidISOLike = (v: string) => {
5841
if (!v) return true
@@ -77,36 +60,14 @@ export const parsePublicNote = (s?: string): PublicNote => {
7760
const obj = JSON.parse(s)
7861
const parsed = PublicNoteSchema.safeParse(obj)
7962
if (parsed.success) {
80-
const v = parsed.data
81-
return {
82-
billingDataMod: {
83-
startDate: v.billingDataMod?.startDate ?? "",
84-
endDate: v.billingDataMod?.endDate ?? "",
85-
autoRenewal: v.billingDataMod?.autoRenewal ?? "",
86-
cycle: v.billingDataMod?.cycle ?? "",
87-
amount: v.billingDataMod?.amount ?? "",
88-
},
89-
planDataMod: {
90-
bandwidth: v.planDataMod?.bandwidth ?? "",
91-
trafficVol: v.planDataMod?.trafficVol ?? "",
92-
trafficType: v.planDataMod?.trafficType ?? "",
93-
IPv4: v.planDataMod?.IPv4 === "1" ? "1" : "0",
94-
IPv6: v.planDataMod?.IPv6 === "1" ? "1" : "0",
95-
networkRoute: v.planDataMod?.networkRoute ?? "",
96-
extra: v.planDataMod?.extra ?? "",
97-
},
98-
}
63+
return parsed.data
9964
}
10065
return defaultPublicNote
10166
} catch {
10267
return defaultPublicNote
10368
}
10469
}
10570

106-
/**
107-
* Validate with zod and convert to a UI-friendly error map.
108-
* Error keys follow the component's path naming; messages provided via i18n.t.
109-
*/
11071
export const validatePublicNote = (pn: PublicNote) => {
11172
const errors: Partial<Record<string, string>> = {}
11273

0 commit comments

Comments
 (0)