Merge branch 'main' of github.com:formbricks/formbricks into feature/integrations

This commit is contained in:
Johannes
2023-07-11 16:02:04 +02:00
183 changed files with 3806 additions and 3441 deletions
+1 -1
View File
@@ -28,7 +28,7 @@ export default function IsPasswordValid({
useEffect(() => {
let newValidations = [...DEFAULT_VALIDATIONS];
if (password) {
if (password !== null) {
newValidations = checkValidation(newValidations, 0, PASSWORD_REGEX.UPPER_AND_LOWER.test(password));
newValidations = checkValidation(newValidations, 1, password.length >= 8);
newValidations = checkValidation(newValidations, 2, PASSWORD_REGEX.NUMBER.test(password));
@@ -9,14 +9,18 @@ import { useState } from "react";
export const PasswordResetForm = ({}) => {
const router = useRouter();
const [error, setError] = useState<string>("");
const [loading, setLoading] = useState<boolean>(false);
const handleSubmit = async (e) => {
e.preventDefault();
setLoading(true);
try {
await forgotPassword(e.target.elements.email.value);
router.push("/auth/forgot-password/email-sent");
} catch (e) {
setError(e.message);
} finally {
setLoading(false);
}
};
@@ -55,7 +59,7 @@ export const PasswordResetForm = ({}) => {
</div>
<div>
<Button type="submit" className="w-full justify-center">
<Button type="submit" variant="darkCTA" className="w-full justify-center" loading={loading}>
Reset password
</Button>
<div className="mt-3 text-center">
+20 -4
View File
@@ -1,7 +1,8 @@
"use client";
import IsPasswordValid from "@/components/auth/IsPasswordValid";
import { resetPassword } from "@/lib/users/users";
import { Button } from "@formbricks/ui";
import { Button, PasswordInput } from "@formbricks/ui";
import { XCircleIcon } from "@heroicons/react/24/solid";
import { useRouter, useSearchParams } from "next/navigation";
import { useState } from "react";
@@ -10,9 +11,13 @@ export const ResetPasswordForm = () => {
const searchParams = useSearchParams();
const router = useRouter();
const [error, setError] = useState<string>("");
const [password, setPassword] = useState<string | null>(null);
const [isValid, setIsValid] = useState(false);
const [loading, setLoading] = useState<boolean>(false);
const handleSubmit = async (e) => {
e.preventDefault();
setLoading(true);
const token = searchParams?.get("token");
try {
if (!token) throw new Error("No token provided");
@@ -21,6 +26,8 @@ export const ResetPasswordForm = () => {
router.push("/auth/forgot-password/reset/success");
} catch (e) {
setError(e.message);
} finally {
setLoading(false);
}
};
@@ -47,18 +54,27 @@ export const ResetPasswordForm = () => {
New password
</label>
<div className="mt-1">
<input
<PasswordInput
id="password"
name="password"
type="password"
value={password ? password : ""}
onChange={(e) => setPassword(e.target.value)}
autoComplete="current-password"
placeholder="*******"
required
className="focus:border-brand focus:ring-brand block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
/>
<IsPasswordValid password={password} setIsValid={setIsValid} />
</div>
</div>
<div>
<Button type="submit" className="w-full justify-center">
<Button
type="submit"
variant="darkCTA"
disabled={!isValid}
className="w-full justify-center"
loading={loading}>
Reset password
</Button>
</div>
+5 -4
View File
@@ -1,6 +1,7 @@
"use client";
import { GoogleButton } from "@/components/auth/GoogleButton";
import { env } from "@/env.mjs";
import { Button, PasswordInput } from "@formbricks/ui";
import { XCircleIcon } from "@heroicons/react/24/solid";
import { signIn } from "next-auth/react";
@@ -75,7 +76,7 @@ export const SigninForm = () => {
className="focus:border-brand focus:ring-brand block w-full rounded-md border-slate-300 shadow-sm sm:text-sm"
/>
</div>
{process.env.NEXT_PUBLIC_PASSWORD_RESET_DISABLED !== "1" && isPasswordFocused && (
{env.NEXT_PUBLIC_PASSWORD_RESET_DISABLED !== "1" && isPasswordFocused && (
<div className="ml-1 text-right transition-all duration-500 ease-in-out">
<Link
href="/auth/forgot-password"
@@ -105,18 +106,18 @@ export const SigninForm = () => {
</Button>
</form>
{process.env.NEXT_PUBLIC_GOOGLE_AUTH_ENABLED === "1" && (
{env.NEXT_PUBLIC_GOOGLE_AUTH_ENABLED === "1" && (
<>
<GoogleButton />
</>
)}
{process.env.NEXT_PUBLIC_GITHUB_AUTH_ENABLED === "1" && (
{env.NEXT_PUBLIC_GITHUB_AUTH_ENABLED === "1" && (
<>
<GithubButton />
</>
)}
</div>
{process.env.NEXT_PUBLIC_SIGNUP_DISABLED !== "1" && (
{env.NEXT_PUBLIC_SIGNUP_DISABLED !== "1" && (
<div className="mt-9 text-center text-xs ">
<span className="leading-5 text-slate-500">New to Formbricks?</span>
<br />
+14 -14
View File
@@ -1,15 +1,15 @@
"use client";
import { Button } from "@formbricks/ui";
import { PasswordInput } from "@formbricks/ui";
import { GoogleButton } from "@/components/auth/GoogleButton";
import IsPasswordValid from "@/components/auth/IsPasswordValid";
import { env } from "@/env.mjs";
import { createUser } from "@/lib/users/users";
import { Button, PasswordInput } from "@formbricks/ui";
import { XCircleIcon } from "@heroicons/react/24/solid";
import Link from "next/link";
import { useRouter, useSearchParams } from "next/navigation";
import { useRef, useState } from "react";
import { GithubButton } from "./GithubButton";
import { GoogleButton } from "@/components/auth/GoogleButton";
import IsPasswordValid from "@/components/auth/IsPasswordValid";
export const SignupForm = () => {
const searchParams = useSearchParams();
@@ -33,7 +33,7 @@ export const SignupForm = () => {
searchParams?.get("inviteToken")
);
const url =
process.env.NEXT_PUBLIC_EMAIL_VERIFICATION_DISABLED === "1"
env.NEXT_PUBLIC_EMAIL_VERIFICATION_DISABLED === "1"
? `/auth/signup-without-verification-success`
: `/auth/verification-requested?email=${encodeURIComponent(e.target.elements.email.value)}`;
@@ -131,7 +131,7 @@ export const SignupForm = () => {
className="focus:border-brand focus:ring-brand block w-full rounded-md shadow-sm sm:text-sm"
/>
</div>
{process.env.NEXT_PUBLIC_PASSWORD_RESET_DISABLED !== "1" && isPasswordFocused && (
{env.NEXT_PUBLIC_PASSWORD_RESET_DISABLED !== "1" && isPasswordFocused && (
<div className="ml-1 text-right transition-all duration-500 ease-in-out">
<Link
href="/auth/forgot-password"
@@ -163,36 +163,36 @@ export const SignupForm = () => {
</Button>
</form>
{process.env.NEXT_PUBLIC_GOOGLE_AUTH_ENABLED === "1" && (
{env.NEXT_PUBLIC_GOOGLE_AUTH_ENABLED === "1" && (
<>
<GoogleButton />
</>
)}
{process.env.NEXT_PUBLIC_GITHUB_AUTH_ENABLED === "1" && (
{env.NEXT_PUBLIC_GITHUB_AUTH_ENABLED === "1" && (
<>
<GithubButton />{" "}
</>
)}
</div>
{(process.env.NEXT_PUBLIC_TERMS_URL || process.env.NEXT_PUBLIC_PRIVACY_URL) && (
{(env.NEXT_PUBLIC_TERMS_URL || env.NEXT_PUBLIC_PRIVACY_URL) && (
<div className="mt-3 text-center text-xs text-slate-500">
By signing up, you agree to our
<br />
{process.env.NEXT_PUBLIC_TERMS_URL && (
{env.NEXT_PUBLIC_TERMS_URL && (
<Link
className="font-semibold"
href="google.com" /* {process.env.NEXT_PUBLIC_TERMS_URL} */
href="google.com" /* {env.NEXT_PUBLIC_TERMS_URL} */
rel="noreferrer"
target="_blank">
Terms of Service
</Link>
)}
{process.env.NEXT_PUBLIC_TERMS_URL && process.env.NEXT_PUBLIC_PRIVACY_URL && <span> and </span>}
{process.env.NEXT_PUBLIC_PRIVACY_URL && (
{env.NEXT_PUBLIC_TERMS_URL && env.NEXT_PUBLIC_PRIVACY_URL && <span> and </span>}
{env.NEXT_PUBLIC_PRIVACY_URL && (
<Link
className="font-semibold"
href="google.com" /* {/* process.env.NEXT_PUBLIC_PRIVACY_URL }*/
href="google.com" /* {/* env.NEXT_PUBLIC_PRIVACY_URL }*/
rel="noreferrer"
target="_blank">
Privacy Policy.
@@ -2,7 +2,7 @@ import { Input } from "@/../../packages/ui";
import SubmitButton from "@/components/preview/SubmitButton";
import { cn } from "@formbricks/lib/cn";
import type { MultipleChoiceSingleQuestion } from "@formbricks/types/questions";
import { useState } from "react";
import { useEffect, useRef, useState } from "react";
import Headline from "./Headline";
import Subheader from "./Subheader";
@@ -20,6 +20,13 @@ export default function MultipleChoiceSingleQuestion({
brandColor,
}: MultipleChoiceSingleProps) {
const [selectedChoice, setSelectedChoice] = useState<string | null>(null);
const otherSpecify = useRef<HTMLInputElement>(null);
useEffect(() => {
if (selectedChoice === "other") {
otherSpecify.current?.focus();
}
}, [selectedChoice]);
/* const [isIphone, setIsIphone] = useState(false);
@@ -31,7 +38,7 @@ export default function MultipleChoiceSingleQuestion({
<form
onSubmit={(e) => {
e.preventDefault();
const value = e.currentTarget[question.id].value;
const value = otherSpecify.current?.value || e.currentTarget[question.id].value;
const data = {
[question.id]: value,
};
@@ -72,6 +79,7 @@ export default function MultipleChoiceSingleQuestion({
{choice.id === "other" && selectedChoice === "other" && (
<Input
id={`${choice.id}-label`}
ref={otherSpecify}
name={question.id}
placeholder="Please specify"
className="mt-3 bg-white focus:border-slate-300"
+7 -6
View File
@@ -1,18 +1,19 @@
import { env } from "@/env.mjs";
import Link from "next/link";
export default function LegalFooter() {
if (!process.env.NEXT_PUBLIC_IMPRINT_URL && !process.env.NEXT_PUBLIC_PRIVACY_URL) return null;
if (!env.NEXT_PUBLIC_IMPRINT_URL && !env.NEXT_PUBLIC_PRIVACY_URL) return null;
return (
<div className="top-0 z-10 w-full border-b bg-white">
<div className="mx-auto max-w-lg p-3 text-center text-sm text-slate-400">
{process.env.NEXT_PUBLIC_IMPRINT_URL && (
<Link href={process.env.NEXT_PUBLIC_IMPRINT_URL} target="_blank">
{env.NEXT_PUBLIC_IMPRINT_URL && (
<Link href={env.NEXT_PUBLIC_IMPRINT_URL} target="_blank">
Imprint
</Link>
)}
{process.env.NEXT_PUBLIC_IMPRINT_URL && process.env.NEXT_PUBLIC_PRIVACY_URL && <span> | </span>}
{process.env.NEXT_PUBLIC_PRIVACY_URL && (
<Link href={process.env.NEXT_PUBLIC_PRIVACY_URL} target="_blank">
{env.NEXT_PUBLIC_IMPRINT_URL && env.NEXT_PUBLIC_PRIVACY_URL && <span> | </span>}
{env.NEXT_PUBLIC_PRIVACY_URL && (
<Link href={env.NEXT_PUBLIC_PRIVACY_URL} target="_blank">
Privacy Policy
</Link>
)}