Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 34 additions & 0 deletions app/browse/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
loadingVariants,
} from "../props/animations";
import BrowseLoader from "./components/BrowseLoader";
import { useAuth } from "../context/AuthContext";
import NotLoggedIn from "../../components/globals/NotLoggedIn";

const Browse = () => {
const searchParams = useSearchParams();
Expand All @@ -29,6 +31,7 @@ const Browse = () => {
const [listings, setListings] = useState<any[]>([]);
const searchBarRef = useRef<any>(null);
const [loading, setLoading] = useState(true);
const { user, loading: authLoading } = useAuth();

useEffect(() => {
const fetchListings = async () => {
Expand Down Expand Up @@ -82,6 +85,37 @@ const Browse = () => {
}
};

// Show loading while auth is being checked
if (authLoading) {
return (
<motion.div
className="flex items-center justify-center min-h-[60vh]"
variants={loadingVariants}
initial="hidden"
animate="visible"
>
<BrowseLoader />
</motion.div>
);
}

// Show not logged in component if user is not authenticated
if (!user) {
return (
<motion.div
className="bg-gray-50 min-h-screen"
variants={containerVariants}
initial="hidden"
animate="visible"
>
<NotLoggedIn
message="Please log in to browse listings"
className="p-8"
/>
</motion.div>
);
}

return (
<motion.div
className="bg-gray-50 min-h-screen"
Expand Down
39 changes: 36 additions & 3 deletions app/create/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ import dynamic from "next/dynamic";
import { ListingService } from '../lib/database/ListingService';
import { UserService } from '../lib/database/UserService';
import { dbLogger } from '../lib/database/utils';
import NotLoggedIn from '../../components/globals/NotLoggedIn';


const MapPicker = dynamic(() => import("../listing/components/MapPicker"), { ssr: false });

const Create = () => {
const [images, setImages] = useState<File[]>([]);
const fileInputRef = useRef<HTMLInputElement | null>(null);
const { user } = useAuth();
const { user, loading: authLoading } = useAuth();
const router = useRouter();
const [title, setTitle] = useState("");
const [category, setCategory] = useState("");
Expand Down Expand Up @@ -92,7 +93,6 @@ const Create = () => {
const handleSaveDraft = async () => {
if (!user?.id) {
toast.error("You must be logged in to save a draft.");
router.push('/auth/signin');
return;
}

Expand Down Expand Up @@ -136,7 +136,6 @@ const Create = () => {
const handleSubmit = async () => {
if (!user?.id) {
toast.error("You must be logged in to create a listing.");
router.push('/auth/signin');
return;
}

Expand Down Expand Up @@ -179,6 +178,40 @@ const Create = () => {
}
};

// Show loading while auth is being checked
if (authLoading) {
return (
<motion.div
className="flex items-center justify-center min-h-[60vh]"
variants={containerVariants}
initial="hidden"
animate="visible"
>
<div className="text-center">
<div className="animate-spin rounded-full h-8 w-8 border-b-2 border-[#bf5700] mx-auto"></div>
<p className="mt-2 text-gray-600">Loading...</p>
</div>
</motion.div>
);
}

// Show not logged in component if user is not authenticated
if (!user) {
return (
<motion.div
className="bg-gray-50 min-h-screen"
variants={containerVariants}
initial="hidden"
animate="visible"
>
<NotLoggedIn
message="Please log in to create a listing"
className="py-10"
/>
</motion.div>
);
}

return (
<motion.div
className="bg-gray-50 flex-1"
Expand Down
27 changes: 23 additions & 4 deletions app/my-listings/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ import {
import BrowseLoader from "../browse/components/BrowseLoader";
import * as timeago from "timeago.js";
import { processListingsWithStatus } from "../lib/utils/statusUtils";
import NotLoggedIn from "../../components/globals/NotLoggedIn";

interface Listing {
id: string;
Expand Down Expand Up @@ -61,10 +62,6 @@ const MyListings = () => {
const [editId, setEditId] = useState<string | null>(null);

useEffect(() => {
if (!authLoading && !user) {
router.push("/auth/signin");
return;
}
if (!authLoading && user) {
fetchListings();
}
Expand Down Expand Up @@ -219,6 +216,28 @@ const MyListings = () => {
}
};

// Show loading while auth is being checked
if (authLoading) {
return <BrowseLoader />;
}

// Show not logged in component if user is not authenticated
if (!user) {
return (
<motion.div
className="bg-gray-50 min-h-screen"
variants={containerVariants}
initial="hidden"
animate="visible"
>
<NotLoggedIn
message="Please log in to view your listings"
className="py-8"
/>
</motion.div>
);
}

if (loading) {
return <BrowseLoader />;
}
Expand Down
65 changes: 65 additions & 0 deletions components/globals/NotLoggedIn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
"use client";
import React from 'react';
import { motion } from 'framer-motion';
import { useRouter } from 'next/navigation';
import { LogIn, UserX } from 'lucide-react';

interface NotLoggedInProps {
message?: string;
showLoginButton?: boolean;
className?: string;
}

const NotLoggedIn: React.FC<NotLoggedInProps> = ({
message = "You're not logged in",
showLoginButton = true,
className = ""
}) => {
const router = useRouter();

const handleLoginClick = () => {
router.push('/auth/signin');
};

return (
<motion.div
className={`flex flex-col items-center justify-center min-h-[60vh] text-center ${className}`}
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.5 }}
>
<motion.div
className="bg-white rounded-lg shadow-lg p-8 max-w-md w-full mx-4"
initial={{ scale: 0.9 }}
animate={{ scale: 1 }}
transition={{ duration: 0.3, delay: 0.2 }}
>
<div className="flex flex-col items-center space-y-4">
<div className="w-16 h-16 bg-gray-100 rounded-full flex items-center justify-center">
<UserX className="w-8 h-8 text-gray-500" />
</div>

<h2 className="text-xl font-semibold text-gray-900">
{message}
</h2>

<p className="text-gray-600 text-sm">
Please log in to access this feature and start using UT Marketplace.
</p>

{showLoginButton && (
<button
onClick={handleLoginClick}
className="flex items-center gap-2 px-6 py-3 bg-[#bf5700] text-white rounded-lg hover:bg-[#a54700] transition-colors duration-200 font-medium cursor-pointer"
>
<LogIn className="w-4 h-4" />
Go to Login
</button>
)}
</div>
</motion.div>
</motion.div>
);
};

export default NotLoggedIn;