diff --git a/samples/msal-custom-auth-samples/react-demo/challenge.tsx b/samples/msal-custom-auth-samples/react-demo/challenge.tsx
new file mode 100644
index 0000000000..9038b48c4c
--- /dev/null
+++ b/samples/msal-custom-auth-samples/react-demo/challenge.tsx
@@ -0,0 +1,55 @@
+// Challenge component for verification code
+const SignInChallenge = () => {
+ const [code, setCode] = useState("");
+ const [isSubmitting, setIsSubmitting] = useState(false);
+ const navigate = useNavigate();
+
+ const { submitCode, status, errorCode, errorMessage } = useCustomAuth();
+
+ const handleSubmit = async (e) => {
+ e.preventDefault();
+ setIsSubmitting(true);
+
+ try {
+ const result = await submitCode(code);
+
+ if (result === "SignIn.Completed") {
+ navigate("/success");
+ }
+ // If not successful, the form will show again with the error message
+ } catch (error) {
+ console.error("Code submission error:", error);
+ } finally {
+ setIsSubmitting(false);
+ }
+ };
+
+ return (
+
+
Verification Required
+
+
Please enter the verification code sent to your device.
+
+ {errorMessage && (
+
{errorMessage}
+ )}
+
+
+
+ );
+};
diff --git a/samples/msal-custom-auth-samples/react-demo/index.tsx b/samples/msal-custom-auth-samples/react-demo/index.tsx
new file mode 100644
index 0000000000..ca7ce1704b
--- /dev/null
+++ b/samples/msal-custom-auth-samples/react-demo/index.tsx
@@ -0,0 +1,24 @@
+import React from "react";
+import { Routes, Route, Navigate } from "react-router-dom";
+
+const App = () => {
+ return (
+
+
+ } />
+ } />
+
+
+
+ }
+ />
+ } />
+
+
+ );
+};
+
+export default App;
diff --git a/samples/msal-custom-auth-samples/react-demo/signIn.tsx b/samples/msal-custom-auth-samples/react-demo/signIn.tsx
new file mode 100644
index 0000000000..2ab213c483
--- /dev/null
+++ b/samples/msal-custom-auth-samples/react-demo/signIn.tsx
@@ -0,0 +1,69 @@
+import React, { useState } from "react";
+import { useNavigate } from "react-router-dom";
+import { useCustomAuth } from "./hooks/useCustomAuth"; // Assuming this hook is in this path
+
+export const SignIn = () => {
+ const [username, setUsername] = useState("");
+ const [password, setPassword] = useState("");
+ const [isSubmitting, setIsSubmitting] = useState(false);
+ const navigate = useNavigate();
+
+ const { startSignIn, status, errorCode, errorMessage } = useCustomAuth();
+
+ const handleSubmit = async (e) => {
+ e.preventDefault();
+ setIsSubmitting(true);
+
+ try {
+ const result = await startSignIn(username, password);
+
+ if (result === "SignIn.Completed") {
+ navigate("/success");
+ } else if (result === "SignIn.ChallengeRequired") {
+ navigate("/challenge");
+ }
+ } catch (error) {
+ console.error("Sign in error:", error);
+ } finally {
+ setIsSubmitting(false);
+ }
+ };
+
+ return (
+
+
Sign In
+
+ {errorMessage && (
+
{errorMessage}
+ )}
+
+
+
+ );
+};
diff --git a/samples/msal-custom-auth-samples/react-demo/success.tsx b/samples/msal-custom-auth-samples/react-demo/success.tsx
new file mode 100644
index 0000000000..915d0fdf5a
--- /dev/null
+++ b/samples/msal-custom-auth-samples/react-demo/success.tsx
@@ -0,0 +1,53 @@
+import React from "react";
+import { useCustomAuth } from "./hooks/useCustomAuth"; // Assuming this hook is in this path
+
+export const SuccessPage = () => {
+ const { user } = useCustomAuth();
+
+ if (!user) {
+ return Loading user data...
;
+ }
+
+ return (
+
+
Sign In Successful!
+
Welcome, {user.displayName || user.username}!
+
+
+
User Profile
+ {user.profileImage && (
+
+

+
+ )}
+
+
+
+ Username: {user.username}
+
+ {user.email && (
+
+ Email: {user.email}
+
+ )}
+ {user.fullName && (
+
+ Full Name: {user.fullName}
+
+ )}
+ {user.accountType && (
+
+ Account Type: {user.accountType}
+
+ )}
+ {user.memberSince && (
+
+ Member Since:{" "}
+ {new Date(user.memberSince).toLocaleDateString()}
+
+ )}
+
+
+
+ );
+};