mirror of
https://github.com/QuivrHQ/quivr.git
synced 2024-09-11 14:36:35 +03:00
style: use Dialog component for /explore
This commit is contained in:
parent
363528d2ce
commit
83287be4f1
@ -1,20 +1,25 @@
|
||||
import { cn } from "@/lib/utils";
|
||||
import { FC, HTMLAttributes } from "react";
|
||||
import { motion } from "framer-motion";
|
||||
import { FC, HTMLAttributes, LegacyRef, forwardRef } from "react";
|
||||
|
||||
interface CardProps extends HTMLAttributes<HTMLDivElement> {}
|
||||
|
||||
const Card: FC<CardProps> = ({ children, className, ...props }) => {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
"shadow-md dark:shadow-primary/25 hover:shadow-xl transition-shadow rounded-xl overflow-hidden bg-white dark:bg-black border border-black/10 dark:border-white/25",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
const Card: FC<CardProps> = forwardRef(
|
||||
({ children, className, ...props }, ref) => {
|
||||
return (
|
||||
<div
|
||||
ref={ref as LegacyRef<HTMLDivElement>}
|
||||
className={cn(
|
||||
"shadow-md dark:shadow-primary/25 hover:shadow-xl transition-shadow rounded-xl overflow-hidden bg-white dark:bg-black border border-black/10 dark:border-white/25",
|
||||
className
|
||||
)}
|
||||
{...props}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
);
|
||||
|
||||
export const AnimatedCard = motion(Card);
|
||||
export default Card;
|
||||
|
34
frontend/app/explore/DocumentItem.tsx
Normal file
34
frontend/app/explore/DocumentItem.tsx
Normal file
@ -0,0 +1,34 @@
|
||||
"use client";
|
||||
import { FC } from "react";
|
||||
import { Document } from "./types";
|
||||
import Button from "../components/ui/Button";
|
||||
import Modal from "../components/ui/Modal";
|
||||
import { AnimatedCard } from "../components/ui/Card";
|
||||
|
||||
interface DocumentProps {
|
||||
document: Document;
|
||||
}
|
||||
|
||||
const DocumentItem: FC<DocumentProps> = ({ document }) => {
|
||||
return (
|
||||
<AnimatedCard
|
||||
initial={{ x: -64, opacity: 0 }}
|
||||
animate={{ x: 0, opacity: 1 }}
|
||||
className="flex items-center justify-between w-full p-5 gap-10"
|
||||
>
|
||||
<p className="text-lg leading-tight max-w-sm">{document.name}</p>
|
||||
<Modal
|
||||
title={document.name}
|
||||
desc={""}
|
||||
Trigger={<Button className="">View</Button>}
|
||||
>
|
||||
<div className="bg-white py-10 w-full h-1/2 overflow-auto rounded-lg prose">
|
||||
<pre>{JSON.stringify(document, null, 2)}</pre>
|
||||
</div>
|
||||
</Modal>
|
||||
</AnimatedCard>
|
||||
);
|
||||
};
|
||||
|
||||
DocumentItem.displayName = "DocumentItem";
|
||||
export default DocumentItem;
|
@ -1,32 +0,0 @@
|
||||
import { FC } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
|
||||
interface DocumentProps {
|
||||
document: {
|
||||
name: string;
|
||||
size: string;
|
||||
};
|
||||
viewDocument: (document: { name: string; size: string }) => void;
|
||||
}
|
||||
|
||||
const DocumentItem: FC<DocumentProps> = ({ document, viewDocument }) => {
|
||||
return (
|
||||
<motion.div
|
||||
initial={{ x: -64, opacity: 0 }}
|
||||
animate={{ x: 0, opacity: 1 }}
|
||||
exit={{ x: 64, opacity: 0 }}
|
||||
className="flex items-center justify-between w-1/2 p-4 mb-4 bg-white shadow rounded"
|
||||
>
|
||||
<p className="text-lg">{document.name}</p>
|
||||
<button
|
||||
onClick={() => viewDocument(document)}
|
||||
className="py-2 px-4 bg-blue-500 text-white rounded mr-2 hover:bg-blue-600 transition duration-200"
|
||||
>
|
||||
View
|
||||
</button>
|
||||
</motion.div>
|
||||
);
|
||||
};
|
||||
|
||||
DocumentItem.displayName = 'DocumentItem';
|
||||
export default DocumentItem;
|
9
frontend/app/explore/loading.tsx
Normal file
9
frontend/app/explore/loading.tsx
Normal file
@ -0,0 +1,9 @@
|
||||
import { FC } from "react";
|
||||
|
||||
interface loadingProps {}
|
||||
|
||||
const loading: FC<loadingProps> = ({}) => {
|
||||
return <div>loading...</div>;
|
||||
};
|
||||
|
||||
export default loading;
|
@ -1,58 +1,39 @@
|
||||
'use client';
|
||||
import { useState, useEffect } from 'react';
|
||||
import axios from 'axios';
|
||||
import DocumentItem from './documentItem';
|
||||
|
||||
interface Document {
|
||||
name: string;
|
||||
size: string;
|
||||
}
|
||||
"use client";
|
||||
import { useState, useEffect } from "react";
|
||||
import axios from "axios";
|
||||
import DocumentItem from "./DocumentItem";
|
||||
import { Document } from "./types";
|
||||
|
||||
export default function ExplorePage() {
|
||||
const [documents, setDocuments] = useState<Document[]>([]);
|
||||
const [selectedDocument, setSelectedDocument] = useState<Document | null>(null);
|
||||
const [documents, setDocuments] = useState<Document[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
fetchDocuments();
|
||||
}, []);
|
||||
useEffect(() => {
|
||||
fetchDocuments();
|
||||
}, []);
|
||||
|
||||
const fetchDocuments = async () => {
|
||||
try {
|
||||
console.log(`Fetching documents from ${process.env.NEXT_PUBLIC_BACKEND_URL}/explore`);
|
||||
const response = await axios.get<{ documents: Document[] }>(`${process.env.NEXT_PUBLIC_BACKEND_URL}/explore`);
|
||||
setDocuments(response.data.documents);
|
||||
} catch (error) {
|
||||
console.error('Error fetching documents', error);
|
||||
setDocuments([]);
|
||||
}
|
||||
};
|
||||
const fetchDocuments = async () => {
|
||||
try {
|
||||
console.log(
|
||||
`Fetching documents from ${process.env.NEXT_PUBLIC_BACKEND_URL}/explore`
|
||||
);
|
||||
const response = await axios.get<{ documents: Document[] }>(
|
||||
`${process.env.NEXT_PUBLIC_BACKEND_URL}/explore`
|
||||
);
|
||||
setDocuments(response.data.documents);
|
||||
} catch (error) {
|
||||
console.error("Error fetching documents", error);
|
||||
setDocuments([]);
|
||||
}
|
||||
};
|
||||
|
||||
const viewDocument = (document: Document) => {
|
||||
setSelectedDocument(document);
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="pt-20 flex flex-col items-center justify-center p-6">
|
||||
<h1 className="text-4xl mb-6">Explore Files</h1>
|
||||
<div className="overflow-y-auto h-[50vh] w-full max-w-xl">
|
||||
{documents.map((document, index) => (
|
||||
<DocumentItem key={index} document={document} viewDocument={viewDocument} />
|
||||
))}
|
||||
</div>
|
||||
{selectedDocument && (
|
||||
<div className="fixed inset-0 flex items-center justify-center z-10 bg-black bg-opacity-50">
|
||||
<div className="bg-white p-6 w-1/2 h-1/2 overflow-auto rounded-lg">
|
||||
<h2 className="text-2xl mb-4">{selectedDocument.name}</h2>
|
||||
<pre>{JSON.stringify(selectedDocument, null, 2)}</pre>
|
||||
<button
|
||||
onClick={() => setSelectedDocument(null)}
|
||||
className="mt-4 px-4 py-2 bg-blue-500 text-white rounded hover:bg-blue-600 transition duration-200"
|
||||
>
|
||||
Close
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div className="pt-20 flex flex-col items-center justify-center p-6">
|
||||
<h1 className="text-4xl mb-6">Explore Files</h1>
|
||||
<div className="w-full max-w-xl flex flex-col gap-5">
|
||||
{documents.map((document, index) => (
|
||||
<DocumentItem key={index} document={document} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
4
frontend/app/explore/types.ts
Normal file
4
frontend/app/explore/types.ts
Normal file
@ -0,0 +1,4 @@
|
||||
export interface Document {
|
||||
name: string;
|
||||
size: string;
|
||||
}
|
Loading…
Reference in New Issue
Block a user