const createSchema = (total: number) => {
const FormNumber = S.transform(S.String, S.Number, {
decode: (s) => (s.trim() === "" ? 0 : parseFloat(s.trim())),
encode: (n) => (n === 0 ? "" : n.toFixed(2)),
});
const SplitsSchema = S.Array(
S.Struct({
memberUserId: S.UUID,
amount: FormNumber.pipe(
S.positive(local.annotate("Must contribute > 0%")),
S.lessThan(total, local.annotate("Can't contribute > 100%")),
),
memberName: S.Union(S.String, S.Literal("anon")),
}),
).pipe(
S.filter(
(splits) => {
const splitsSum = Number.sumAll(splits.map((s) => s.amount));
console.log(splitsSum, total, "\n\n");
return total === splitsSum;
},
{
message: () =>
Match.value(view).pipe(
Match.when("percent", () => "Splits must sum to 100%"),
Match.when("amount", () => `Splits must sum to $${total}`),
Match.orElseAbsurd,
),
},
),
);
const Schema = S.Struct({
description: S.String,
date: S.DateFromSelf,
amount: FormNumber.pipe(
S.int(local.annotate("Amount must be a whole number")),
S.positive(local.annotate("Item must cost at least $0.01")),
S.lessThan(100_000, local.annotate("Item must not exceed $100,000")),
),
paidBy: S.Literal(...participants).pipe(
S.annotations(local.annotate("Paid By must be a valid member")),
),
splits: SplitsSchema,
});
return Schema;
};
const createSchema = (total: number) => {
const FormNumber = S.transform(S.String, S.Number, {
decode: (s) => (s.trim() === "" ? 0 : parseFloat(s.trim())),
encode: (n) => (n === 0 ? "" : n.toFixed(2)),
});
const SplitsSchema = S.Array(
S.Struct({
memberUserId: S.UUID,
amount: FormNumber.pipe(
S.positive(local.annotate("Must contribute > 0%")),
S.lessThan(total, local.annotate("Can't contribute > 100%")),
),
memberName: S.Union(S.String, S.Literal("anon")),
}),
).pipe(
S.filter(
(splits) => {
const splitsSum = Number.sumAll(splits.map((s) => s.amount));
console.log(splitsSum, total, "\n\n");
return total === splitsSum;
},
{
message: () =>
Match.value(view).pipe(
Match.when("percent", () => "Splits must sum to 100%"),
Match.when("amount", () => `Splits must sum to $${total}`),
Match.orElseAbsurd,
),
},
),
);
const Schema = S.Struct({
description: S.String,
date: S.DateFromSelf,
amount: FormNumber.pipe(
S.int(local.annotate("Amount must be a whole number")),
S.positive(local.annotate("Item must cost at least $0.01")),
S.lessThan(100_000, local.annotate("Item must not exceed $100,000")),
),
paidBy: S.Literal(...participants).pipe(
S.annotations(local.annotate("Paid By must be a valid member")),
),
splits: SplitsSchema,
});
return Schema;
};