diff --git a/apps/web/next.config.js b/apps/web/next.config.js
index 7393ba932..e1849c0ee 100644
--- a/apps/web/next.config.js
+++ b/apps/web/next.config.js
@@ -10,7 +10,6 @@ const withBundleAnalyzer = require("@next/bundle-analyzer")({
/** @type {import('next').NextConfig} */
const nextConfig = {
- output: "standalone",
productionBrowserSourceMaps: true,
transpilePackages: [
"@rallly/backend",
diff --git a/apps/web/public/locales/en/app.json b/apps/web/public/locales/en/app.json
index 9636e9617..b991a71c5 100644
--- a/apps/web/public/locales/en/app.json
+++ b/apps/web/public/locales/en/app.json
@@ -221,7 +221,6 @@
"integrations": "Integrations",
"contacts": "Contacts",
"unlockFeatures": "Unlock all Pro features.",
- "back": "Back",
"pollStatusAll": "All",
"pollStatusLive": "Live",
"pollStatusFinalized": "Finalized",
@@ -238,5 +237,8 @@
"registrations": "Registrations",
"inviteParticipantsDescription": "Copy and share the invite link to start gathering responses from your participants.",
"inviteLink": "Invite Link",
- "inviteParticipantLinkInfo": "Anyone with this link will be able to vote on your poll."
+ "inviteParticipantLinkInfo": "Anyone with this link will be able to vote on your poll.",
+ "accountNotLinkedTitle": "Your account cannot be linked to an existing user",
+ "accountNotLinkedDescription": "A user with this email already exists. Please log in using the original method.",
+ "or": "Or"
}
diff --git a/apps/web/public/static/microsoft.svg b/apps/web/public/static/microsoft.svg
new file mode 100644
index 000000000..1f7397648
--- /dev/null
+++ b/apps/web/public/static/microsoft.svg
@@ -0,0 +1 @@
+
\ No newline at end of file
diff --git a/apps/web/src/app/[locale]/(auth)/login/login-form.tsx b/apps/web/src/app/[locale]/(auth)/login/login-form.tsx
index 834044f29..161abd2ed 100644
--- a/apps/web/src/app/[locale]/(auth)/login/login-form.tsx
+++ b/apps/web/src/app/[locale]/(auth)/login/login-form.tsx
@@ -1,7 +1,8 @@
"use client";
+import { Alert, AlertDescription, AlertTitle } from "@rallly/ui/alert";
import { Button } from "@rallly/ui/button";
import { useQuery } from "@tanstack/react-query";
-import { UserIcon } from "lucide-react";
+import { AlertTriangleIcon, UserIcon } from "lucide-react";
import Image from "next/image";
import { useRouter, useSearchParams } from "next/navigation";
import { getProviders, signIn, useSession } from "next-auth/react";
@@ -21,6 +22,7 @@ const allowGuestAccess = !isSelfHosted;
export function LoginForm() {
const { t } = useTranslation();
+ const searchParams = useSearchParams();
const { register, handleSubmit, getValues, formState, setError } = useForm<{
email: string;
@@ -38,21 +40,13 @@ export function LoginForm() {
const [email, setEmail] = React.useState();
const posthog = usePostHog();
const router = useRouter();
- const callbackUrl = (useSearchParams()?.get("callbackUrl") as string) ?? "/";
+ const callbackUrl = searchParams?.get("callbackUrl") ?? "/";
+
+ const error = searchParams?.get("error");
const alternativeLoginMethods = React.useMemo(() => {
const res: Array<{ login: () => void; icon: JSX.Element; name: string }> =
[];
- if (allowGuestAccess) {
- res.push({
- login: () => {
- router.push(callbackUrl);
- },
- icon: ,
- name: t("continueAsGuest"),
- });
- }
-
if (providers?.oidc) {
res.push({
login: () => {
@@ -78,6 +72,35 @@ export function LoginForm() {
name: t("loginWith", { provider: providers.google.name }),
});
}
+
+ if (providers?.["azure-ad"]) {
+ res.push({
+ login: () => {
+ signIn("azure-ad", {
+ callbackUrl,
+ });
+ },
+ icon: (
+
+ ),
+ name: t("loginWith", { provider: "Microsoft" }),
+ });
+ }
+
+ if (allowGuestAccess) {
+ res.push({
+ login: () => {
+ router.push(callbackUrl);
+ },
+ icon: ,
+ name: t("continueAsGuest"),
+ });
+ }
return res;
}, [callbackUrl, providers, router, t]);
@@ -148,7 +171,7 @@ export function LoginForm() {
total: 2,
})}
-