Skip to content

Commit

Permalink
Refactor modal component to add max height and overflow-y for better …
Browse files Browse the repository at this point in the history
…content display
  • Loading branch information
JHM69 committed Oct 25, 2024
1 parent 3fc551e commit 9780901
Show file tree
Hide file tree
Showing 10 changed files with 221 additions and 121 deletions.
115 changes: 73 additions & 42 deletions app/(trip)/trip/blogs/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,29 @@
"use client";

import React, { useState, useEffect } from "react";
import { useRouter } from "next/navigation";
import { useRouter, useSearchParams } from "next/navigation";
import { useSession } from "next-auth/react";
import {
UploadCloud,
Search,
Loader2,
Heart,
MessageSquare,
} from "lucide-react";
import axios from "axios";
import { useToast } from "@/components/ui/use-toast";
import {
Dialog,
DialogContent,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import ReactMarkdown from "react-markdown";
import remarkGfm from "remark-gfm";
import BlogGenerator from "./generate";
import { Modal } from "@/components/ui/modal";
import { ModalFullScreen } from "@/components/ui/modal-full";

const breadcrumbItems = [{ title: "Blog", link: "/trip/blog" }];

export default function Page() {
const router = useRouter();
const [isOpen, setIsOpen] = useState(false);
const [userId, setUserId] = useState(undefined);
const [tripPlanId, setTripPlanId] = useState(undefined);
const { data: session } = useSession();
const [blogs, setBlogs] = useState([]);
Expand All @@ -38,6 +33,15 @@ export default function Page() {
const [selectedBlog, setSelectedBlog] = useState(null);
const { toast } = useToast();

const searchParams = useSearchParams(); // Use useSearchParams hook

useEffect(() => {
const tripPlanIdFromQuery = searchParams.get("tripPlanId"); // Get tripPlanId from query string
if (tripPlanIdFromQuery) {
setTripPlanId(tripPlanIdFromQuery);
}
}, [searchParams]);

// Fetch blogs based on tripPlanId and search query
const fetchBlogs = async () => {
setLoading(true);
Expand Down Expand Up @@ -107,47 +111,74 @@ export default function Page() {
<p>No blogs found</p>
</div>
) : (
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-4">
<div className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-6">
{blogs.map((blog, index) => (
<div key={index} className="relative group border rounded p-4">
{/* Small preview of blog content */}
<p className="text-sm">
{blog.content.substring(0, 100)}...
</p>
{/* Author */}
<div className="flex items-center mt-2">
<img
src={blog.author.photo}
alt={blog.author.name}
className="w-8 h-8 rounded-full mr-2"
/>
<span className="text-sm">{blog.author.name}</span>
<div key={index} className="bg-white border rounded-lg shadow-md overflow-hidden">
<div className="p-4">
{/* Blog Title */}
<h2 className="text-xl font-semibold mb-2">{blog.title || "Untitled Blog"}</h2>
{/* Small preview of blog content */}
<p className="text-gray-700 text-sm mb-4">
{blog.content.substring(0, 100)}...
</p>
{/* Author and date */}
<div className="flex items-center text-gray-500 text-sm mb-4">
<span>By {blog.author.name}</span>
<span className="mx-2"></span>
<span>{new Date(blog.createdAt).toLocaleDateString()}</span>
</div>
{/* Action buttons */}
<div className="flex items-center justify-between">
<div className="flex space-x-4">
<button className="flex items-center text-gray-500 hover:text-red-500">
<Heart className="w-5 h-5 mr-1" />
<span>Like</span>
</button>
<button className="flex items-center text-gray-500 hover:text-blue-500">
<MessageSquare className="w-5 h-5 mr-1" />
<span>Comment</span>
</button>
</div>
{/* Preview Button */}
<Button
variant="default"
onClick={() => setSelectedBlog(blog)}
>
Preview
</Button>
</div>
</div>
{/* Preview Button */}
<Button
variant="default"
onClick={() => setSelectedBlog(blog)}
className="mt-2"
>
Preview
</Button>
</div>
))}
</div>
)}

{/* Dialog for Generate Blog */}
<Modal isOpen={isOpen} onClose={() => setIsOpen(false)} title={"Blog Generator"} description={"Ai Blog generator will help to make your Blog"}>

<BlogGenerator
email={session?.user?.email}
name={session?.user?.name}
tripPlanId={tripPlanId}
/>

</Modal>
{selectedBlog && (
<ModalFullScreen
isOpen={true}
onClose={() => setSelectedBlog(null)}
title="Blog Preview"
description=""
>
<div className="space-y-4">
<ReactMarkdown>{selectedBlog?.content}</ReactMarkdown>
</div>
</ModalFullScreen>
)}


{/* Dialog for Generate Blog */}
<ModalFullScreen
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title="Blog Generator"
description="AI Blog generator will help to make your Blog"
>
<BlogGenerator
email={session?.user?.email}
name={session?.user?.name}
tripPlanId={tripPlanId}
/>
</ModalFullScreen>
</div>
);
}
11 changes: 10 additions & 1 deletion app/(trip)/trip/media/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"use client";

import React, { useState, useEffect } from "react";
import { useRouter } from "next/navigation";
import { useRouter, useSearchParams } from "next/navigation";
import MultipleImageUpload from "./uploads";
import { useSession } from "next-auth/react";
import {
Expand Down Expand Up @@ -34,6 +34,15 @@ export default function Page() {
const [loading, setLoading] = useState(false);
const [searchQuery, setSearchQuery] = useState("");
const [selectedImages, setSelectedImages] = useState([]);

const searchParams = useSearchParams(); // Use useSearchParams hook

useEffect(() => {
const tripPlanIdFromQuery = searchParams.get("tripPlanId"); // Get tripPlanId from query string
if (tripPlanIdFromQuery) {
setTripPlanId(tripPlanIdFromQuery);
}
}, [searchParams]);

// Fetch images based on tripPlanId and search query
const fetchImages = async () => {
Expand Down
27 changes: 12 additions & 15 deletions app/(trip)/trip/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@ import { useEffect, useState, useCallback } from "react";
import { useSearchParams, usePathname, useRouter } from "next/navigation";
import TripPlan from "@/components/layout/TripPlan";
import { useSession } from "next-auth/react";
import { toast } from "@/components/ui/use-toast";
import { Toast } from "@radix-ui/react-toast";

export default function Page() {
const searchParams = useSearchParams();
Expand All @@ -18,18 +16,16 @@ export default function Page() {
);
const [tripPlans, setTripPlans] = useState([]);
const [selectedTripPlan, setSelectedTripPlan] = useState({});
const [email, setEmail] = useState("");
const [hasSavedTripPlan, setHasSavedTripPlan] = useState(false);

const { data: session } = useSession();
const [locationError, setLocationError] = useState(null);
const [isFetchingLocation, setIsFetchingLocation] = useState(false);

// Function to update URL with tripPlanId
const updateURL = useCallback(() => {
const params = new URLSearchParams(searchParams.toString());
params.set("tripPlanId", tripPlanId);
router.push(`${pathname}?${params.toString()}`);
}, [tripPlanId, pathname, searchParams, router]);
router.replace(`${pathname}?${params.toString()}`);
}, [tripPlanId, pathname]);

useEffect(() => {
updateURL();
Expand All @@ -39,9 +35,10 @@ export default function Page() {
useEffect(() => {
const saveTripPlan = async () => {
const tripPlan = localStorage.getItem("tripPlan");
if (!tripPlan || hasSavedTripPlan) return; // Prevent multiple saves
setLoading(true);

try {
try {
const res = await fetch("/api/trip", {
method: "POST",
headers: { "Content-Type": "application/json" },
Expand All @@ -56,9 +53,7 @@ export default function Page() {
localStorage.removeItem("tripPlan");
setTripPlanId(data.tripPlans[0].id);
setSelectedTripPlan(data.tripPlans[0]);
const params = new URLSearchParams(searchParams.toString());
params.set("tripPlanId", data.tripPlans[0].id);
router.push(`${pathname}?${params.toString()}`);
setHasSavedTripPlan(true); // Update the state variable
alert("Trip plan saved successfully");
}
} catch (error) {
Expand All @@ -68,8 +63,10 @@ export default function Page() {
}
};

saveTripPlan();
}, [session?.user?.email, searchParams, pathname]);
if (session?.user?.email) {
saveTripPlan();
}
}, [session?.user?.email, hasSavedTripPlan]); // Removed searchParams and pathname

return (
<div className="relative flex flex-col p-8 bg-gray-50 min-h-screen">
Expand All @@ -80,9 +77,9 @@ export default function Page() {
<div className="flex justify-center items-center">
<div className="loader"></div>
</div>
) : tripPlans.length > 0 ? (
) : tripPlans?.length > 0 ? (
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
{tripPlans.map((trip) => (
{tripPlans?.map((trip) => (
<div
key={trip.id}
className="bg-white p-4 rounded-lg shadow-md cursor-pointer hover:bg-blue-50 transition duration-200 transform hover:scale-105"
Expand Down
7 changes: 3 additions & 4 deletions app/api/blog/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,11 +97,11 @@ export async function POST(request: NextRequest) {
});


if (content && title){
if (content ){
await prisma.blog.create({

data: {
title : title,
title : title + " by " + name,
author: {
connect: {
email: email,
Expand All @@ -112,8 +112,7 @@ export async function POST(request: NextRequest) {
id: tripPlanId,
},
},
content: content || "",
tripPlanId: tripPlanId,
content: content || "",
},
});

Expand Down
5 changes: 4 additions & 1 deletion app/api/tripPlan/extract/route.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { NextResponse } from 'next/server'
const axios = require('axios');

const pythonServer = 'http://localhost:5000';
// const pythonServer = 'http://localhost:5000';

const pythonServer = 'http://172.28.31.180:5000'


export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
Expand Down
5 changes: 4 additions & 1 deletion app/api/tripPlan/route.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
import { NextResponse } from 'next/server'
const axios = require('axios');

const pythonServer = 'http://localhost:5000';
// const pythonServer = 'http://localhost:5000';

const pythonServer = 'http://172.28.31.180:5000'


export async function GET(request: Request) {
const { searchParams } = new URL(request.url);
Expand Down
58 changes: 58 additions & 0 deletions components/ui/modal-full.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
"use client";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";

interface ModalProps {
title: string;
description: string;
isOpen: boolean;
onClose: () => void;
children?: React.ReactNode;
}

export const ModalFullScreen: React.FC<ModalProps> = ({
title,
description,
isOpen,
onClose,
children,
}) => {
const onChange = (open: boolean) => {
if (!open) {
onClose();
}
};

return (
<Dialog open={isOpen} onOpenChange={onChange}>
<DialogContent
className="
fixed inset-0
bg-white
max-w-full
w-full
md:w-[70%]
md:left-1/2
md:transform
md:-translate-x-1/2
h-full
overflow-y-auto
rounded-lg
shadow-lg
mt-96
"
>
<DialogHeader>
<DialogTitle>{title}</DialogTitle>
<DialogDescription>{description}</DialogDescription>
</DialogHeader>
<div>{children}</div>
</DialogContent>
</Dialog>
);
};
2 changes: 1 addition & 1 deletion components/ui/modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const Modal: React.FC<ModalProps> = ({

return (
<Dialog open={isOpen} onOpenChange={onChange}>
<DialogContent>
<DialogContent className="max-h-[80vh] overflow-y-auto">
<DialogHeader>
<DialogTitle>{title}</DialogTitle>
<DialogDescription>{description}</DialogDescription>
Expand Down
Loading

0 comments on commit 9780901

Please sign in to comment.