Component for QuestionTypeSelector

This commit is contained in:
Naitik
2023-10-03 15:44:28 +05:30
parent b2237bb5e5
commit 6c0d356c2a
4 changed files with 61 additions and 26 deletions
@@ -1,14 +1,14 @@
import React, { useState, useEffect } from "react";
import React, { useState } from "react";
import { TSurveyOpenTextQuestion, TSurveyWithAnalytics } from "@formbricks/types/v1/surveys";
import { Button, Input, Label } from "@formbricks/ui";
import { Button, Input, Label, QuestionTypeSelector } from "@formbricks/ui";
import { TrashIcon, PlusIcon } from "@heroicons/react/24/solid";
const questionTypes = [
{ value: "text", label: "Text" },
{ value: "email", label: "Email" },
{ value: "url", label: "URL" },
{ value: "number", label: "Number" },
{ value: "phone", label: "Phone Number" },
{ value: "text", label: "Text 📝" },
{ value: "email", label: "Email 📧" },
{ value: "url", label: "URL 🌐" },
{ value: "number", label: "Number 1️⃣" },
{ value: "phone", label: "Phone ☎️" },
];
interface OpenQuestionFormProps {
@@ -28,15 +28,10 @@ export default function OpenQuestionForm({
}: OpenQuestionFormProps): JSX.Element {
const [showSubheader, setShowSubheader] = useState(!!question.subheader);
// Function to handle question type change
const handleQuestionTypeChange = (value: string) => {
updateQuestion(questionIdx, { inputType: value });
};
useEffect(() => {
handleQuestionTypeChange("text");
}, []);
return (
<form>
<div className="mt-3">
@@ -98,16 +93,11 @@ export default function OpenQuestionForm({
<div className="mt-3">
<Label htmlFor="questionType">Question Type</Label>
<div className="flex items-center">
{questionTypes.map((type) => (
<div
key={type.value}
onClick={() => handleQuestionTypeChange(type.value)}
className={`mr-2 cursor-pointer rounded-md border p-2 ${
question.inputType === type.value ? "bg-slate-50" : "bg-white"
}`}>
{type.label}
</div>
))}
<QuestionTypeSelector
questionTypes={questionTypes}
currentType={question.inputType}
handleTypeChange={handleQuestionTypeChange}
/>
</div>
</div>
</form>
@@ -6,7 +6,10 @@ import Subheader from "./Subheader";
import SubmitButton from "./SubmitButton";
import { useState } from "preact/hooks";
function validateInput(value: string, questionType: string): boolean {
function validateInput(value: string, questionType: string, required: boolean): boolean {
if (!required && (value == undefined || value == "" || value == null || value.length <= 0)) {
return true;
}
switch (questionType) {
case "email":
const emailPattern = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
@@ -15,7 +18,8 @@ function validateInput(value: string, questionType: string): boolean {
const urlPattern = /^(ftp|http|https):\/\/[^ "]+$/;
return urlPattern.test(value);
case "number":
return !isNaN(parseFloat(value));
const numberPattern = /^[0-9]*$/;
return numberPattern.test(value);
case "phone":
const phonePattern = /^\+?[0-9]+$/;
return phonePattern.test(value);
@@ -47,10 +51,12 @@ export default function OpenTextQuestion({
brandColor,
autoFocus = true,
}: OpenTextQuestionProps) {
const [isValid, setIsValid] = useState(true);
const [isValid, setIsValid] = useState(
validateInput(value as string, question.inputType, question.required)
);
const handleInputChange = (inputValue: string) => {
const isValidInput = validateInput(inputValue, question.inputType);
const isValidInput = validateInput(inputValue, question.inputType, question.required);
setIsValid(isValidInput);
onChange({ [question.id]: inputValue });
};
@@ -59,6 +65,7 @@ export default function OpenTextQuestion({
<form
onSubmit={(e) => {
e.preventDefault();
validateInput(value as string, question.inputType, question.required);
if (isValid) {
onSubmit({ [question.id]: value, inputType: question.inputType });
}
@@ -94,6 +101,7 @@ export default function OpenTextQuestion({
isValid ? "border-slate-100" : "border-red-500" // Apply red border for invalid input
} bg-slate-50 p-2 shadow-sm focus:border-slate-500 focus:outline-none focus:ring-0 sm:text-sm`}></textarea>
)}
{!isValid && <p className="text-red-500">Please enter a valid {question.inputType}</p>}
</div>
<div className="mt-4 flex w-full justify-between">
{!isFirstQuestion && (
@@ -0,0 +1,36 @@
import React from "react";
interface QuestionType {
value: string;
label: string;
}
interface QuestionTypeSelectorProps {
questionTypes: QuestionType[];
currentType: string | undefined;
handleTypeChange: (value: string) => void;
}
export function QuestionTypeSelector({
questionTypes,
currentType,
handleTypeChange,
}: QuestionTypeSelectorProps): JSX.Element {
return (
<div className="flex items-center rounded-md border p-2">
{questionTypes.map((type, index) => (
<div
key={type.value}
onClick={() => handleTypeChange(type.value)}
className={`mr-2 cursor-pointer rounded-md ${
(currentType === undefined && type.value === "text") || currentType === type.value
? "bg-slate-100"
: "bg-white"
}`}
style={{ marginLeft: index !== 0 ? "8px" : "0" }}>
{type.label}
</div>
))}
</div>
);
}
+1
View File
@@ -73,6 +73,7 @@ export { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./comp
export { AddVariablesDropdown, Editor } from "./components/editor";
export { Skeleton } from "./components/Skeleton";
export { NoMobileOverlay } from "./components/NoMobileOverlay";
export { QuestionTypeSelector } from "./components/QuestionTypeSelector";
/* Icons */
export { AngryBirdRage2Icon } from "./components/icons/AngryBirdRage2Icon";