mirror of
https://github.com/formbricks/formbricks.git
synced 2026-04-10 19:29:33 -05:00
Merge branch 'main' of https://github.com/formbricks/formbricks
This commit is contained in:
@@ -39,7 +39,7 @@ To link a response to a user in your Formbricks database, you can pass your inte
|
||||
|
||||
## Where do I find my userId?
|
||||
|
||||
The `userId` we are refering to is the `userId` of your own system. For example, a user signs up to your app and gets the Id `ABC123` assigned then this is the Id you pass along in the URL parameter.
|
||||
The `userId` we are referring to is the `userId` of your own system. For example, a user signs up to your app and gets the Id `ABC123` assigned then this is the Id you pass along in the URL parameter.
|
||||
|
||||
This allows you to connect the response to the user profile of this specific in the Formbricks database. You can then use the response data to create segments for further surveying or invite them to an interview, etc.
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ export const SideNavigation = ({ pathname }) => {
|
||||
onClick={() => setSelectedId(heading.id)}
|
||||
className={`${
|
||||
heading.id === selectedId
|
||||
? "text-brand font-medium"
|
||||
? "text-brand-dark font-medium"
|
||||
: "font-normal text-slate-600 hover:text-slate-950 dark:text-white dark:hover:text-slate-50"
|
||||
}`}>
|
||||
{heading.text}
|
||||
|
||||
@@ -178,6 +178,11 @@ export const isEndingCardValid = (
|
||||
surveyLanguages: TSurveyLanguage[]
|
||||
) => {
|
||||
if (card.type === "endScreen") {
|
||||
const parseResult = z.string().url().safeParse(card.buttonLink);
|
||||
if (card.buttonLabel !== undefined && !parseResult.success) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
isContentValid(card.headline, surveyLanguages) &&
|
||||
isContentValid(card.subheader, surveyLanguages) &&
|
||||
@@ -188,7 +193,6 @@ export const isEndingCardValid = (
|
||||
if (parseResult.success) {
|
||||
return card.label?.trim() !== "";
|
||||
} else {
|
||||
toast.error("Invalid Redirect Url in Ending card");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ export const DisableTwoFactorModal = ({ open, setOpen }: TDisableTwoFactorModalP
|
||||
placeholder="*******"
|
||||
aria-placeholder="password"
|
||||
required
|
||||
className="focus:border-brand focus:ring-brand block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
|
||||
className="focus:border-brand-dark focus:ring-brand-dark block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
|
||||
{...field}
|
||||
/>
|
||||
|
||||
|
||||
@@ -83,7 +83,7 @@ const ConfirmPasswordForm = ({
|
||||
placeholder="*******"
|
||||
aria-placeholder="password"
|
||||
required
|
||||
className="focus:border-brand focus:ring-brand block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
|
||||
className="focus:border-brand-dark focus:ring-brand-dark block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
|
||||
{...field}
|
||||
/>
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ export const PasswordResetForm = ({}) => {
|
||||
type="email"
|
||||
autoComplete="email"
|
||||
required
|
||||
className="focus:border-brand focus:ring-brand block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
|
||||
className="focus:border-brand-dark focus:ring-brand-dark block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -69,7 +69,7 @@ export const ResetPasswordForm = () => {
|
||||
autoComplete="current-password"
|
||||
placeholder="*******"
|
||||
required
|
||||
className="focus:border-brand focus:ring-brand mt-2 block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
|
||||
className="focus:border-brand-dark focus:ring-brand-dark mt-2 block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
@@ -84,7 +84,7 @@ export const ResetPasswordForm = () => {
|
||||
autoComplete="current-password"
|
||||
placeholder="*******"
|
||||
required
|
||||
className="focus:border-brand focus:ring-brand mt-2 block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
|
||||
className="focus:border-brand-dark focus:ring-brand-dark mt-2 block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -156,7 +156,7 @@ export const SigninForm = ({
|
||||
required
|
||||
placeholder="work@email.com"
|
||||
defaultValue={searchParams?.get("email") || ""}
|
||||
className="focus:border-brand focus:ring-brand block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
|
||||
className="focus:border-brand-dark focus:ring-brand-dark block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
|
||||
{...formMethods.register("email", {
|
||||
required: true,
|
||||
pattern: /\S+@\S+\.\S+/,
|
||||
@@ -178,7 +178,7 @@ export const SigninForm = ({
|
||||
aria-placeholder="password"
|
||||
onFocus={() => setIsPasswordFocused(true)}
|
||||
required
|
||||
className="focus:border-brand focus:ring-brand block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
|
||||
className="focus:border-brand-dark focus:ring-brand-dark block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
|
||||
{...field}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -17,7 +17,7 @@ export const TwoFactorBackup = () => {
|
||||
id="totpBackup"
|
||||
required
|
||||
placeholder="XXXXX-XXXXX"
|
||||
className="focus:border-brand focus:ring-brand block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
|
||||
className="focus:border-brand-dark focus:ring-brand-dark block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
|
||||
{...register("backupCode")}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -16,7 +16,16 @@ Your turn 👇
|
||||
|
||||
////////////////////////////
|
||||
|
||||
---
|
||||
|
||||
» 02-October-2024 by [@Jemeni11\_](https://x.com/Jemeni11_)
|
||||
» 03-October-2024 by [@adityadeshlahre](https://x.com/adityadeshlahre/)
|
||||
|
||||
---
|
||||
|
||||
» 03-October-2024 by [@adityadeshlahre](https://x.com/adityadeshlahre/)
|
||||
» 03-October-2024 by [@HarshBhatX](https://x.com/HarshBhatX/status/HarshBhatX)
|
||||
---
|
||||
|
||||
» 03-October-2024 by [@Ionfinisher](https://x.com/ion_finisher/)
|
||||
|
||||
---
|
||||
|
||||
@@ -17,5 +17,5 @@ Your turn 👇
|
||||
////////////////////////////
|
||||
|
||||
» 01-October-2024 by X
|
||||
|
||||
» 03-October-2024 by [@Recent-Highlight-449](https://www.reddit.com/user/Recent-Highlight-449/)
|
||||
---
|
||||
|
||||
@@ -19,7 +19,10 @@ Your turn 👇
|
||||
|
||||
////////////////////////////
|
||||
|
||||
» 05-April-2024 by X
|
||||
» Link 1: https...
|
||||
» 03-Octobet-2024 by Harsh Bhat
|
||||
» Link 1: https://youtu.be/pcC4Dr6Wj2Q?si=j1Rftb57M0V6vfLS
|
||||
» Link 2: https://youtu.be/NQi1CdGo6dU?si=Dhe_sVaT27MOrYVj
|
||||
» Link 3: https://youtu.be/hI4RksyFE2k?si=tgREw0wQ_tirD41O
|
||||
|
||||
|
||||
---
|
||||
|
||||
@@ -54,6 +54,11 @@ export const Survey = ({
|
||||
}: SurveyBaseProps) => {
|
||||
const [localSurvey, setlocalSurvey] = useState<TSurvey>(survey);
|
||||
|
||||
// Update localSurvey when the survey prop changes (it changes in case of survey editor)
|
||||
useEffect(() => {
|
||||
setlocalSurvey(survey);
|
||||
}, [survey]);
|
||||
|
||||
const autoFocusEnabled = autoFocus !== undefined ? autoFocus : window.self === window.top;
|
||||
|
||||
const [questionId, setQuestionId] = useState(() => {
|
||||
|
||||
@@ -29,7 +29,7 @@ export const ZSurveyEndScreenCard = ZSurveyEndingBase.extend({
|
||||
headline: ZI18nString.optional(),
|
||||
subheader: ZI18nString.optional(),
|
||||
buttonLabel: ZI18nString.optional(),
|
||||
buttonLink: z.string().optional(),
|
||||
buttonLink: z.string().url("Invalid Button Url in Ending card").optional(),
|
||||
imageUrl: z.string().optional(),
|
||||
videoUrl: z.string().optional(),
|
||||
});
|
||||
@@ -38,7 +38,7 @@ export type TSurveyEndScreenCard = z.infer<typeof ZSurveyEndScreenCard>;
|
||||
|
||||
export const ZSurveyRedirectUrlCard = ZSurveyEndingBase.extend({
|
||||
type: z.literal("redirectToUrl"),
|
||||
url: z.string().url("Invalid redirect Url in Ending card").optional(),
|
||||
url: z.string().url("Invalid Redirect Url in Ending card").optional(),
|
||||
label: z.string().optional(),
|
||||
});
|
||||
|
||||
@@ -2008,7 +2008,8 @@ const validateActions = (
|
||||
return undefined;
|
||||
});
|
||||
|
||||
return actionIssues.filter((issue) => issue !== undefined);
|
||||
const filteredActionIssues = actionIssues.filter((issue) => issue !== undefined);
|
||||
return filteredActionIssues;
|
||||
};
|
||||
|
||||
const validateLogic = (survey: TSurvey, questionIndex: number, logic: TSurveyLogic[]): z.ZodIssue[] => {
|
||||
|
||||
@@ -233,7 +233,7 @@ export const findQuestionsWithCyclicLogic = (questions: TSurveyQuestion[]): stri
|
||||
|
||||
// Helper function to find all "jumpToQuestion" actions in the logic
|
||||
const findJumpToQuestionActions = (actions: TSurveyLogicAction[]): TActionJumpToQuestion[] => {
|
||||
return actions.filter((action) => action.objective === "jumpToQuestion");
|
||||
return actions.filter((action): action is TActionJumpToQuestion => action.objective === "jumpToQuestion");
|
||||
};
|
||||
|
||||
// function to validate hidden field or question id
|
||||
|
||||
@@ -109,7 +109,7 @@ export const SignupOptions = ({
|
||||
placeholder="Full Name"
|
||||
aria-placeholder="Full Name"
|
||||
required
|
||||
className="focus:border-brand focus:ring-brand block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
|
||||
className="focus:border-brand-dark focus:ring-brand-dark block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
@@ -125,7 +125,7 @@ export const SignupOptions = ({
|
||||
required
|
||||
placeholder="work@email.com"
|
||||
defaultValue={emailFromSearchParams}
|
||||
className="focus:border-brand focus:ring-brand block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
|
||||
className="focus:border-brand-dark focus:ring-brand-dark block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
|
||||
/>
|
||||
</div>
|
||||
<div className="transition-all duration-500 ease-in-out">
|
||||
@@ -142,7 +142,7 @@ export const SignupOptions = ({
|
||||
aria-placeholder="password"
|
||||
onFocus={() => setIsPasswordFocused(true)}
|
||||
required
|
||||
className="focus:border-brand focus:ring-brand block w-full rounded-md shadow-sm sm:text-sm"
|
||||
className="focus:border-brand-dark focus:ring-brand-dark block w-full rounded-md shadow-sm sm:text-sm"
|
||||
/>
|
||||
</div>
|
||||
{passwordResetEnabled && isPasswordFocused && (
|
||||
|
||||
@@ -33,7 +33,7 @@ export const StartFromScratchTemplate = ({
|
||||
}}
|
||||
className={cn(
|
||||
activeTemplate?.name === customSurvey.name
|
||||
? "ring-brand border-transparent ring-2"
|
||||
? "ring-brand-dark border-transparent ring-2"
|
||||
: "hover:border-brand-dark border-dashed border-slate-300",
|
||||
"duration-120 group relative rounded-lg border-2 bg-transparent p-6 transition-colors duration-150"
|
||||
)}>
|
||||
|
||||
Reference in New Issue
Block a user