diff --git a/src/App.jsx b/src/App.jsx index 17933fc..c9c8c52 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -7,7 +7,7 @@ import { PanelLeftClose, PanelLeftOpen, Sparkles, CloudSun, ArrowRight, Droplets, CheckCircle2, PieChart, History, X, Download, Bell, Globe, Filter, ShoppingBag, Share2, - FolderOpen, Tag, Link, Calendar, ChevronLeft, ChevronRight, Users + FolderOpen, Tag, Link, Calendar, ChevronLeft, ChevronRight, ChevronDown, Users, MapPin, Copy } from 'lucide-react'; import { @@ -69,8 +69,11 @@ export default function App() { // Estado da Comunidade const [communitySearchTerm, setCommunitySearchTerm] = useState(''); + const [showRecommended, setShowRecommended] = useState(false); const [communityUsers, setCommunityUsers] = useState([]); const [selectedCommunityUser, setSelectedCommunityUser] = useState(null); + const [selectedUserProfile, setSelectedUserProfile] = useState(null); + const [showInspectModal, setShowInspectModal] = useState(false); const [selectedUserClothes, setSelectedUserClothes] = useState([]); const [selectedUserLooks, setSelectedUserLooks] = useState([]); @@ -433,7 +436,8 @@ export default function App() { username: userProfile.username || '', fullName: userProfile.fullName || '', avatar: userProfile.avatar || null, - isPrivate: userProfile.settings?.isPrivate || false + isPrivate: userProfile.settings?.isPrivate || false, + location: userProfile.location || '' }, { merge: true }).catch(err => { console.error("Erro ao sincronizar perfil público:", err); if (err.code === 'permission-denied') { @@ -441,7 +445,7 @@ export default function App() { } }); } - }, [user, userProfile?.username, userProfile?.fullName, userProfile?.avatar, userProfile?.settings?.isPrivate]); + }, [user, userProfile?.username, userProfile?.fullName, userProfile?.avatar, userProfile?.settings?.isPrivate, userProfile?.location]); // Fetch utilizadores da comunidade useEffect(() => { @@ -452,16 +456,25 @@ export default function App() { const snap = await getDocs(profilesRef); const users = snap.docs.map(d => d.data()).filter(u => u.uid !== user?.uid); - if (communitySearchTerm.trim()) { + if (showRecommended) { + const normalizeLoc = (str) => str ? str.normalize("NFD").replace(/[\u0300-\u036f]/g, "").toLowerCase().trim() : ""; + const myLocation = normalizeLoc(userProfile?.location); + if (myLocation) { + setCommunityUsers(users.filter(u => + normalizeLoc(u.location) === myLocation + )); + } else { + setCommunityUsers([]); + } + } else if (communitySearchTerm.trim()) { let term = communitySearchTerm.trim().toLowerCase(); if (term.startsWith('@')) term = term.substring(1); setCommunityUsers(users.filter(u => { const uname = u.username ? u.username.toLowerCase() : ''; - const fname = u.fullName ? u.fullName.toLowerCase() : ''; - return uname.includes(term) || fname.includes(term); + return uname.includes(term); })); } else { - setCommunityUsers(users); + setCommunityUsers([]); } } catch (err) { console.error("Erro ao buscar comunidade", err); @@ -469,13 +482,14 @@ export default function App() { } }; fetchUsers(); - }, [view, communitySearchTerm, user?.uid]); + }, [view, communitySearchTerm, showRecommended, user?.uid, userProfile?.location]); const viewCommunityUser = async (targetUser) => { setSelectedCommunityUser(targetUser); if (targetUser.isPrivate) { setSelectedUserClothes([]); setSelectedUserLooks([]); + setSelectedUserProfile(null); return; } @@ -489,6 +503,15 @@ export default function App() { const looksCol = collection(db, 'artifacts', appId, 'users', targetUser.uid, 'looks'); const snapLooks = await getDocs(looksCol); setSelectedUserLooks(snapLooks.docs.map(d => ({id: d.id, ...d.data()}))); + + // Profile + const profileDocRef = doc(db, 'artifacts', appId, 'users', targetUser.uid, 'profile', 'data'); + const snapProfile = await getDoc(profileDocRef); + if (snapProfile.exists()) { + setSelectedUserProfile(snapProfile.data()); + } else { + setSelectedUserProfile({}); + } } catch (err) { console.error("Erro ao carregar perfil do utilizador", err); } @@ -1094,7 +1117,8 @@ export default function App() { fullName: fd.get('fullName') || '', dob: dob, bio: fd.get('bio') || '', - location: fd.get('location') || '' + location: fd.get('location') || '', + createdAt: userProfile?.createdAt || new Date().getTime() }, { merge: true }).catch(err => { console.error(err); }); @@ -2126,7 +2150,21 @@ export default function App() {

{userProfile?.fullName || t('yourAccount')}

-

@{userProfile?.username || user?.email?.split('@')[0] || t('papMode')}

+
+

@{userProfile?.username || user?.email?.split('@')[0] || t('papMode')}

+ +
@@ -2146,18 +2184,27 @@ export default function App() {
- - - +
+ + +
+
+ + +
+
+ + +
@@ -2176,15 +2223,30 @@ export default function App() {
{!selectedCommunityUser ? ( <> -
- - setCommunitySearchTerm(e.target.value)} - className={`w-full p-6 pl-16 rounded-3xl font-black text-lg outline-none focus:ring-4 focus:ring-primary-500/20 transition-all shadow-xl shadow-black/5 text-inherit ${darkMode ? 'bg-gray-800' : 'bg-white'}`} - /> +
+
+ + { + setCommunitySearchTerm(e.target.value); + if (e.target.value) setShowRecommended(false); + }} + className={`w-full p-6 pl-16 rounded-3xl font-black text-lg outline-none focus:ring-4 focus:ring-primary-500/20 transition-all shadow-xl shadow-black/5 text-inherit ${darkMode ? 'bg-gray-800' : 'bg-white'}`} + /> +
+
{communityUsers.length === 0 ? ( @@ -2210,7 +2272,7 @@ export default function App() { ) : (
- @@ -2219,13 +2281,80 @@ export default function App() {
{selectedCommunityUser.avatar ? Avatar : {(selectedCommunityUser.fullName?.[0] || selectedCommunityUser.username?.[0] || 'U').toUpperCase()}}
-
-

{selectedCommunityUser.fullName || t('userTitle')}

-

@{selectedCommunityUser.username || 'user'}

+
+
+

{selectedCommunityUser.fullName || t('userTitle')}

+
+

@{selectedCommunityUser.username || 'user'}

+ +
+
+
+ {showInspectModal && ( +
setShowInspectModal(false)}> + e.stopPropagation()}> + +
+
+ {selectedCommunityUser.avatar ? Avatar : {(selectedCommunityUser.fullName?.[0] || selectedCommunityUser.username?.[0] || 'U').toUpperCase()}} +
+
+

{selectedCommunityUser.fullName || t('userTitle')}

+

@{selectedCommunityUser.username || 'user'}

+
+
+ +
+
+

Data de Nascimento

+

{selectedUserProfile?.dob ? new Date(selectedUserProfile.dob).toLocaleDateString() : 'Não especificada'}

+
+
+

Localidade

+

{selectedUserProfile?.location || selectedCommunityUser.location || 'Não especificada'}

+
+
+

Bio

+

{selectedUserProfile?.bio || 'Sem biografia'}

+
+
+
+

Peças Registadas

+

{selectedUserClothes.length}

+
+
+

Outfits Criados

+

{selectedUserLooks.length}

+
+
+
+

Data de Registo da Conta

+

{selectedUserProfile?.createdAt ? new Date(selectedUserProfile.createdAt).toLocaleDateString() : 'Desconhecida'}

+
+
+
+
+ )} + {selectedCommunityUser.isPrivate ? (