diff --git a/src/components/ui/Toast.jsx b/src/components/ui/Toast.jsx
new file mode 100644
index 0000000..06b4129
--- /dev/null
+++ b/src/components/ui/Toast.jsx
@@ -0,0 +1,25 @@
+import React, { useEffect } from "react";
+
+const Toast = ({ message, type = "success", onClose }) => {
+ useEffect(() => {
+ const timer = setTimeout(onClose, 3000);
+ return () => clearTimeout(timer);
+ }, [onClose]);
+
+ return (
+
+ {type === "success" ? "✅" : "❌"}
+ {message}
+
+ );
+};
+
+export default Toast;
\ No newline at end of file
diff --git a/src/pages/Profile.jsx b/src/pages/Profile.jsx
index c207c17..26f0739 100644
--- a/src/pages/Profile.jsx
+++ b/src/pages/Profile.jsx
@@ -1,4 +1,5 @@
import React, { useState, useEffect } from "react";
+import Toast from "../components/ui/Toast";
import LottiePlayer from "../components/ui/LottiePlayer";
import {
MapPin,
@@ -26,7 +27,7 @@ export const Profile = () => {
const { userData, user, setUserData } = useAuth();
const [copied, setCopied] = useState(false);
const [rank, setRank] = useState("Loading...");
-
+ const [toast, setToast] = useState(null);
// Social links edit states
const [editingSocial, setEditingSocial] = useState(null);
const [editValue, setEditValue] = useState("");
@@ -82,9 +83,38 @@ export const Profile = () => {
};
// Handle social link update
- const handleUpdateSocialLink = async (type, value) => {
+const handleUpdateSocialLink = async (type, value) => {
if (!user) return;
-
+
+ // Validate input before updating
+ if (type === "linkedin") {
+ if (value && value.trim()) {
+ const linkedinPattern = /^(https?:\/\/)?(www\.)?linkedin\.com\/in\/[\w\-]+\/?$/i;
+ const rawVal = value.trim();
+ const testVal = rawVal.startsWith('http') ? rawVal : 'https://' + rawVal;
+ if (!linkedinPattern.test(testVal)) {
+ setToast({ message: "Invalid LinkedIn URL. Use format: linkedin.com/in/username", type: "error" });
+ return;
+ }
+ }
+ } else if (type === "instagram") {
+ if (value && value.trim()) {
+ const igPattern = /^@?[\w](?!.*?\.{2})[\w.]{1,28}[\w]$/;
+ if (!igPattern.test(value.trim())) {
+ setToast({ message: "Invalid Instagram username.", type: "error" });
+ return;
+ }
+ }
+ } else if (type === "discord") {
+ if (value && value.trim()) {
+ const discordPattern = /^.{3,32}(#\d{4})?$/;
+ if (!discordPattern.test(value.trim())) {
+ setToast({ message: "Invalid Discord username.", type: "error" });
+ return;
+ }
+ }
+ }
+
setUpdating(true);
try {
const userRef = doc(db, "users", user.uid);
@@ -138,10 +168,10 @@ export const Profile = () => {
setEditingSocial(null);
setEditValue("");
- alert(`${type.charAt(0).toUpperCase() + type.slice(1)} updated successfully!`);
+ setToast({ message: `${type.charAt(0).toUpperCase() + type.slice(1)} updated successfully!`, type: "success" });
} catch (err) {
console.error("Error updating social link:", err);
- alert(`Failed to update ${type}. Please try again.`);
+ setToast({ message: `Failed to update ${type}. Please try again.`, type: "error" });
} finally {
setUpdating(false);
}