fix: sonar security hotspot (permission issue - non-root user in Dockerfile) (#5411)

Co-authored-by: Matthias Nannt <mail@matthiasnannt.com>
This commit is contained in:
Vijay
2025-05-06 22:44:51 +05:30
committed by GitHub
parent 8bf1e096c0
commit ae2cb15055
41 changed files with 67 additions and 63 deletions

View File

@@ -20,6 +20,7 @@ FROM base AS installer
# Enable corepack and prepare pnpm
RUN npm install -g corepack@latest
RUN corepack enable
RUN corepack prepare pnpm@9.15.0 --activate
# Install necessary build tools and compilers
RUN apk update && apk add --no-cache cmake g++ gcc jq make openssl-dev python3
@@ -77,6 +78,7 @@ FROM base AS runner
RUN npm install -g corepack@latest
RUN corepack enable
RUN corepack prepare pnpm@9.15.0 --activate
RUN apk add --no-cache curl \
&& apk add --no-cache supercronic \
@@ -146,7 +148,7 @@ RUN npm install -g tsx typescript prisma pino-pretty
EXPOSE 3000
ENV HOSTNAME "0.0.0.0"
ENV NODE_ENV="production"
# USER nextjs
USER nextjs
# Prepare volume for uploads
RUN mkdir -p /home/nextjs/apps/web/uploads/

View File

@@ -33,7 +33,7 @@ const Loading = () => {
</div>
</div>
</div>
<div className="col-span-2 my-auto flex justify-center text-center text-sm whitespace-nowrap text-slate-500">
<div className="col-span-2 my-auto flex justify-center whitespace-nowrap text-center text-sm text-slate-500">
<div className="h-4 w-28 animate-pulse rounded-full bg-slate-200"></div>
</div>
</div>

View File

@@ -264,7 +264,7 @@ export const MainNavigation = ({
size="icon"
onClick={toggleSidebar}
className={cn(
"rounded-xl bg-slate-50 p-1 text-slate-600 transition-all hover:bg-slate-100 focus:ring-0 focus:ring-transparent focus:outline-none"
"rounded-xl bg-slate-50 p-1 text-slate-600 transition-all hover:bg-slate-100 focus:outline-none focus:ring-0 focus:ring-transparent"
)}>
{isCollapsed ? (
<PanelLeftOpenIcon strokeWidth={1.5} />

View File

@@ -118,7 +118,7 @@ const Page = async (props) => {
<div className="relative isolate mt-8 overflow-hidden rounded-lg bg-slate-900 px-3 pt-8 shadow-2xl sm:px-8 md:pt-12 lg:flex lg:gap-x-10 lg:px-12 lg:pt-0">
<svg
viewBox="0 0 1024 1024"
className="absolute top-1/2 left-1/2 -z-10 h-[64rem] w-[64rem] -translate-y-1/2 [mask-image:radial-gradient(closest-side,white,transparent)] sm:left-full sm:-ml-80 lg:left-1/2 lg:ml-0 lg:-translate-x-1/2 lg:translate-y-0"
className="absolute left-1/2 top-1/2 -z-10 h-[64rem] w-[64rem] -translate-y-1/2 [mask-image:radial-gradient(closest-side,white,transparent)] sm:left-full sm:-ml-80 lg:left-1/2 lg:ml-0 lg:-translate-x-1/2 lg:translate-y-0"
aria-hidden="true">
<circle
cx={512}

View File

@@ -38,7 +38,7 @@ export const ResponseTableCell = ({
<button
type="button"
aria-label="Expand response"
className="hidden flex-shrink-0 cursor-pointer items-center rounded-md border border-slate-200 bg-white p-2 group-hover:flex hover:border-slate-300 focus:outline-none"
className="hidden flex-shrink-0 cursor-pointer items-center rounded-md border border-slate-200 bg-white p-2 hover:border-slate-300 focus:outline-none group-hover:flex"
onClick={handleCellClick}>
<Maximize2Icon className="h-4 w-4" />
</button>

View File

@@ -41,7 +41,7 @@ export const ConsentSummary = ({ questionSummary, survey, setFilter }: ConsentSu
return (
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
<QuestionSummaryHeader questionSummary={questionSummary} survey={survey} />
<div className="space-y-5 px-4 pt-4 pb-6 text-sm md:px-6 md:text-base">
<div className="space-y-5 px-4 pb-6 pt-4 text-sm md:px-6 md:text-base">
{summaryItems.map((summaryItem) => {
return (
<button

View File

@@ -80,7 +80,7 @@ export const FileUploadSummary = ({
return (
<div className="relative m-2 rounded-lg bg-slate-200" key={fileUrl}>
<a href={fileUrl} key={fileUrl} target="_blank" rel="noopener noreferrer">
<div className="absolute top-0 right-0 m-2">
<div className="absolute right-0 top-0 m-2">
<div className="flex h-8 w-8 items-center justify-center rounded-lg bg-slate-50 hover:bg-white">
<DownloadIcon className="h-6 text-slate-500" />
</div>

View File

@@ -52,7 +52,7 @@ export const MatrixQuestionSummary = ({ questionSummary, survey, setFilter }: Ma
<table className="mx-auto border-collapse cursor-default text-left">
<thead>
<tr>
<th className="p-4 pt-0 pb-3 font-medium text-slate-400 dark:border-slate-600 dark:text-slate-200"></th>
<th className="p-4 pb-3 pt-0 font-medium text-slate-400 dark:border-slate-600 dark:text-slate-200"></th>
{columns.map((column) => (
<th key={column} className="text-center font-medium">
<TooltipRenderer tooltipContent={getTooltipContent(column)} shouldRender={true}>
@@ -65,7 +65,7 @@ export const MatrixQuestionSummary = ({ questionSummary, survey, setFilter }: Ma
<tbody>
{questionSummary.data.map(({ rowLabel, columnPercentages }, rowIndex) => (
<tr key={rowLabel}>
<td className="max-w-60 overflow-hidden p-4 text-ellipsis whitespace-nowrap">
<td className="max-w-60 overflow-hidden text-ellipsis whitespace-nowrap p-4">
<TooltipRenderer tooltipContent={getTooltipContent(rowLabel)} shouldRender={true}>
<p className="max-w-40 overflow-hidden text-ellipsis whitespace-nowrap">{rowLabel}</p>
</TooltipRenderer>

View File

@@ -83,7 +83,7 @@ export const MultipleChoiceSummary = ({
) : undefined
}
/>
<div className="space-y-5 px-4 pt-4 pb-6 text-sm md:px-6 md:text-base">
<div className="space-y-5 px-4 pb-6 pt-4 text-sm md:px-6 md:text-base">
{results.map((result, resultsIdx) => (
<Fragment key={result.value}>
<button

View File

@@ -62,7 +62,7 @@ export const NPSSummary = ({ questionSummary, survey, setFilter }: NPSSummaryPro
return (
<div className="rounded-xl border border-slate-200 bg-white shadow-sm">
<QuestionSummaryHeader questionSummary={questionSummary} survey={survey} />
<div className="space-y-5 px-4 pt-4 pb-6 text-sm md:px-6 md:text-base">
<div className="space-y-5 px-4 pb-6 pt-4 text-sm md:px-6 md:text-base">
{["promoters", "passives", "detractors", "dismissed"].map((group) => (
<button
className="w-full cursor-pointer hover:opacity-80"
@@ -72,7 +72,7 @@ export const NPSSummary = ({ questionSummary, survey, setFilter }: NPSSummaryPro
className={`mb-2 flex justify-between ${group === "dismissed" ? "mb-2 border-t bg-white pt-4 text-sm md:text-base" : ""}`}>
<div className="mr-8 flex space-x-1">
<p
className={`font-semibold text-slate-700 capitalize ${group === "dismissed" ? "" : "text-slate-700"}`}>
className={`font-semibold capitalize text-slate-700 ${group === "dismissed" ? "" : "text-slate-700"}`}>
{group}
</p>
<div>
@@ -94,7 +94,7 @@ export const NPSSummary = ({ questionSummary, survey, setFilter }: NPSSummaryPro
))}
</div>
<div className="flex justify-center pt-4 pb-4">
<div className="flex justify-center pb-4 pt-4">
<HalfCircle value={questionSummary.score} />
</div>
</div>

View File

@@ -43,7 +43,7 @@ export const PictureChoiceSummary = ({ questionSummary, survey, setFilter }: Pic
) : undefined
}
/>
<div className="space-y-5 px-4 pt-4 pb-6 text-sm md:px-6 md:text-base">
<div className="space-y-5 px-4 pb-6 pt-4 text-sm md:px-6 md:text-base">
{results.map((result, index) => (
<button
className="w-full cursor-pointer hover:opacity-80"

View File

@@ -50,7 +50,7 @@ export const RatingSummary = ({ questionSummary, survey, setFilter }: RatingSumm
</div>
}
/>
<div className="space-y-5 px-4 pt-4 pb-6 text-sm md:px-6 md:text-base">
<div className="space-y-5 px-4 pb-6 pt-4 text-sm md:px-6 md:text-base">
{questionSummary.choices.map((result) => (
<button
className="w-full cursor-pointer hover:opacity-80"

View File

@@ -91,7 +91,7 @@ export const QuestionFilterComboBox = ({
key={`${o}-${index}`}
type="button"
onClick={() => handleRemoveMultiSelect(filterComboBoxValue.filter((i) => i !== o))}
className="flex w-30 items-center bg-slate-100 px-2 whitespace-nowrap text-slate-600">
className="w-30 flex items-center whitespace-nowrap bg-slate-100 px-2 text-slate-600">
{o}
<X width={14} height={14} className="ml-2" />
</button>
@@ -129,7 +129,7 @@ export const QuestionFilterComboBox = ({
<DropdownMenuTrigger
disabled={disabled}
className={clsx(
"h-9 max-w-fit rounded-md rounded-r-none border-r-[1px] border-slate-300 bg-white p-2 text-sm text-slate-600 focus:ring-0 focus:outline-transparent",
"h-9 max-w-fit rounded-md rounded-r-none border-r-[1px] border-slate-300 bg-white p-2 text-sm text-slate-600 focus:outline-transparent focus:ring-0",
!disabled ? "cursor-pointer" : "opacity-50"
)}>
<div className="flex items-center justify-between">

View File

@@ -164,7 +164,7 @@ export const QuestionsComboBox = ({ options, selected, onChangeValue }: Question
value={inputValue}
onValueChange={setInputValue}
placeholder={t("common.search") + "..."}
className="h-5 border-none border-transparent p-0 shadow-none ring-offset-transparent outline-0 focus:border-none focus:border-transparent focus:shadow-none focus:ring-offset-transparent focus:outline-0"
className="h-5 border-none border-transparent p-0 shadow-none outline-0 ring-offset-transparent focus:border-none focus:border-transparent focus:shadow-none focus:outline-0 focus:ring-offset-transparent"
/>
)}
<div>

View File

@@ -312,7 +312,7 @@ function AttributeSegmentFilter({
}}
value={attrKeyValue}>
<SelectTrigger
className="flex w-auto items-center justify-center bg-white whitespace-nowrap capitalize"
className="flex w-auto items-center justify-center whitespace-nowrap bg-white capitalize"
hideArrow>
<SelectValue>
<div className={cn("flex items-center gap-2", !isCapitalized(attrKeyValue ?? "") && "lowercase")}>
@@ -494,7 +494,7 @@ function PersonSegmentFilter({
}}
value={personIdentifier}>
<SelectTrigger
className="flex w-auto items-center justify-center bg-white whitespace-nowrap capitalize"
className="flex w-auto items-center justify-center whitespace-nowrap bg-white capitalize"
hideArrow>
<SelectValue>
<div className="flex items-center gap-1 lowercase">
@@ -643,7 +643,7 @@ function SegmentSegmentFilter({
}}
value={currentSegment?.id}>
<SelectTrigger
className="flex w-auto items-center justify-center bg-white whitespace-nowrap capitalize"
className="flex w-auto items-center justify-center whitespace-nowrap bg-white capitalize"
hideArrow>
<div className="flex items-center gap-1">
<Users2Icon className="h-4 w-4 text-sm" />

View File

@@ -207,7 +207,7 @@ export const TeamSettingsModal = ({
<div className="sticky top-0 flex h-full flex-col rounded-lg">
<button
className={cn(
"absolute top-0 right-0 hidden pt-4 pr-4 text-slate-400 hover:text-slate-500 focus:ring-0 focus:outline-none sm:block"
"absolute right-0 top-0 hidden pr-4 pt-4 text-slate-400 hover:text-slate-500 focus:outline-none focus:ring-0 sm:block"
)}
onClick={closeSettingsModal}>
<XIcon className="h-6 w-6 rounded-md bg-white" />

View File

@@ -10,7 +10,7 @@ const LoadingCard = () => {
return (
<div className="w-full max-w-4xl rounded-xl border border-slate-200 bg-white py-4 shadow-sm">
<div className="grid content-center border-b border-slate-200 px-4 pb-4 text-left text-slate-900">
<h3 className="h-6 w-full max-w-56 animate-pulse rounded-lg bg-slate-100 text-lg leading-6 font-medium">
<h3 className="h-6 w-full max-w-56 animate-pulse rounded-lg bg-slate-100 text-lg font-medium leading-6">
<span className="sr-only">{t("common.loading")}</span>
</h3>
<p className="mt-3 h-4 w-full max-w-80 animate-pulse rounded-lg bg-slate-100 text-sm text-slate-500">

View File

@@ -105,7 +105,7 @@ export const TemplateList = ({
};
return (
<main className="relative z-0 flex-1 overflow-y-auto px-6 pt-2 pb-6 focus:outline-none">
<main className="relative z-0 flex-1 overflow-y-auto px-6 pb-6 pt-2 focus:outline-none">
{showFilters && !templateSearch && (
<TemplateFilters
selectedFilter={selectedFilter}

View File

@@ -88,7 +88,7 @@ export const AnimatedSurveyBg = ({ handleBgChange, background }: AnimatedSurveyB
<source src={`${key}`} type="video/mp4" />
</video>
<input
className="absolute top-2 right-2 h-4 w-4 rounded-sm bg-white"
className="absolute right-2 top-2 h-4 w-4 rounded-sm bg-white"
type="checkbox"
checked={animation === value}
onChange={() => handleBg(value)}

View File

@@ -67,7 +67,7 @@ export const EditWelcomeCard = ({
<div
className={cn(
open ? "bg-slate-50" : "",
"flex w-10 items-center justify-center rounded-l-lg border-t border-b border-l group-aria-expanded:rounded-bl-none",
"flex w-10 items-center justify-center rounded-l-lg border-b border-l border-t group-aria-expanded:rounded-bl-none",
isInvalid ? "bg-red-400" : "bg-white group-hover:bg-slate-50"
)}>
<Hand className="h-4 w-4" />

View File

@@ -178,7 +178,7 @@ export const FileUploadQuestionForm = ({
</Button>
)}
</div>
<div className="mt-6 mb-8 space-y-6">
<div className="mb-8 mt-6 space-y-6">
<AdvancedOptionToggle
isChecked={question.allowMultipleFiles}
onToggle={() => updateQuestion(questionIdx, { allowMultipleFiles: !question.allowMultipleFiles })}
@@ -218,7 +218,7 @@ export const FileUploadQuestionForm = ({
updateQuestion(questionIdx, { maxSizeInMB: parseInt(e.target.value, 10) });
}}
className="mr-2 ml-2 inline w-20 bg-white text-center text-sm"
className="ml-2 mr-2 inline w-20 bg-white text-center text-sm"
/>
MB
</p>

View File

@@ -113,7 +113,7 @@ export const HiddenFieldsCard = ({
<div
className={cn(
open ? "bg-slate-50" : "bg-white group-hover:bg-slate-50",
"flex w-10 items-center justify-center rounded-l-lg border-t border-b border-l group-aria-expanded:rounded-bl-none"
"flex w-10 items-center justify-center rounded-l-lg border-b border-l border-t group-aria-expanded:rounded-bl-none"
)}>
<EyeOff className="h-4 w-4" />
</div>
@@ -161,7 +161,7 @@ export const HiddenFieldsCard = ({
);
})
) : (
<p className="mt-2 text-sm text-slate-500 italic">
<p className="mt-2 text-sm italic text-slate-500">
{t("environments.surveys.edit.no_hidden_fields_yet_add_first_one_below")}
</p>
)}

View File

@@ -106,7 +106,7 @@ export const HowToSendCard = ({ localSurvey, setLocalSurvey, environment }: HowT
className="h-full w-full cursor-pointer"
id="howToSendCardTrigger">
<div className="inline-flex px-4 py-4">
<div className="flex items-center pr-5 pl-2">
<div className="flex items-center pl-2 pr-5">
<CheckIcon
strokeWidth={3}
className="h-7 w-7 rounded-full border border-green-300 bg-green-100 p-1.5 text-green-600"

View File

@@ -196,7 +196,7 @@ export const QuestionCard = ({
)}>
<div className="mt-3 flex w-full justify-center">{QUESTIONS_ICON_MAP[question.type]}</div>
<button className="opacity-0 group-hover:opacity-100 hover:cursor-move">
<button className="opacity-0 hover:cursor-move group-hover:opacity-100">
<GripIcon className="h-4 w-4" />
</button>
</div>

View File

@@ -121,7 +121,7 @@ export const RecontactOptionsCard = ({
className="h-full w-full cursor-pointer rounded-lg hover:bg-slate-50"
id="recontactOptionsCardTrigger">
<div className="inline-flex px-4 py-4">
<div className="flex items-center pr-5 pl-2">
<div className="flex items-center pl-2 pr-5">
<CheckIcon
strokeWidth={3}
className="h-7 w-7 rounded-full border border-green-300 bg-green-100 p-1.5 text-green-600"
@@ -256,7 +256,7 @@ export const RecontactOptionsCard = ({
id="inputDays"
value={inputDays === 0 ? 1 : inputDays}
onChange={handleRecontactDaysChange}
className="mr-2 ml-2 inline w-16 bg-white text-center text-sm"
className="ml-2 mr-2 inline w-16 bg-white text-center text-sm"
/>
{t("environments.surveys.edit.days_before_showing_this_survey_again")}.
</p>

View File

@@ -318,7 +318,7 @@ export const ResponseOptionsCard = ({
)}>
<Collapsible.CollapsibleTrigger asChild className="h-full w-full cursor-pointer">
<div className="inline-flex px-4 py-4">
<div className="flex items-center pr-5 pl-2">
<div className="flex items-center pl-2 pr-5">
<CheckIcon
strokeWidth={3}
className="h-7 w-7 rounded-full border border-green-300 bg-green-100 p-1.5 text-green-600"
@@ -356,7 +356,7 @@ export const ResponseOptionsCard = ({
value={localSurvey.autoComplete?.toString()}
onChange={handleInputResponse}
onBlur={handleInputResponseBlur}
className="mr-2 ml-2 inline w-20 bg-white text-center text-sm"
className="ml-2 mr-2 inline w-20 bg-white text-center text-sm"
/>
{t("environments.surveys.edit.completed_responses")}
</p>
@@ -451,7 +451,7 @@ export const ResponseOptionsCard = ({
<Input
autoFocus
id="heading"
className="mt-2 mb-4 bg-white"
className="mb-4 mt-2 bg-white"
name="heading"
defaultValue={surveyClosedMessage.heading}
onChange={(e) => handleClosedSurveyMessageChange({ heading: e.target.value })}
@@ -506,7 +506,7 @@ export const ResponseOptionsCard = ({
<Input
autoFocus
id="heading"
className="mt-2 mb-4 bg-white"
className="mb-4 mt-2 bg-white"
name="heading"
value={singleUseMessage.heading}
onChange={(e) => handleSingleUseSurveyMessageChange({ heading: e.target.value })}
@@ -514,7 +514,7 @@ export const ResponseOptionsCard = ({
<Label htmlFor="headline">{t("environments.surveys.edit.subheading")}</Label>
<Input
className="mt-2 mb-4 bg-white"
className="mb-4 mt-2 bg-white"
id="subheading"
name="subheading"
value={singleUseMessage.subheading}

View File

@@ -64,7 +64,7 @@ export const SavedActionsTab = ({
(actions, i) =>
actions.length > 0 && (
<div key={i} className="me-4">
<h2 className="mt-4 mb-2 font-semibold">
<h2 className="mb-2 mt-4 font-semibold">
{i === 0 ? t("common.no_code") : t("common.code")}
</h2>
<div className="flex flex-col gap-2">

View File

@@ -329,7 +329,7 @@ export const SurveyMenuBar = ({
/>
</div>
<div className="mt-3 flex items-center gap-2 sm:mt-0 sm:ml-4">
<div className="mt-3 flex items-center gap-2 sm:ml-4 sm:mt-0">
{responseCount > 0 && (
<div>
<Alert variant="warning" size="small">

View File

@@ -91,7 +91,7 @@ export const SurveyPlacementCard = ({
asChild
className="h-full w-full cursor-pointer rounded-lg hover:bg-slate-50">
<div className="inline-flex px-4 py-4">
<div className="flex items-center pr-5 pl-2">
<div className="flex items-center pl-2 pr-5">
<CheckIcon
strokeWidth={3}
className="h-7 w-7 rounded-full border border-green-300 bg-green-100 p-1.5 text-green-600"

View File

@@ -41,7 +41,7 @@ export const SurveyVariablesCard = ({
<div
className={cn(
open ? "bg-slate-50" : "bg-white group-hover:bg-slate-50",
"flex w-10 items-center justify-center rounded-l-lg border-t border-b border-l group-aria-expanded:rounded-bl-none"
"flex w-10 items-center justify-center rounded-l-lg border-b border-l border-t group-aria-expanded:rounded-bl-none"
)}>
<div className="flex w-full justify-center">
<FileDigitIcon className="h-4 w-4" />
@@ -75,7 +75,7 @@ export const SurveyVariablesCard = ({
/>
))
) : (
<p className="mt-2 text-sm text-slate-500 italic">
<p className="mt-2 text-sm italic text-slate-500">
{t("environments.surveys.edit.no_variables_yet_add_first_one_below")}
</p>
)}

View File

@@ -24,7 +24,7 @@ export const TargetingLockedCard = ({ isFormbricksCloud, environmentId }: Target
asChild
className="h-full w-full cursor-pointer rounded-lg hover:bg-slate-50">
<div className="inline-flex px-4 py-6">
<div className="flex items-center pr-5 pl-2">
<div className="flex items-center pl-2 pr-5">
<div className="rounded-full border border-slate-300 bg-slate-100 p-1">
<LockIcon className="h-4 w-4 text-slate-500" strokeWidth={3} />
</div>

View File

@@ -192,7 +192,7 @@ export const ImageFromUnsplashSurveyBg = ({ handleBgChange }: ImageFromUnsplashS
return (
<div className="relative mt-2 w-full">
<div className="relative">
<SearchIcon className="absolute top-1/2 left-2 h-6 w-4 -translate-y-1/2 text-slate-500" />
<SearchIcon className="absolute left-2 top-1/2 h-6 w-4 -translate-y-1/2 text-slate-500" />
<Input
value={query}
onChange={handleChange}
@@ -215,7 +215,7 @@ export const ImageFromUnsplashSurveyBg = ({ handleBgChange }: ImageFromUnsplashS
className="h-full cursor-pointer rounded-lg object-cover"
/>
{image.authorName && (
<span className="bg-opacity-75 absolute right-1 bottom-1 hidden rounded bg-black px-2 py-1 text-xs text-white group-hover:block">
<span className="absolute bottom-1 right-1 hidden rounded bg-black bg-opacity-75 px-2 py-1 text-xs text-white group-hover:block">
{image.authorName}
</span>
)}

View File

@@ -75,7 +75,7 @@ const FollowUpActionMultiEmailInput = ({
<span className="text-slate-900">{email}</span>
<button
onClick={() => removeEmail(index)}
className="px-1 text-lg leading-none font-medium text-slate-500">
className="px-1 text-lg font-medium leading-none text-slate-500">
×
</button>
</div>

View File

@@ -98,11 +98,11 @@ export const CopySurveyForm = ({ defaultProjects, survey, onCancel, setOpen }: I
field.onChange([...field.value, environment.id]);
}
}}
className="focus:ring-opacity-50 mr-2 h-4 w-4 appearance-none border-slate-300 checked:border-transparent checked:bg-slate-500 checked:after:bg-slate-500 checked:hover:bg-slate-500 focus:ring-2 focus:ring-slate-500"
className="mr-2 h-4 w-4 appearance-none border-slate-300 checked:border-transparent checked:bg-slate-500 checked:after:bg-slate-500 checked:hover:bg-slate-500 focus:ring-2 focus:ring-slate-500 focus:ring-opacity-50"
id={environment.id}
/>
<Label htmlFor={environment.id}>
<p className="text-sm font-medium text-slate-900 capitalize">
<p className="text-sm font-medium capitalize text-slate-900">
{environment.type}
</p>
</Label>
@@ -121,8 +121,8 @@ export const CopySurveyForm = ({ defaultProjects, survey, onCancel, setOpen }: I
);
})}
</div>
<div className="fixed right-0 bottom-0 left-0 z-10 flex w-full justify-end space-x-2 bg-white">
<div className="flex w-full justify-end pr-4 pb-4">
<div className="fixed bottom-0 left-0 right-0 z-10 flex w-full justify-end space-x-2 bg-white">
<div className="flex w-full justify-end pb-4 pr-4">
<Button type="button" onClick={onCancel} variant="ghost">
{t("common.cancel")}
</Button>

View File

@@ -32,7 +32,7 @@ vi.mock("@/modules/ui/components/checkbox", () => ({
id={id}
data-testid={id}
name={props.name}
className="focus:ring-opacity-50 mr-2 h-4 w-4 appearance-none border-slate-300 checked:border-transparent checked:bg-slate-500 checked:after:bg-slate-500 checked:hover:bg-slate-500 focus:ring-2 focus:ring-slate-500"
className="mr-2 h-4 w-4 appearance-none border-slate-300 checked:border-transparent checked:bg-slate-500 checked:after:bg-slate-500 checked:hover:bg-slate-500 focus:ring-2 focus:ring-slate-500 focus:ring-opacity-50"
onChange={() => {
// Call onCheckedChange with true to simulate checkbox selection
onCheckedChange(true);

View File

@@ -37,7 +37,7 @@ export const TemplateContainerWithPreview = ({
<MenuBar />
<div className="relative z-0 flex flex-1 overflow-hidden">
<div className="flex-1 flex-col overflow-auto bg-slate-50">
<div className="mt-6 mb-3 ml-6 flex flex-col items-center justify-between md:flex-row md:items-end">
<div className="mb-3 ml-6 mt-6 flex flex-col items-center justify-between md:flex-row md:items-end">
<h1 className="text-2xl font-bold text-slate-800">
{t("environments.surveys.templates.create_a_new_survey")}
</h1>

View File

@@ -57,7 +57,7 @@ const CardTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HT
return (
<h3
ref={ref}
className={cn("text-2xl leading-none font-semibold tracking-tight", className)}
className={cn("text-2xl font-semibold leading-none tracking-tight", className)}
{...props}>
{headingContent}
</h3>

View File

@@ -13,7 +13,7 @@ const DialogOverlay = React.forwardRef<
ref={ref}
className={cn(
blur && "backdrop-blur-md",
"bg-opacity-30 fixed inset-0 z-50",
"fixed inset-0 z-50 bg-opacity-30",
"data-[state='closed']:animate-fadeOut data-[state='open']:animate-fadeIn"
)}
{...props}
@@ -58,8 +58,8 @@ const DialogContent = React.forwardRef<
<DialogPrimitive.Content
ref={ref}
className={cn(
"fixed top-[50%] left-[50%] z-50 translate-x-[-50%] translate-y-[-50%] transform rounded-lg bg-white text-left shadow-xl transition-all sm:my-2 sm:w-full sm:max-w-xl",
`${noPadding ? "" : "px-4 pt-5 pb-4 sm:p-6"}`,
"fixed left-[50%] top-[50%] z-50 translate-x-[-50%] translate-y-[-50%] transform rounded-lg bg-white text-left shadow-xl transition-all sm:my-2 sm:w-full sm:max-w-xl",
`${noPadding ? "" : "px-4 pb-4 pt-5 sm:p-6"}`,
"data-[state='closed']:animate-fadeOut data-[state='open']:animate-fadeIn",
size && sizeClassName && sizeClassName[size],
!restrictOverflow && "overflow-hidden",
@@ -78,7 +78,7 @@ const DialogContent = React.forwardRef<
{children}
<DialogPrimitive.Close
className={cn(
"absolute top-0 right-0 hidden pt-4 pr-4 text-slate-400 hover:text-slate-500 focus:ring-0 focus:outline-none sm:block",
"absolute right-0 top-0 hidden pr-4 pt-4 text-slate-400 hover:text-slate-500 focus:outline-none focus:ring-0 sm:block",
hideCloseButton && "!hidden"
)}>
<XIcon className="h-6 w-6 rounded-md bg-white" />

View File

@@ -246,10 +246,10 @@ export const PreviewSurvey = ({
className="relative flex h-full w-[95%] items-center justify-center rounded-lg border border-slate-300 bg-slate-200">
{previewMode === "mobile" && (
<>
<p className="absolute top-0 left-0 m-2 rounded bg-slate-100 px-2 py-1 text-xs text-slate-400">
<p className="absolute left-0 top-0 m-2 rounded bg-slate-100 px-2 py-1 text-xs text-slate-400">
Preview
</p>
<div className="absolute top-0 right-0 m-2">
<div className="absolute right-0 top-0 m-2">
<ResetProgressButton onClick={resetQuestionProgress} />
</div>
<MediaBackground
@@ -284,7 +284,7 @@ export const PreviewSurvey = ({
</Modal>
) : (
<div className="flex h-full w-full flex-col justify-center px-1">
<div className="absolute top-5 left-5">
<div className="absolute left-5 top-5">
{!styling.isLogoHidden && (
<ClientLogo environmentId={environment.id} projectLogo={project.logo} previewSurvey />
)}
@@ -392,7 +392,7 @@ export const PreviewSurvey = ({
styling={styling}
ContentRef={ContentRef as React.RefObject<HTMLDivElement>}
isEditorView>
<div className="absolute top-5 left-5">
<div className="absolute left-5 top-5">
{!styling.isLogoHidden && (
<ClientLogo environmentId={environment.id} projectLogo={project.logo} previewSurvey />
)}

View File

@@ -1,6 +1,7 @@
{
"name": "@formbricks/web",
"version": "0.0.0",
"packageManager": "pnpm@9.15.0",
"private": true,
"scripts": {
"clean": "rimraf .turbo node_modules .next coverage",

View File

@@ -1,5 +1,6 @@
{
"name": "@formbricks/database",
"packageManager": "pnpm@9.15.0",
"private": true,
"version": "0.1.0",
"main": "./src/index.ts",