Copy overhaul + qr designs
This commit is contained in:
@@ -9,11 +9,38 @@ import { z } from 'zod';
|
||||
// QR Code Schemas
|
||||
// ==========================================
|
||||
|
||||
/**
|
||||
* Zod strips unknown keys silently. This schema therefore has to list every
|
||||
* design field that is actually stored - otherwise the moment anyone switches
|
||||
* the route from saving `body.style` to saving the parsed output, every shape,
|
||||
* gradient and logo disappears without an error anywhere.
|
||||
*/
|
||||
export const qrStyleSchema = z.object({
|
||||
fgColor: z.string().regex(/^#[0-9A-F]{6}$/i, 'Invalid foreground color format').optional(),
|
||||
bgColor: z.string().regex(/^#[0-9A-F]{6}$/i, 'Invalid background color format').optional(),
|
||||
foregroundColor: z.string().optional(),
|
||||
backgroundColor: z.string().optional(),
|
||||
cornerStyle: z.enum(['square', 'rounded']).optional(),
|
||||
size: z.number().min(100).max(1000).optional(),
|
||||
moduleShape: z
|
||||
.enum([
|
||||
'square', 'rounded', 'dots', 'classy', 'classy-rounded',
|
||||
'diamond', 'star', 'hexagon', 'plus', 'mosaic', 'liquid',
|
||||
])
|
||||
.optional(),
|
||||
eyeFrameShape: z.enum(['square', 'rounded']).optional(),
|
||||
eyeBallShape: z.enum(['square', 'rounded', 'circle', 'diamond', 'hexagon']).optional(),
|
||||
gradientMode: z.enum(['none', 'linear', 'radial']).optional(),
|
||||
gradientTo: z.string().optional(),
|
||||
frameType: z.string().optional(),
|
||||
imageSettings: z
|
||||
.object({
|
||||
src: z.string(),
|
||||
height: z.number().optional(),
|
||||
width: z.number().optional(),
|
||||
excavate: z.boolean().optional(),
|
||||
})
|
||||
.optional(),
|
||||
});
|
||||
|
||||
export const createQRSchema = z.object({
|
||||
@@ -31,12 +58,33 @@ export const createQRSchema = z.object({
|
||||
|
||||
tags: z.array(z.string()).optional(),
|
||||
|
||||
style: z.object({
|
||||
foregroundColor: z.string().optional(),
|
||||
backgroundColor: z.string().optional(),
|
||||
cornerStyle: z.enum(['square', 'rounded']).optional(),
|
||||
size: z.number().optional(),
|
||||
}).optional(),
|
||||
style: z
|
||||
.object({
|
||||
foregroundColor: z.string().optional(),
|
||||
backgroundColor: z.string().optional(),
|
||||
cornerStyle: z.enum(['square', 'rounded']).optional(),
|
||||
size: z.number().optional(),
|
||||
moduleShape: z
|
||||
.enum([
|
||||
'square', 'rounded', 'dots', 'classy', 'classy-rounded',
|
||||
'diamond', 'star', 'hexagon', 'plus', 'mosaic', 'liquid',
|
||||
])
|
||||
.optional(),
|
||||
eyeFrameShape: z.enum(['square', 'rounded']).optional(),
|
||||
eyeBallShape: z.enum(['square', 'rounded', 'circle', 'diamond', 'hexagon']).optional(),
|
||||
gradientMode: z.enum(['none', 'linear', 'radial']).optional(),
|
||||
gradientTo: z.string().optional(),
|
||||
frameType: z.string().optional(),
|
||||
imageSettings: z
|
||||
.object({
|
||||
src: z.string(),
|
||||
height: z.number().optional(),
|
||||
width: z.number().optional(),
|
||||
excavate: z.boolean().optional(),
|
||||
})
|
||||
.optional(),
|
||||
})
|
||||
.optional(),
|
||||
});
|
||||
|
||||
export const updateQRSchema = z.object({
|
||||
@@ -53,6 +101,11 @@ export const updateQRSchema = z.object({
|
||||
style: qrStyleSchema.optional(),
|
||||
|
||||
isActive: z.boolean().optional(),
|
||||
|
||||
// Pausing frees a dynamic code slot without deleting the code or its scan
|
||||
// history. Used by the upgrade modal so hitting the limit has an exit that
|
||||
// does not cost money and does not destroy anything.
|
||||
status: z.enum(['ACTIVE', 'PAUSED']).optional(),
|
||||
});
|
||||
|
||||
export const bulkQRSchema = z.object({
|
||||
@@ -115,23 +168,23 @@ export const resetPasswordSchema = z.object({
|
||||
// Settings Schemas
|
||||
// ==========================================
|
||||
|
||||
export const updateProfileSchema = z.object({
|
||||
name: z.string()
|
||||
.min(2, 'Name must be at least 2 characters')
|
||||
.max(100, 'Name must be less than 100 characters')
|
||||
.trim(),
|
||||
});
|
||||
|
||||
export const onboardingUpdateSchema = z.object({
|
||||
signupSourceSelfReported: z.string().max(100).optional(),
|
||||
primaryUseCase: z.string().max(100).optional(),
|
||||
primaryGoal: z.string().max(100).optional(),
|
||||
jobRole: z.string().max(100).optional(),
|
||||
companyName: z.string().max(200).optional(),
|
||||
companyWebsite: z.string().max(200).optional(),
|
||||
teamSizeBucket: z.string().max(100).optional(),
|
||||
markProfileComplete: z.boolean().optional(),
|
||||
});
|
||||
export const updateProfileSchema = z.object({
|
||||
name: z.string()
|
||||
.min(2, 'Name must be at least 2 characters')
|
||||
.max(100, 'Name must be less than 100 characters')
|
||||
.trim(),
|
||||
});
|
||||
|
||||
export const onboardingUpdateSchema = z.object({
|
||||
signupSourceSelfReported: z.string().max(100).optional(),
|
||||
primaryUseCase: z.string().max(100).optional(),
|
||||
primaryGoal: z.string().max(100).optional(),
|
||||
jobRole: z.string().max(100).optional(),
|
||||
companyName: z.string().max(200).optional(),
|
||||
companyWebsite: z.string().max(200).optional(),
|
||||
teamSizeBucket: z.string().max(100).optional(),
|
||||
markProfileComplete: z.boolean().optional(),
|
||||
});
|
||||
|
||||
export const changePasswordSchema = z.object({
|
||||
currentPassword: z.string()
|
||||
|
||||
Reference in New Issue
Block a user