feat: mejorar área privada, invitaciones de registro y contraste de modales
- Se sincronizó el estado de autenticación en las páginas de publicación y mis avisos usando AuthContext. - Se actualizó el diseño de las invitaciones a registro en áreas privadas. - Se añadió soporte para abrir el modal de login directamente en la pestaña de registro. - Se mejoró la legibilidad de todos los modales aumentando el desenfoque de fondo y la opacidad.
This commit is contained in:
@@ -243,7 +243,7 @@ function Navbar() {
|
|||||||
)}
|
)}
|
||||||
|
|
||||||
{showLoginModal && (
|
{showLoginModal && (
|
||||||
<div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/60 backdrop-blur-md animate-fade-in p-4">
|
<div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/80 backdrop-blur-xl animate-fade-in p-4">
|
||||||
<div className="relative w-full max-w-md">
|
<div className="relative w-full max-w-md">
|
||||||
<LoginModal
|
<LoginModal
|
||||||
onSuccess={handleLoginSuccess}
|
onSuccess={handleLoginSuccess}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ export default function ChatModal({ isOpen, onClose, adId, adTitle, sellerId, cu
|
|||||||
if (!isOpen) return null;
|
if (!isOpen) return null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="fixed inset-0 z-[200] flex items-end md:items-center justify-center p-4 md:p-6 bg-black/80 backdrop-blur-sm animate-fade-in">
|
<div className="fixed inset-0 z-[200] flex items-end md:items-center justify-center p-4 md:p-6 bg-black/80 backdrop-blur-xl animate-fade-in">
|
||||||
<div className="bg-[#12141a] w-full max-w-lg rounded-[2rem] border border-white/10 shadow-2xl flex flex-col max-h-[85vh] overflow-hidden animate-scale-up">
|
<div className="bg-[#12141a] w-full max-w-lg rounded-[2rem] border border-white/10 shadow-2xl flex flex-col max-h-[85vh] overflow-hidden animate-scale-up">
|
||||||
|
|
||||||
{/* Header Neutro */}
|
{/* Header Neutro */}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export default function ConfirmationModal({
|
|||||||
<div className="fixed inset-0 z-[200] flex items-center justify-center p-4 animate-fade-in">
|
<div className="fixed inset-0 z-[200] flex items-center justify-center p-4 animate-fade-in">
|
||||||
{/* Backdrop */}
|
{/* Backdrop */}
|
||||||
<div
|
<div
|
||||||
className="absolute inset-0 bg-black/80 backdrop-blur-sm"
|
className="absolute inset-0 bg-black/80 backdrop-blur-xl"
|
||||||
onClick={onCancel}
|
onClick={onCancel}
|
||||||
></div>
|
></div>
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { QRCodeSVG } from "qrcode.react";
|
|||||||
interface Props {
|
interface Props {
|
||||||
onSuccess: (user: UserSession) => void;
|
onSuccess: (user: UserSession) => void;
|
||||||
onClose: () => void;
|
onClose: () => void;
|
||||||
|
initialMode?: "LOGIN" | "REGISTER";
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- ICONOS SVG ---
|
// --- ICONOS SVG ---
|
||||||
@@ -94,9 +95,9 @@ const NeutralCircleIcon = () => (
|
|||||||
</svg>
|
</svg>
|
||||||
);
|
);
|
||||||
|
|
||||||
export default function LoginModal({ onSuccess, onClose }: Props) {
|
export default function LoginModal({ onSuccess, onClose, initialMode }: Props) {
|
||||||
// Toggle entre Login y Registro
|
// Toggle entre Login y Registro
|
||||||
const [mode, setMode] = useState<"LOGIN" | "REGISTER">("LOGIN");
|
const [mode, setMode] = useState<"LOGIN" | "REGISTER">(initialMode || "LOGIN");
|
||||||
|
|
||||||
// Estados de Login
|
// Estados de Login
|
||||||
const [username, setUsername] = useState("");
|
const [username, setUsername] = useState("");
|
||||||
@@ -459,7 +460,7 @@ export default function LoginModal({ onSuccess, onClose }: Props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
// CAMBIO: max-w-lg (más ancho) y overflow-hidden para evitar scrollbars feos
|
// CAMBIO: max-w-lg (más ancho) y overflow-hidden para evitar scrollbars feos
|
||||||
<div className="glass px-8 py-6 rounded-3xl border border-white/10 shadow-2xl max-w-lg w-full animate-fade-in-up relative overflow-hidden">
|
<div className="bg-[#161a22] px-8 py-6 rounded-3xl border border-white/10 shadow-2xl max-w-lg w-full animate-fade-in-up relative overflow-hidden backdrop-blur-3xl">
|
||||||
{loading && (
|
{loading && (
|
||||||
<div className="absolute top-0 left-0 w-full h-1 bg-blue-500 animate-pulse"></div>
|
<div className="absolute top-0 left-0 w-full h-1 bg-blue-500 animate-pulse"></div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { AdsV2Service, type AdListingDto } from "../services/ads.v2.service";
|
|||||||
import { useAuth } from "../context/AuthContext";
|
import { useAuth } from "../context/AuthContext";
|
||||||
import { ChatService, type ChatMessage } from "../services/chat.service";
|
import { ChatService, type ChatMessage } from "../services/chat.service";
|
||||||
import ChatModal from "../components/ChatModal";
|
import ChatModal from "../components/ChatModal";
|
||||||
|
import LoginModal from "../components/LoginModal";
|
||||||
import { formatCurrency, getImageUrl, parseUTCDate } from "../utils/app.utils";
|
import { formatCurrency, getImageUrl, parseUTCDate } from "../utils/app.utils";
|
||||||
import { AD_STATUSES, STATUS_CONFIG } from "../constants/adStatuses";
|
import { AD_STATUSES, STATUS_CONFIG } from "../constants/adStatuses";
|
||||||
import ConfirmationModal from "../components/ConfirmationModal";
|
import ConfirmationModal from "../components/ConfirmationModal";
|
||||||
@@ -17,7 +18,8 @@ export default function MisAvisosPage() {
|
|||||||
const [mensajes, setMensajes] = useState<ChatMessage[]>([]);
|
const [mensajes, setMensajes] = useState<ChatMessage[]>([]);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
const { user, fetchUnreadCount } = useAuth();
|
const { user, fetchUnreadCount, login } = useAuth();
|
||||||
|
const [showLoginModal, setShowLoginModal] = useState(false);
|
||||||
|
|
||||||
const [selectedChat, setSelectedChat] = useState<{
|
const [selectedChat, setSelectedChat] = useState<{
|
||||||
adId: number;
|
adId: number;
|
||||||
@@ -234,22 +236,39 @@ export default function MisAvisosPage() {
|
|||||||
if (!user) {
|
if (!user) {
|
||||||
return (
|
return (
|
||||||
<div className="container mx-auto px-6 py-24 text-center animate-fade-in-up">
|
<div className="container mx-auto px-6 py-24 text-center animate-fade-in-up">
|
||||||
<div className="glass p-12 rounded-[3rem] max-w-2xl mx-auto border border-white/5 shadow-2xl">
|
<div className="bg-[#111318]/90 backdrop-blur-3xl p-12 rounded-[3rem] max-w-2xl mx-auto border border-white/5 shadow-2xl">
|
||||||
<span className="text-7xl mb-8 block">🔒</span>
|
<span className="text-7xl mb-8 block">🔒</span>
|
||||||
<h2 className="text-5xl font-black mb-4 uppercase tracking-tighter">
|
<h2 className="text-5xl font-black mb-4 uppercase tracking-tighter">
|
||||||
Área Privada
|
Registrate o Inicia Sesión
|
||||||
</h2>
|
</h2>
|
||||||
<p className="text-gray-400 mb-10 text-lg italic">
|
<p className="text-gray-400 mb-10 text-lg italic">
|
||||||
Para gestionar tus publicaciones, primero debes iniciar sesión.
|
Para ver y gestionar tus avisos, primero debes registrarte o iniciar sesión.
|
||||||
</p>
|
</p>
|
||||||
<Link
|
<div className="flex flex-col md:flex-row gap-4 justify-center">
|
||||||
to="/publicar"
|
<button
|
||||||
|
onClick={() => setShowLoginModal(true)}
|
||||||
className="bg-blue-600 hover:bg-blue-500 text-white px-12 py-5 rounded-[2rem] font-bold uppercase tracking-widest transition-all inline-block shadow-lg shadow-blue-600/20"
|
className="bg-blue-600 hover:bg-blue-500 text-white px-12 py-5 rounded-[2rem] font-bold uppercase tracking-widest transition-all inline-block shadow-lg shadow-blue-600/20"
|
||||||
>
|
>
|
||||||
Identificarse
|
Registrarse
|
||||||
</Link>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{showLoginModal && (
|
||||||
|
<div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/80 backdrop-blur-xl animate-fade-in p-4">
|
||||||
|
<div className="relative w-full max-w-md text-left">
|
||||||
|
<LoginModal
|
||||||
|
initialMode="REGISTER"
|
||||||
|
onSuccess={(u) => {
|
||||||
|
login(u);
|
||||||
|
setShowLoginModal(false);
|
||||||
|
}}
|
||||||
|
onClose={() => setShowLoginModal(false)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,10 @@ import { useState, useEffect } from "react";
|
|||||||
import { useSearchParams, useNavigate } from "react-router-dom";
|
import { useSearchParams, useNavigate } from "react-router-dom";
|
||||||
import { AvisosService } from "../services/avisos.service";
|
import { AvisosService } from "../services/avisos.service";
|
||||||
import { AdsV2Service } from "../services/ads.v2.service";
|
import { AdsV2Service } from "../services/ads.v2.service";
|
||||||
import { AuthService, type UserSession } from "../services/auth.service";
|
|
||||||
import type { DatosAvisoDto } from "../types/aviso.types";
|
import type { DatosAvisoDto } from "../types/aviso.types";
|
||||||
import FormularioAviso from "../components/FormularioAviso";
|
import FormularioAviso from "../components/FormularioAviso";
|
||||||
|
import { useAuth } from "../context/AuthContext";
|
||||||
import LoginModal from "../components/LoginModal";
|
import LoginModal from "../components/LoginModal";
|
||||||
|
|
||||||
const TAREAS_DISPONIBLES = [
|
const TAREAS_DISPONIBLES = [
|
||||||
@@ -34,9 +35,8 @@ export default function PublicarAvisoPage() {
|
|||||||
const [planSeleccionado, setPlanSeleccionado] =
|
const [planSeleccionado, setPlanSeleccionado] =
|
||||||
useState<DatosAvisoDto | null>(null);
|
useState<DatosAvisoDto | null>(null);
|
||||||
const [fixedCategory, setFixedCategory] = useState<string | null>(null);
|
const [fixedCategory, setFixedCategory] = useState<string | null>(null);
|
||||||
const [user, setUser] = useState<UserSession | null>(
|
const [showLoginModal, setShowLoginModal] = useState(false);
|
||||||
AuthService.getCurrentUser(),
|
const { user, login } = useAuth();
|
||||||
);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (editId) {
|
if (editId) {
|
||||||
@@ -147,12 +147,40 @@ export default function PublicarAvisoPage() {
|
|||||||
|
|
||||||
if (!user) {
|
if (!user) {
|
||||||
return (
|
return (
|
||||||
<div className="flex justify-center items-center py-20 min-h-[60vh]">
|
<div className="container mx-auto px-6 py-24 text-center animate-fade-in-up">
|
||||||
|
<div className="bg-[#111318]/90 backdrop-blur-3xl p-12 rounded-[3rem] max-w-2xl mx-auto border border-white/5 shadow-2xl">
|
||||||
|
<span className="text-7xl mb-8 block">🔒</span>
|
||||||
|
<h2 className="text-5xl font-black mb-4 uppercase tracking-tighter">
|
||||||
|
Registrate o Inicia Sesión
|
||||||
|
</h2>
|
||||||
|
<p className="text-gray-400 mb-10 text-lg italic">
|
||||||
|
Para publicar tus avisos, primero debes registrarte o iniciar sesión.
|
||||||
|
</p>
|
||||||
|
<div className="flex flex-col md:flex-row gap-4 justify-center">
|
||||||
|
<button
|
||||||
|
onClick={() => setShowLoginModal(true)}
|
||||||
|
className="bg-blue-600 hover:bg-blue-500 text-white px-12 py-5 rounded-[2rem] font-bold uppercase tracking-widest transition-all inline-block shadow-lg shadow-blue-600/20"
|
||||||
|
>
|
||||||
|
Registrarse
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{showLoginModal && (
|
||||||
|
<div className="fixed inset-0 z-[200] flex items-center justify-center bg-black/80 backdrop-blur-xl animate-fade-in p-4">
|
||||||
|
<div className="relative w-full max-w-md">
|
||||||
<LoginModal
|
<LoginModal
|
||||||
onSuccess={(u) => setUser(u)}
|
initialMode="REGISTER"
|
||||||
onClose={() => navigate("/")}
|
onSuccess={(u) => {
|
||||||
|
login(u);
|
||||||
|
setShowLoginModal(false);
|
||||||
|
}}
|
||||||
|
onClose={() => setShowLoginModal(false)}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user