-
Notifications
You must be signed in to change notification settings - Fork 940
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat: Advanced Custom Styling #2182
Conversation
…feat/form-styling
The latest updates on your projects. Learn more about Vercel for Git ↗︎ 2 Ignored Deployments
|
Thank you for following the naming conventions for pull request titles! 🙏 |
apps/web/app/(app)/environments/[environmentId]/surveys/components/Modal.tsxConsider using the const scalingClasses = useMemo(() => calculateScaling(), [windowWidth, previewMode]);
const highlightBorderColorStyle = useMemo(() => {
if (!highlightBorderColor)
return {
overflow: "auto",
};
return {
border: `2px solid ${highlightBorderColor}`,
overflow: "auto",
};
}, [highlightBorderColor]);
Consider using a switch statement instead of multiple if-else statements for let placementClass = "";
switch (placement) {
case "bottomLeft":
placementClass = "bottom left";
break;
case "bottomRight":
placementClass = "bottom right";
break;
case "topLeft":
placementClass = "top left";
break;
case "topRight":
placementClass = "top right";
break;
}
packages/surveys/src/components/questions/OpenTextQuestion.tsxConsider using the const handleInputChange = useCallback((inputValue: string) => {
onChange({ [question.id]: inputValue });
}, [onChange, question.id]);
const handleInputResize = useCallback((event: { target: any }) => {
let maxHeight = 160; // 8 lines
const textarea = event.target;
textarea.style.height = "auto";
const newHeight = Math.min(textarea.scrollHeight, maxHeight);
textarea.style.height = `${newHeight}px`;
textarea.style.overflow = newHeight >= maxHeight ? "auto" : "hidden";
}, []);
apps/web/app/(app)/environments/[environmentId]/settings/lookandfeel/components/UnifiedStyling.tsxConsider breaking down the large // Example of breaking down the component
const UnifiedStyling = ({ product }: UnifiedStylingProps) => {
// ...
return (
<div className="flex">
<StylingSettings {...props} />
<SurveyPreview {...props} />
</div>
);
};
Consider using the // Example of using useCallback
const onSave = useCallback(async () => {
// ...
}, [dependencies]);
Consider abstracting the color defaults into a separate constant or configuration file. This will make the code cleaner and easier to manage. // Example of abstracting color defaults
const COLOR_DEFAULTS = {
brandColor: "#64748b",
questionColor: "#2b2524",
inputColor: "#efefef",
inputBorderColor: "#c0c0c0",
cardBackgroundColor: "#c0c0c0",
highlighBorderColor: "#64748b",
};
packages/database/migrations/20240229062232_adds_styling_column_to_product_model/data-migration.tsInstead of updating the product one by one in the loop, you can collect all the updates and perform them in a single transaction. This will significantly improve the performance of your script. const updates = products.map(product => {
const styling: TStyling = {
unifiedStyling: true,
allowStyleOverwrite: true,
brandColor: {
light: product.brandColor,
},
...(product.highlightBorderColor && {
highlightBorderColor: {
light: product.highlightBorderColor,
dark: product.highlightBorderColor,
},
}),
};
return tx.product.update({
where: {
id: product.id,
},
data: {
styling,
},
});
});
await tx.$transaction(updates);
It's a good practice to throw an error when the expected data is not found. This will help you to identify issues in your data or script early. if (!products) {
throw new Error('No products found');
}
packages/database/migrations/20240229062232_adds_styling_column_to_product_model/migration.sqlConsider adding an index to the new JSONB column to improve query performance. If you're going to query by any of the keys in the JSONB column, you should create a GIN index on it. However, keep in mind that while GIN indexes improve read performance, they can slow down write operations. Therefore, it's a trade-off that you need to consider based on your application's needs. CREATE INDEX idx_product_styling ON "Product" USING gin ("styling");
Consider removing the default value from the JSONB column and handle it at the application level. This way, you can avoid data redundancy and ensure consistency across your application. ALTER TABLE "Product" ADD COLUMN "styling" JSONB;
packages/surveys/tailwind.config.jsConsider using more descriptive names for your custom variables. This will make the code easier to read and maintain. For example, instead of "custom", you could use "fbBorderRadius". This makes it clear that this variable is a custom border radius for Facebook elements. borderRadius: {
fbBorderRadius: "var(--fb-border-radius)",
},
|
color={cardBackgroundColor} | ||
setColor={setCardBackgroundColor} | ||
description="Change the text color of the survey questions." | ||
/> | ||
|
||
<div className="flex flex-col gap-4"> | ||
<div className="flex items-center gap-6"> | ||
<Switch | ||
checked={allowHighlightBorder} | ||
onCheckedChange={(value) => { | ||
setAllowHighlightBorder(value); | ||
}} | ||
disabled={!unifiedStyling} | ||
/> | ||
<div className="flex flex-col"> | ||
<h3 className="text-base font-semibold">Add highlight border</h3> | ||
<p className="text-sm text-slate-800">Add on outer border to your survey card</p> | ||
</div> | ||
</div> | ||
|
||
{allowHighlightBorder && ( | ||
<ColorPicker | ||
color={highlightBorderColor} | ||
onChange={setHighlightBorderColor} | ||
containerClass="my-0" | ||
/> | ||
)} | ||
</div> | ||
|
||
<DarkModeColors | ||
isDarkMode={isDarkMode} | ||
setIsDarkMode={setIsDarkMode} | ||
brandColor={brandColorDark} | ||
cardBackgroundColor={cardBackgroundColorDark} | ||
highlightBorderColor={highlightBorderColorDark} | ||
inputBorderColor={inputBorderColorDark} | ||
inputColor={inputColorDark} | ||
questionColor={questionColorDark} | ||
setBrandColor={setBrandColorDark} | ||
setCardBackgroundColor={setCardBackgroundColorDark} | ||
setHighlighBorderColor={setHighlightBorderColorDark} | ||
setInputBorderColor={setInputBorderColorDark} | ||
setInputColor={setInputColorDark} | ||
setQuestionColor={setQuestionColorDark} | ||
/> | ||
|
||
<div className="flex flex-col gap-4"> | ||
<div className="flex flex-col"> | ||
<h3 className="text-base font-semibold text-slate-900">Roundness</h3> | ||
<p className="text-sm text-slate-800">Change the border radius of the card and the inputs.</p> | ||
</div> | ||
|
||
<Slider | ||
value={[roundness]} | ||
max={16} | ||
onValueChange={(value) => setRoundness(value[0])} | ||
disabled={!unifiedStyling} | ||
/> | ||
</div> | ||
|
||
<CardArrangement | ||
activeCardArrangement={linkSurveysCardArrangement} | ||
surveyType="link" | ||
setActiveCardArrangement={setLinkSurveysCardArrangement} | ||
/> | ||
|
||
<CardArrangement | ||
activeCardArrangement={inAppSurveysCardArrangement} | ||
surveyType="web" | ||
setActiveCardArrangement={setInAppSurveysCardArrangement} | ||
/> | ||
</div> | ||
|
||
<div className="mt-8 flex items-center justify-end gap-2"> | ||
<Button variant="minimal" className="flex items-center gap-2"> | ||
Reset | ||
<RotateCcwIcon className="h-4 w-4" /> | ||
</Button> | ||
|
||
<Button variant="darkCTA" onClick={onSave}> | ||
Save changes | ||
</Button> | ||
</div> | ||
</div> | ||
|
||
{/* Survey Preview */} | ||
|
||
<div className="w-1/2 bg-slate-100 pt-4"> | ||
<div className="h-full max-h-[800px]"> | ||
<UnifiedStylingPreviewSurvey | ||
activeQuestionId={activeQuestionId} | ||
setActiveQuestionId={setActiveQuestionId} | ||
survey={previewSurvey as TSurvey} | ||
product={product} | ||
/> | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Breaking down the large UnifiedStyling
component into smaller, more manageable components. This will make the code easier to read and maintain.
const UnifiedStyling = ({ product }: UnifiedStylingProps) => { | |
const router = useRouter(); | |
const [unifiedStyling, setUnifiedStyling] = useState(product.styling?.unifiedStyling ?? false); | |
const [allowStyleOverwrite, setAllowStyleOverwrite] = useState( | |
product.styling?.allowStyleOverwrite ?? false | |
); | |
const [brandColor, setBrandColor] = useState( | |
product.styling?.brandColor?.light ?? colorDefaults.brandColor | |
); | |
const [questionColor, setQuestionColor] = useState( | |
product.styling?.questionColor?.light ?? colorDefaults.questionColor | |
); | |
const [inputColor, setInputColor] = useState( | |
product.styling?.inputColor?.light ?? colorDefaults.inputColor | |
); | |
const [inputBorderColor, setInputBorderColor] = useState( | |
product.styling?.inputBorderColor?.light ?? colorDefaults.inputBorderColor | |
); | |
const [cardBackgroundColor, setCardBackgroundColor] = useState( | |
product.styling?.cardBackgroundColor?.light ?? colorDefaults.cardBackgroundColor | |
); | |
// highlight border | |
const [allowHighlightBorder, setAllowHighlightBorder] = useState( | |
!!product.styling?.highlightBorderColor?.light ?? false | |
); | |
const [highlightBorderColor, setHighlightBorderColor] = useState( | |
product.styling?.highlightBorderColor?.light ?? colorDefaults.highlighBorderColor | |
); | |
const [isDarkMode, setIsDarkMode] = useState(product.styling?.isDarkModeEnabled ?? false); | |
const [brandColorDark, setBrandColorDark] = useState(product.styling?.brandColor?.dark); | |
const [questionColorDark, setQuestionColorDark] = useState(product.styling?.questionColor?.dark); | |
const [inputColorDark, setInputColorDark] = useState(product.styling?.inputColor?.dark); | |
const [inputBorderColorDark, setInputBorderColorDark] = useState(product.styling?.inputBorderColor?.dark); | |
const [cardBackgroundColorDark, setCardBackgroundColorDark] = useState( | |
product.styling?.cardBackgroundColor?.dark | |
); | |
const [highlightBorderColorDark, setHighlightBorderColorDark] = useState( | |
product.styling?.highlightBorderColor?.dark | |
); | |
const [roundness, setRoundness] = useState(product.styling?.roundness ?? 8); | |
const [linkSurveysCardArrangement, setLinkSurveysCardArrangement] = useState( | |
product.styling?.cardArrangement?.linkSurveys ?? "casual" | |
); | |
const [inAppSurveysCardArrangement, setInAppSurveysCardArrangement] = useState( | |
product.styling?.cardArrangement?.inAppSurveys ?? "casual" | |
); | |
const [activeQuestionId, setActiveQuestionId] = useState<string | null>(null); | |
useEffect(() => { | |
setActiveQuestionId(previewSurvey.questions[0].id); | |
}, []); | |
useEffect(() => { | |
if (!unifiedStyling) { | |
setAllowStyleOverwrite(false); | |
} | |
}, [unifiedStyling]); | |
const onSave = async () => { | |
await updateProductAction(product.id, { | |
styling: { | |
unifiedStyling, | |
allowStyleOverwrite, | |
brandColor: { | |
light: brandColor, | |
dark: brandColorDark, | |
}, | |
questionColor: { | |
light: questionColor, | |
dark: questionColorDark, | |
}, | |
inputColor: { | |
light: inputColor, | |
dark: inputColorDark, | |
}, | |
inputBorderColor: { | |
light: inputBorderColor, | |
dark: inputBorderColorDark, | |
}, | |
cardBackgroundColor: { | |
light: cardBackgroundColor, | |
dark: cardBackgroundColorDark, | |
}, | |
highlightBorderColor: allowHighlightBorder | |
? { | |
light: highlightBorderColor, | |
dark: highlightBorderColorDark, | |
} | |
: undefined, | |
isDarkModeEnabled: isDarkMode, | |
roundness, | |
cardArrangement: { | |
linkSurveys: linkSurveysCardArrangement, | |
inAppSurveys: inAppSurveysCardArrangement, | |
}, | |
}, | |
}); | |
toast.success("Styling updated successfully."); | |
router.refresh(); | |
}; | |
return ( | |
<div className="flex"> | |
{/* Styling settings */} | |
<div className="w-1/2 pr-6"> | |
<div className="flex flex-col gap-6"> | |
<div className="flex flex-col gap-4 rounded-lg bg-slate-50 p-4"> | |
<div className="flex items-center gap-6"> | |
<Switch | |
checked={unifiedStyling} | |
onCheckedChange={(value) => { | |
setUnifiedStyling(value); | |
}} | |
/> | |
<div className="flex flex-col"> | |
<h3 className="text-base font-semibold">Enable unified styling</h3> | |
<p className="text-sm text-slate-800">Set base styles for all surveys below</p> | |
</div> | |
</div> | |
<div className="flex items-center gap-6"> | |
<Switch | |
checked={allowStyleOverwrite} | |
onCheckedChange={(value) => { | |
setAllowStyleOverwrite(value); | |
}} | |
disabled={!unifiedStyling} | |
/> | |
<div className="flex flex-col"> | |
<h3 className="text-base font-semibold">Allow overwriting styles</h3> | |
<p className="text-sm text-slate-800"> | |
Activate if you want some surveys to be styled differently | |
</p> | |
</div> | |
</div> | |
</div> | |
<ColorSelectorWithLabel | |
label="Brand color" | |
color={brandColor} | |
setColor={setBrandColor} | |
description="Change the text color of the survey questions." | |
disabled | |
/> | |
<ColorSelectorWithLabel | |
label="Question color" | |
color={questionColor} | |
setColor={setQuestionColor} | |
description="Change the text color of the survey questions." | |
/> | |
<ColorSelectorWithLabel | |
label="Input color" | |
color={inputColor} | |
setColor={setInputColor} | |
description="Change the text color of the survey questions." | |
/> | |
<ColorSelectorWithLabel | |
label="Input border color" | |
color={inputBorderColor} | |
setColor={setInputBorderColor} | |
description="Change the text color of the survey questions." | |
/> | |
<ColorSelectorWithLabel | |
label="Card background color" | |
color={cardBackgroundColor} | |
setColor={setCardBackgroundColor} | |
description="Change the text color of the survey questions." | |
/> | |
<div className="flex flex-col gap-4"> | |
<div className="flex items-center gap-6"> | |
<Switch | |
checked={allowHighlightBorder} | |
onCheckedChange={(value) => { | |
setAllowHighlightBorder(value); | |
}} | |
disabled={!unifiedStyling} | |
/> | |
<div className="flex flex-col"> | |
<h3 className="text-base font-semibold">Add highlight border</h3> | |
<p className="text-sm text-slate-800">Add on outer border to your survey card</p> | |
</div> | |
</div> | |
{allowHighlightBorder && ( | |
<ColorPicker | |
color={highlightBorderColor} | |
onChange={setHighlightBorderColor} | |
containerClass="my-0" | |
/> | |
)} | |
</div> | |
<DarkModeColors | |
isDarkMode={isDarkMode} | |
setIsDarkMode={setIsDarkMode} | |
brandColor={brandColorDark} | |
cardBackgroundColor={cardBackgroundColorDark} | |
highlightBorderColor={highlightBorderColorDark} | |
inputBorderColor={inputBorderColorDark} | |
inputColor={inputColorDark} | |
questionColor={questionColorDark} | |
setBrandColor={setBrandColorDark} | |
setCardBackgroundColor={setCardBackgroundColorDark} | |
setHighlighBorderColor={setHighlightBorderColorDark} | |
setInputBorderColor={setInputBorderColorDark} | |
setInputColor={setInputColorDark} | |
setQuestionColor={setQuestionColorDark} | |
/> | |
<div className="flex flex-col gap-4"> | |
<div className="flex flex-col"> | |
<h3 className="text-base font-semibold text-slate-900">Roundness</h3> | |
<p className="text-sm text-slate-800">Change the border radius of the card and the inputs.</p> | |
</div> | |
<Slider | |
value={[roundness]} | |
max={16} | |
onValueChange={(value) => setRoundness(value[0])} | |
disabled={!unifiedStyling} | |
/> | |
</div> | |
<CardArrangement | |
activeCardArrangement={linkSurveysCardArrangement} | |
surveyType="link" | |
setActiveCardArrangement={setLinkSurveysCardArrangement} | |
/> | |
<CardArrangement | |
activeCardArrangement={inAppSurveysCardArrangement} | |
surveyType="web" | |
setActiveCardArrangement={setInAppSurveysCardArrangement} | |
/> | |
</div> | |
<div className="mt-8 flex items-center justify-end gap-2"> | |
<Button variant="minimal" className="flex items-center gap-2"> | |
Reset | |
<RotateCcwIcon className="h-4 w-4" /> | |
</Button> | |
<Button variant="darkCTA" onClick={onSave}> | |
Save changes | |
</Button> | |
</div> | |
</div> | |
{/* Survey Preview */} | |
<div className="w-1/2 bg-slate-100 pt-4"> | |
<div className="h-full max-h-[800px]"> | |
<UnifiedStylingPreviewSurvey | |
activeQuestionId={activeQuestionId} | |
setActiveQuestionId={setActiveQuestionId} | |
survey={previewSurvey as TSurvey} | |
product={product} | |
/> | |
</div> | |
</div> | |
</div> | |
); | |
}; | |
const StylingSettings = ({...props}) => { | |
// ... styling settings code ... | |
}; | |
const SurveyPreview = ({...props}) => { | |
// ... survey preview code ... | |
}; | |
const UnifiedStyling = ({ product }: UnifiedStylingProps) => { | |
// ... | |
return ( | |
<div className="flex"> | |
<StylingSettings {...props} /> | |
<SurveyPreview {...props} /> | |
</div> | |
); | |
}; |
const onSave = async () => { | ||
await updateProductAction(product.id, { | ||
styling: { | ||
unifiedStyling, | ||
allowStyleOverwrite, | ||
brandColor: { | ||
light: brandColor, | ||
dark: brandColorDark, | ||
}, | ||
questionColor: { | ||
light: questionColor, | ||
dark: questionColorDark, | ||
}, | ||
inputColor: { | ||
light: inputColor, | ||
dark: inputColorDark, | ||
}, | ||
inputBorderColor: { | ||
light: inputBorderColor, | ||
dark: inputBorderColorDark, | ||
}, | ||
cardBackgroundColor: { | ||
light: cardBackgroundColor, | ||
dark: cardBackgroundColorDark, | ||
}, | ||
highlightBorderColor: allowHighlightBorder | ||
? { | ||
light: highlightBorderColor, | ||
dark: highlightBorderColorDark, | ||
} | ||
: undefined, | ||
isDarkModeEnabled: isDarkMode, | ||
roundness, | ||
cardArrangement: { | ||
linkSurveys: linkSurveysCardArrangement, | ||
inAppSurveys: inAppSurveysCardArrangement, | ||
}, | ||
}, | ||
}); | ||
|
||
toast.success("Styling updated successfully."); | ||
router.refresh(); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use the useCallback
hook for the onSave
function to prevent unnecessary re-renders and improve performance.
const onSave = async () => { | |
await updateProductAction(product.id, { | |
styling: { | |
unifiedStyling, | |
allowStyleOverwrite, | |
brandColor: { | |
light: brandColor, | |
dark: brandColorDark, | |
}, | |
questionColor: { | |
light: questionColor, | |
dark: questionColorDark, | |
}, | |
inputColor: { | |
light: inputColor, | |
dark: inputColorDark, | |
}, | |
inputBorderColor: { | |
light: inputBorderColor, | |
dark: inputBorderColorDark, | |
}, | |
cardBackgroundColor: { | |
light: cardBackgroundColor, | |
dark: cardBackgroundColorDark, | |
}, | |
highlightBorderColor: allowHighlightBorder | |
? { | |
light: highlightBorderColor, | |
dark: highlightBorderColorDark, | |
} | |
: undefined, | |
isDarkModeEnabled: isDarkMode, | |
roundness, | |
cardArrangement: { | |
linkSurveys: linkSurveysCardArrangement, | |
inAppSurveys: inAppSurveysCardArrangement, | |
}, | |
}, | |
}); | |
toast.success("Styling updated successfully."); | |
router.refresh(); | |
}; | |
const onSave = useCallback(async () => { | |
await updateProductAction(product.id, { | |
styling: { | |
unifiedStyling, | |
allowStyleOverwrite, | |
brandColor: { | |
light: brandColor, | |
dark: brandColorDark, | |
}, | |
questionColor: { | |
light: questionColor, | |
dark: questionColorDark, | |
}, | |
inputColor: { | |
light: inputColor, | |
dark: inputColorDark, | |
}, | |
inputBorderColor: { | |
light: inputBorderColor, | |
dark: inputBorderColorDark, | |
}, | |
cardBackgroundColor: { | |
light: cardBackgroundColor, | |
dark: cardBackgroundColorDark, | |
}, | |
highlightBorderColor: allowHighlightBorder | |
? { | |
light: highlightBorderColor, | |
dark: highlightBorderColorDark, | |
} | |
: undefined, | |
isDarkModeEnabled: isDarkMode, | |
roundness, | |
cardArrangement: { | |
linkSurveys: linkSurveysCardArrangement, | |
inAppSurveys: inAppSurveysCardArrangement, | |
}, | |
}, | |
}); | |
toast.success("Styling updated successfully."); | |
router.refresh(); | |
}, [unifiedStyling, allowStyleOverwrite, brandColor, brandColorDark, questionColor, questionColorDark, inputColor, inputColorDark, inputBorderColor, inputBorderColorDark, cardBackgroundColor, cardBackgroundColorDark, allowHighlightBorder, highlightBorderColor, highlightBorderColorDark, isDarkMode, roundness, linkSurveysCardArrangement, inAppSurveysCardArrangement]); |
const colorDefaults = { | ||
brandColor: "#64748b", | ||
questionColor: "#2b2524", | ||
inputColor: "#efefef", | ||
inputBorderColor: "#c0c0c0", | ||
cardBackgroundColor: "#c0c0c0", | ||
highlighBorderColor: "#64748b", | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Abstract the color defaults into a separate constant for cleaner and more manageable code.
const colorDefaults = { | |
brandColor: "#64748b", | |
questionColor: "#2b2524", | |
inputColor: "#efefef", | |
inputBorderColor: "#c0c0c0", | |
cardBackgroundColor: "#c0c0c0", | |
highlighBorderColor: "#64748b", | |
}; | |
const COLOR_DEFAULTS = { | |
brandColor: "#64748b", | |
questionColor: "#2b2524", | |
inputColor: "#efefef", | |
inputBorderColor: "#c0c0c0", | |
cardBackgroundColor: "#c0c0c0", | |
highlighBorderColor: "#64748b", | |
}; |
if (products.length) { | ||
for (const product of products) { | ||
if (product.styling !== null) { | ||
// styling object already exists for this product | ||
continue; | ||
} | ||
|
||
const styling: TStyling = { | ||
unifiedStyling: true, | ||
allowStyleOverwrite: true, | ||
brandColor: { | ||
light: product.brandColor, | ||
}, | ||
...(product.highlightBorderColor && { | ||
highlightBorderColor: { | ||
light: product.highlightBorderColor, | ||
dark: product.highlightBorderColor, | ||
}, | ||
}), | ||
}; | ||
|
||
await tx.product.update({ | ||
where: { | ||
id: product.id, | ||
}, | ||
data: { | ||
styling, | ||
}, | ||
}); | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The code is updated to collect all the updates and perform them in a single transaction, improving the performance of the data migration script.
if (products.length) { | |
for (const product of products) { | |
if (product.styling !== null) { | |
// styling object already exists for this product | |
continue; | |
} | |
const styling: TStyling = { | |
unifiedStyling: true, | |
allowStyleOverwrite: true, | |
brandColor: { | |
light: product.brandColor, | |
}, | |
...(product.highlightBorderColor && { | |
highlightBorderColor: { | |
light: product.highlightBorderColor, | |
dark: product.highlightBorderColor, | |
}, | |
}), | |
}; | |
await tx.product.update({ | |
where: { | |
id: product.id, | |
}, | |
data: { | |
styling, | |
}, | |
}); | |
} | |
} | |
const updates = products.map(product => { | |
if (product.styling !== null) { | |
// styling object already exists for this product | |
return; | |
} | |
const styling: TStyling = { | |
unifiedStyling: true, | |
allowStyleOverwrite: true, | |
brandColor: { | |
light: product.brandColor, | |
}, | |
...(product.highlightBorderColor && { | |
highlightBorderColor: { | |
light: product.highlightBorderColor, | |
dark: product.highlightBorderColor, | |
}, | |
}), | |
}; | |
return tx.product.update({ | |
where: { | |
id: product.id, | |
}, | |
data: { | |
styling, | |
}, | |
}); | |
}); | |
await tx.$transaction(updates); |
if (!products) { | ||
// something went wrong, could not find any products | ||
return; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Throwing an error when no products are found will help identify issues in the data or script early.
if (!products) { | |
// something went wrong, could not find any products | |
return; | |
} | |
if (!products || products.length === 0) { | |
throw new Error('No products found'); | |
} |
@@ -0,0 +1,2 @@ | |||
-- AlterTable | |||
ALTER TABLE "Product" ADD COLUMN "styling" JSONB DEFAULT '{"unifiedStyling":true,"allowStyleOverwrite":true,"brandColor":{"light":"#64748b"}}'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Removed the default value from the JSONB column to avoid data redundancy and ensure consistency across the application.
ALTER TABLE "Product" ADD COLUMN "styling" JSONB DEFAULT '{"unifiedStyling":true,"allowStyleOverwrite":true,"brandColor":{"light":"#64748b"}}'; | |
ALTER TABLE "Product" ADD COLUMN "styling" JSONB; |
borderRadius: { | ||
custom: "var(--fb-border-radius)", | ||
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Renamed the variable 'custom' to 'fbBorderRadius' for better readability and maintainability.
borderRadius: { | |
custom: "var(--fb-border-radius)", | |
}, | |
borderRadius: { | |
fbBorderRadius: "var(--fb-border-radius)", | |
}, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pandeymangg Great job! Works great now and it's a really cool feature that gives so many new possibilities and great survey looks. 😊
Co-authored-by: Johannes <72809645+jobenjada@users.noreply.github.com> Co-authored-by: Johannes <johannes@formbricks.com> Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
What does this PR do?
Fixes # (issue)
How should this be tested?
Checklist
Required
pnpm build
console.logs
git pull origin main
Appreciated