diff --git a/app/login/page.tsx b/app/login/page.tsx index e96dbd9..3c7ec78 100644 --- a/app/login/page.tsx +++ b/app/login/page.tsx @@ -10,34 +10,58 @@ export default function LoginPage() { const router = useRouter() useEffect(() => { - // If user is already authenticated, redirect to dashboard if (!loading && user) { router.push('/dashboard') } }, [user, loading, router]) + // Loading spinner (fullscreen, responsive) if (loading) { return ( -
+<<<<<<< HEAD +
-
-

Loading...

+
+

Loading...

+======= +<<<<<<< HEAD +
+======= +
+>>>>>>> 103a9a3825538b99686d415d2314c828cd229ade +
+
+

Loading...

+>>>>>>> 8c5d71f2bcb92fa8a2790cab3afe90a1c657bd0f
) } +<<<<<<< HEAD + if (user) return null + + return +======= // If user is authenticated, don't render anything (effect will redirect) - if (user) { - return null - } + if (user) return null - // Show login component for unauthenticated users +<<<<<<< HEAD + // Main login page layout (centered) return ( -
-
- +
+ +======= + // Responsive Fullscreen login with advanced background & centering + return ( +
+
+
+ +
+>>>>>>> 103a9a3825538b99686d415d2314c828cd229ade
) -} \ No newline at end of file +>>>>>>> 8c5d71f2bcb92fa8a2790cab3afe90a1c657bd0f +} diff --git a/package-lock.json b/package-lock.json index f2b09c3..fa777e6 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,6 +8,7 @@ "name": "dumpit", "version": "0.0.1", "dependencies": { + "@heroicons/react": "^2.2.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "firebase": "^9.23.0", @@ -20,8 +21,8 @@ }, "devDependencies": { "@eslint/js": "^9.9.1", - "@types/node": "^20.0.0", - "@types/react": "^18.3.5", + "@types/node": "20.19.23", + "@types/react": "18.3.26", "@types/react-dom": "^18.3.0", "autoprefixer": "^10.4.18", "eslint": "^9.9.1", @@ -29,7 +30,7 @@ "globals": "^15.9.0", "postcss": "^8.4.35", "tailwindcss": "^3.4.1", - "typescript": "^5.5.3", + "typescript": "5.9.3", "typescript-eslint": "^8.3.0" } }, @@ -252,6 +253,7 @@ "resolved": "https://registry.npmjs.org/@firebase/app/-/app-0.9.13.tgz", "integrity": "sha512-GfiI1JxJ7ecluEmDjPzseRXk/PX31hS7+tjgBopL7XjB2hLUdR+0FTMXy2Q3/hXezypDvU6or7gVFizDESrkXw==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@firebase/component": "0.6.4", "@firebase/logger": "0.4.0", @@ -309,6 +311,7 @@ "resolved": "https://registry.npmjs.org/@firebase/app-compat/-/app-compat-0.2.13.tgz", "integrity": "sha512-j6ANZaWjeVy5zg6X7uiqh6lM6o3n3LD1+/SJFNs9V781xyryyZWXe+tmnWNWPkP086QfJoNkWN9pMQRqSG4vMg==", "license": "Apache-2.0", + "peer": true, "dependencies": { "@firebase/app": "0.9.13", "@firebase/component": "0.6.4", @@ -321,7 +324,8 @@ "version": "0.9.0", "resolved": "https://registry.npmjs.org/@firebase/app-types/-/app-types-0.9.0.tgz", "integrity": "sha512-AeweANOIo0Mb8GiYm3xhTEBVCmPwTYAu9Hcd2qSkLuga/6+j9b1Jskl5bpiSQWy9eJ/j5pavxj6eYogmnuzm+Q==", - "license": "Apache-2.0" + "license": "Apache-2.0", + "peer": true }, "node_modules/@firebase/auth": { "version": "0.23.2", @@ -731,6 +735,7 @@ "resolved": "https://registry.npmjs.org/@firebase/util/-/util-1.9.3.tgz", "integrity": "sha512-DY02CRhOZwpzO36fHpuVysz6JZrscPiBXD0fXp6qSrL9oNOx5KWICKdR95C0lSITzxp0TZosVyHqzatE8JbcjA==", "license": "Apache-2.0", + "peer": true, "dependencies": { "tslib": "^2.1.0" } @@ -1040,6 +1045,15 @@ "node": ">=6" } }, + "node_modules/@heroicons/react": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.2.0.tgz", + "integrity": "sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==", + "license": "MIT", + "peerDependencies": { + "react": ">= 16 || ^19.0.0-rc" + } + }, "node_modules/@humanfs/core": { "version": "0.19.1", "resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz", @@ -1542,9 +1556,9 @@ "license": "MIT" }, "node_modules/@types/node": { - "version": "20.19.22", - "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.22.tgz", - "integrity": "sha512-hRnu+5qggKDSyWHlnmThnUqg62l29Aj/6vcYgUaSFL9oc7DVjeWEQN3PRgdSc6F8d9QRMWkf36CLMch1Do/+RQ==", + "version": "20.19.23", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.23.tgz", + "integrity": "sha512-yIdlVVVHXpmqRhtyovZAcSy0MiPcYWGkoO4CGe/+jpP0hmNuihm4XhHbADpK++MsiLHP5MVlv+bcgdF99kSiFQ==", "license": "MIT", "dependencies": { "undici-types": "~6.21.0" @@ -1575,6 +1589,7 @@ "integrity": "sha512-RFA/bURkcKzx/X9oumPG9Vp3D3JUgus/d0b67KB0t5S/raciymilkOa66olh78MUI92QLbEJevO7rvqU/kjwKA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@types/prop-types": "*", "csstype": "^3.0.2" @@ -1686,6 +1701,7 @@ "integrity": "sha512-6JSSaBZmsKvEkbRUkf7Zj7dru/8ZCrJxAqArcLaVMee5907JdtEbKGsZ7zNiIm/UAkpGUkaSMZEXShnN2D1HZA==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@typescript-eslint/scope-manager": "8.46.1", "@typescript-eslint/types": "8.46.1", @@ -1917,6 +1933,7 @@ "integrity": "sha512-NZyJarBfL7nWwIq+FDL6Zp/yHEhePMNnnJ0y3qfieCrmNvYct8uvtiV41UvlSe6apAfk0fY1FbWx+NwfmpvtTg==", "dev": true, "license": "MIT", + "peer": true, "bin": { "acorn": "bin/acorn" }, @@ -2191,6 +2208,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "baseline-browser-mapping": "^2.8.9", "caniuse-lite": "^1.0.30001746", @@ -2703,6 +2721,7 @@ "integrity": "sha512-XyLmROnACWqSxiGYArdef1fItQd47weqB7iwtfr9JHwRrqIXZdcFMvvEcL9xHCmL0SNsOvF0c42lWyM1U5dgig==", "dev": true, "license": "MIT", + "peer": true, "dependencies": { "@eslint-community/eslint-utils": "^4.8.0", "@eslint-community/regexpp": "^4.12.1", @@ -4073,6 +4092,7 @@ "integrity": "sha512-/imKNG4EbWNrVjoNC/1H5/9GFy+tqjGBHCaSsN+P2RnPqjsLmv6UD3Ej+Kj8nBWaRAwyk7kK5ZUc+OEatnTR3A==", "dev": true, "license": "MIT", + "peer": true, "bin": { "jiti": "bin/jiti.js" } @@ -4887,6 +4907,7 @@ } ], "license": "MIT", + "peer": true, "dependencies": { "nanoid": "^3.3.11", "picocolors": "^1.1.1", @@ -5147,6 +5168,7 @@ "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0" }, @@ -5159,6 +5181,7 @@ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz", "integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==", "license": "MIT", + "peer": true, "dependencies": { "loose-envify": "^1.1.0", "scheduler": "^0.23.2" @@ -5849,6 +5872,7 @@ "integrity": "sha512-jl1vZzPDinLr9eUt3J/t7V6FgNEw9QjvBPdysz9KfQDD41fQrC2Y4vKQdiaUpFT4bXlb1RHhLpp8wtm6M5TgSw==", "dev": true, "license": "Apache-2.0", + "peer": true, "bin": { "tsc": "bin/tsc", "tsserver": "bin/tsserver" diff --git a/package.json b/package.json index 876bb42..17f8751 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "typecheck": "tsc --noEmit" }, "dependencies": { + "@heroicons/react": "^2.2.0", "class-variance-authority": "^0.7.1", "clsx": "^2.1.1", "firebase": "^9.23.0", @@ -22,8 +23,8 @@ }, "devDependencies": { "@eslint/js": "^9.9.1", - "@types/node": "^20.0.0", - "@types/react": "^18.3.5", + "@types/node": "20.19.23", + "@types/react": "18.3.26", "@types/react-dom": "^18.3.0", "autoprefixer": "^10.4.18", "eslint": "^9.9.1", @@ -31,7 +32,7 @@ "globals": "^15.9.0", "postcss": "^8.4.35", "tailwindcss": "^3.4.1", - "typescript": "^5.5.3", + "typescript": "5.9.3", "typescript-eslint": "^8.3.0" } } diff --git a/public/Google.png b/public/Google.png new file mode 100644 index 0000000..5a7b3c3 Binary files /dev/null and b/public/Google.png differ diff --git a/src/components/Auth.tsx b/src/components/Auth.tsx index 7b239c3..1997142 100644 --- a/src/components/Auth.tsx +++ b/src/components/Auth.tsx @@ -1,353 +1,601 @@ 'use client' -import { Loader2, LogIn, UserPlus } from 'lucide-react'; -import { useState } from 'react'; -import { useAuth } from '../contexts/AuthContext'; +import Image from "next/image" +import { useState } from "react" +import { + GoogleAuthProvider, + signInWithPopup, + signInWithEmailAndPassword, + createUserWithEmailAndPassword, +} from "firebase/auth" +import { auth } from "@/lib/firebase" +<<<<<<< HEAD +======= +<<<<<<< HEAD +======= -export function Auth() { - const [isLogin, setIsLogin] = useState(true); - const [email, setEmail] = useState(''); - const [password, setPassword] = useState(''); - const [username, setUsername] = useState(''); - const [loading, setLoading] = useState(false); - const [googleLoading, setGoogleLoading] = useState(false); - const [error, setError] = useState(''); - const [usernameError, setUsernameError] = useState(''); - const [usernameSuggestions, setUsernameSuggestions] = useState([]); - const { signIn, signUp, signInWithGoogle } = useAuth(); - - // Username validation regex: 3-20 characters, lowercase, numbers, underscores, hyphens - const usernameRegex = /^[a-z0-9_-]{3,20}$/; - - // Map Firebase error codes to user-friendly messages - const getFriendlyErrorMessage = (errorCode: string): string => { - switch (errorCode) { - case 'auth/email-already-in-use': - return 'This email is already registered. Try signing in instead.'; - case 'auth/weak-password': - return 'Password should be at least 6 characters long.'; - case 'auth/invalid-email': - return 'Please enter a valid email address.'; - case 'auth/user-not-found': - return 'No account found with this email. Please sign up first.'; - case 'auth/wrong-password': - return 'Incorrect password. Please try again.'; - case 'auth/too-many-requests': - return 'Too many failed attempts. Please try again later.'; - case 'auth/network-request-failed': - return 'Network error. Please check your connection and try again.'; - case 'auth/user-disabled': - return 'This account has been disabled. Please contact support.'; - default: - return 'An unexpected error occurred. Please try again.'; - } - }; - - const validateUsernameFormat = (username: string): boolean => { - return usernameRegex.test(username); - }; +const GoogleLogo = () => ( + + + + + + + + +) +>>>>>>> 103a9a3825538b99686d415d2314c828cd229ade +>>>>>>> 8c5d71f2bcb92fa8a2790cab3afe90a1c657bd0f - const checkUsernameUniqueness = async (username: string): Promise => { - try { - const response = await fetch('/api/check-username', { - method: 'POST', - headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify({ username }), - }); +export function Auth() { + const [loading, setLoading] = useState(false) + const [error, setError] = useState("") +<<<<<<< HEAD + const [tab, setTab] = useState<"login" | "signup">("login") +======= +<<<<<<< HEAD + const [tab, setTab] = useState("login") +======= + const [tab, setTab] = useState("login") // login or signup +>>>>>>> 103a9a3825538b99686d415d2314c828cd229ade +>>>>>>> 8c5d71f2bcb92fa8a2790cab3afe90a1c657bd0f + const [showPassword, setShowPassword] = useState(false) + const [email, setEmail] = useState("") + const [password, setPassword] = useState("") + const [emailTouched, setEmailTouched] = useState(false) + const [passwordTouched, setPasswordTouched] = useState(false) - if (!response.ok) { - console.error('API error:', response.status); - return false; // Assume taken on error - } +<<<<<<< HEAD + const emailValid = email.includes("@") && email.includes(".") + const passwordValid = password.length >= 6 - const data = await response.json(); - return data.available; - } catch (error) { - console.error('Error checking username uniqueness:', error); - return false; // Assume taken on error - } - }; +======= +<<<<<<< HEAD + const emailValid = email.includes("@") && email.includes(".") + const passwordValid = password.length >= 6 - const generateUsernameSuggestions = (baseUsername: string): string[] => { - const suggestions: string[] = []; - const cleanBase = baseUsername.replace(/[^a-z0-9_-]/g, '').toLowerCase(); - - // Add numbers - for (let i = 1; i <= 5; i++) { - suggestions.push(`${cleanBase}${i}`); - } +======= + // Input validations + const emailValid = email.includes("@") && email.includes(".") + const passwordValid = password.length >= 6 - // Add underscores with numbers - for (let i = 1; i <= 3; i++) { - suggestions.push(`${cleanBase}_${i}`); + // Email/Password login or signup +>>>>>>> 103a9a3825538b99686d415d2314c828cd229ade +>>>>>>> 8c5d71f2bcb92fa8a2790cab3afe90a1c657bd0f + const handleFormSubmit = async (e: React.FormEvent) => { + e.preventDefault() + setEmailTouched(true) + setPasswordTouched(true) +<<<<<<< HEAD + +======= +>>>>>>> 8c5d71f2bcb92fa8a2790cab3afe90a1c657bd0f + if (!emailValid || !passwordValid) { + setError("Please fix the errors above") + return } +<<<<<<< HEAD - return suggestions.slice(0, 5); // Return first 5 suggestions - }; - - const handleUsernameChange = async (value: string) => { - setUsername(value); - setUsernameError(''); - setUsernameSuggestions([]); - - if (value.trim() === '') return; - - // Check format - if (!validateUsernameFormat(value)) { - setUsernameError('Username must be 3-20 characters, lowercase letters, numbers, underscores, or hyphens only.'); - return; + setLoading(true) + setError("") + + try { + if (tab === "login") { + await signInWithEmailAndPassword(auth, email, password) + } else { + await createUserWithEmailAndPassword(auth, email, password) + } + } catch (e: any) { + setError(e.message || "Authentication failed") + } finally { + setLoading(false) } + } - // Check uniqueness - const isAvailable = await checkUsernameUniqueness(value); - if (!isAvailable) { - setUsernameError('This username is already taken.'); - const suggestions = generateUsernameSuggestions(value); - setUsernameSuggestions(suggestions); + const handleGoogleSignIn = async () => { + setLoading(true) + setError("") + + try { + const provider = new GoogleAuthProvider() + await signInWithPopup(auth, provider) + } catch (e: any) { + setError("Google sign-in failed: " + (e.message || "")) + } finally { + setLoading(false) } - }; - - const handleSubmit = async (e: React.FormEvent) => { - e.preventDefault(); - setError(''); - setLoading(true); - +======= + setLoading(true) + setError("") try { - if (isLogin) { - const { error } = await signIn(email, password); - if (error) { - setError(getFriendlyErrorMessage(error.code || '')); - setLoading(false); - } - // Success - auth state change will trigger navigation + if (tab === "login") { + await signInWithEmailAndPassword(auth, email, password) } else { - // Validate username for signup - if (!username.trim()) { - setError('Username is required'); - setLoading(false); - return; - } - - if (!validateUsernameFormat(username)) { - setError('Username must be 3-20 characters, lowercase letters, numbers, underscores, or hyphens only.'); - setLoading(false); - return; - } - - const isAvailable = await checkUsernameUniqueness(username); - if (!isAvailable) { - setError('This username is already taken. Please choose a different one.'); - setLoading(false); - return; - } - - const { error } = await signUp(email, password, username); - if (error) { - setError(getFriendlyErrorMessage(error.code || '')); - setLoading(false); - } - // Success - auth state change will trigger navigation + await createUserWithEmailAndPassword(auth, email, password) } - } catch (err) { - console.error('Auth error:', err); - setError('An unexpected error occurred. Please try again.'); - setLoading(false); + } catch (e: any) { + setError(e.message || "Authentication failed") } - }; - + setLoading(false) + } + +<<<<<<< HEAD +======= + // Google sign in +>>>>>>> 103a9a3825538b99686d415d2314c828cd229ade const handleGoogleSignIn = async () => { - setError(''); - setGoogleLoading(true); - + setLoading(true) + setError("") try { - const { error } = await signInWithGoogle(); - if (error) { - setError(getFriendlyErrorMessage(error.code || '') || 'Failed to sign in with Google'); - } - // Success - auth state change will trigger navigation - } catch (err) { - console.error('Google auth error:', err); - setError('An unexpected error occurred with Google sign-in. Please try again.'); - } finally { - setGoogleLoading(false); + const provider = new GoogleAuthProvider() + await signInWithPopup(auth, provider) + } catch (e: any) { + setError("Google sign-in failed: " + (e.message || "")) } - }; + setLoading(false) +>>>>>>> 8c5d71f2bcb92fa8a2790cab3afe90a1c657bd0f + } + // UI return ( -
-
-
-
-
- D -
-

DumpIt

-

Your Personal Resource Vault

+<<<<<<< HEAD +
+
+
+
+ DumpIt Logo
+
-
+

+ DumpIt +

+ +

+ Your Personal Resource Vault +

+ +
+ {(["login", "signup"] as const).map((item) => ( + key={item} + className={`flex-1 py-2.5 rounded-xl text-sm sm:text-base font-bold focus:outline-none focus:ring-2 focus:ring-blue-400 transition-all + ${tab === item + ? "bg-[#2075f7] text-white shadow-lg hover:bg-[#1a5fd6]" + : "bg-white text-[#2075f7] border-2 border-blue-200 hover:bg-blue-50"}`} + onClick={() => { + setTab(item) + setError("") + }} + aria-selected={tab === item} + role="tab" +======= +<<<<<<< HEAD +
+
+ + DumpIt Logo + +

DumpIt

+
Your Personal Resource Vault
+
+ {["login", "signup"].map(item => ( -
+ ))} +
+<<<<<<< HEAD -
- {!isLogin && ( -
- - handleUsernameChange(e.target.value)} - className={`w-full px-4 py-2 border rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none transition-all ${ - usernameError ? 'border-red-500' : 'border-gray-300' - }`} - placeholder="johndoe" - required={!isLogin} - /> - {usernameError && ( -

{usernameError}

- )} - {usernameSuggestions.length > 0 && ( -
-

Try these instead:

-
- {usernameSuggestions.map((suggestion) => ( - - ))} -
-
- )} -
+ +
+ +======= + +
+ +>>>>>>> 8c5d71f2bcb92fa8a2790cab3afe90a1c657bd0f + setEmail(e.target.value)} + onBlur={() => setEmailTouched(true)} + disabled={loading} + /> + {emailTouched && !emailValid && ( +

+ Please enter a valid email address +

)} +
-
- - setEmail(e.target.value)} - className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none transition-all" - placeholder="you@example.com" - required - /> -
- -
- +
+ +======= + className={`w-full rounded-lg border border-gray-300 p-3 text-base bg-white focus:outline-none + focus:ring-2 focus:ring-[#2075f7] transition-all + ${emailTouched && !emailValid && "border-red-400 bg-red-50"}`} + placeholder="you@example.com" + required + onChange={(e: React.ChangeEvent) => setEmail(e.target.value)} + onBlur={() => setEmailTouched(true)} + /> + {emailTouched && !emailValid && ( +
Enter a valid email
+ )} +
+
+ +>>>>>>> 8c5d71f2bcb92fa8a2790cab3afe90a1c657bd0f +
setPassword(e.target.value)} - className="w-full px-4 py-2 border border-gray-300 rounded-lg focus:ring-2 focus:ring-blue-500 focus:border-transparent outline-none transition-all" - placeholder="••••••••" + onBlur={() => setPasswordTouched(true)} + disabled={loading} + /> +
+ {passwordTouched && !passwordValid && ( +<<<<<<< HEAD +

+ Password must be at least 6 characters +

+ )} +
+ + {error && ( +
+ {error} +
+ )} - {error && ( -
- {error} -
+ + +
+
+ OR +
+
+ +
+ )} +======= +
+
+ {/* Logo & Header */} +
+ + DumpIt Logo + +

DumpIt

+
Your Personal Resource Vault
+
+ {/* Tab switch */} +
+ {["login", "signup"].map(item => ( - -
-
- or continue with -
-
- + ))} +
+ {/* Form */} +
+
+ + setEmail(e.target.value)} + onBlur={() => setEmailTouched(true)} + /> + {emailTouched && !emailValid &&
Enter a valid email
} +
+
+ + setPassword(e.target.value)} + onBlur={() => setPasswordTouched(true)} + /> - + {passwordTouched && !passwordValid &&
Password must be at least 6 characters
} +>>>>>>> 103a9a3825538b99686d415d2314c828cd229ade +
+ {error && ( +
{error}
+ )} + + +<<<<<<< HEAD +
+======= + {/* Social login separator and Google */} +
+>>>>>>> 103a9a3825538b99686d415d2314c828cd229ade + + OR + +
+ + +
+ + By logging in, you accept our{" "} + + Privacy Policy + + . + + + Need help?{" "} + + Contact Support + + +======= + alt="Google logo" + width={24} + height={24} + className="mr-2" + style={{ objectFit: "cover" }} + /> + {loading ? "Signing in..." : "Continue with Google"} + +
+ By logging in, you accept our Privacy Policy. + Need help? Contact Support +======= + className="w-full py-3 flex items-center justify-center rounded-xl border border-gray-300 bg-white shadow-md hover:bg-gray-50 transition font-semibold text-base text-gray-600" + disabled={loading} + > + + {loading ? "Signing in..." : "Continue with Google"} + + {/* Legal/support links */} +
+ By logging in, you accept our Privacy Policy. + Need help? Contact Support +>>>>>>> 103a9a3825538b99686d415d2314c828cd229ade +>>>>>>> 8c5d71f2bcb92fa8a2790cab3afe90a1c657bd0f
- ); + ) } diff --git a/src/lib/firebase.ts b/src/lib/firebase.ts index 01b5fbe..de062f8 100644 --- a/src/lib/firebase.ts +++ b/src/lib/firebase.ts @@ -1,52 +1,20 @@ -import { isSupported as analyticsSupported, getAnalytics } from 'firebase/analytics'; -import { initializeApp } from 'firebase/app'; -import { getAuth } from 'firebase/auth'; -import { getFirestore } from 'firebase/firestore'; +// src/lib/firebase.ts +import { initializeApp } from "firebase/app"; +import { getAuth } from "firebase/auth"; +import { getFirestore } from "firebase/firestore"; -// Read config from Next.js env. These should be set in your .env as NEXT_PUBLIC_FIREBASE_* const firebaseConfig = { - apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY, - authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, - projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, - storageBucket: process.env.NEXT_PUBLIC_FIREBASE_STORAGE_BUCKET, - messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID, - appId: process.env.NEXT_PUBLIC_FIREBASE_APP_ID, - measurementId: process.env.NEXT_PUBLIC_FIREBASE_MEASUREMENT_ID, + apiKey: "AIzaSyBMPM93qI02vLppxEOwIRF13JZqRf_kbQs", + authDomain: "dumpit-50760.firebaseapp.com", + projectId: "dumpit-50760", + storageBucket: "dumpit-50760.appspot.com", + messagingSenderId: "924635227217", + appId: "1:924635227217:web:aecaee9b8591294e274470", + measurementId: "G-FX15XKQWJN" }; -// Validate required keys -const requiredKeys = ['apiKey', 'authDomain', 'projectId', 'appId'] as const; -const missing = requiredKeys.filter((k) => !(firebaseConfig as any)[k]); -const isDummyConfig = missing.length > 0 || firebaseConfig.apiKey?.includes('Dummy') || firebaseConfig.apiKey?.includes('dummy'); +const app = initializeApp(firebaseConfig); -if (isDummyConfig) { - // eslint-disable-next-line no-console - console.warn( - '⚠️ Firebase configuration is incomplete or using dummy values. \n' + - 'Please add NEXT_PUBLIC_FIREBASE_* environment variables to your .env.local file.\n' + - 'See FIREBASE_SETUP.md for instructions.' - ); -} - -// Initialize Firebase -const app = initializeApp(firebaseConfig as any); export const auth = getAuth(app); export const db = getFirestore(app); - -// Guard analytics initialization: it will fail in SSR or if measurementId is not provided -(async () => { - try { - if (firebaseConfig.measurementId && typeof window !== 'undefined') { - const ok = await analyticsSupported(); - if (ok) { - getAnalytics(app); - } - } - } catch (err) { - // Not fatal — analytics optional, but surface the error to console for debugging - // eslint-disable-next-line no-console - console.warn('Firebase analytics not available:', err); - } -})(); - -export default app; +// REMOVE analytics initialization here!