I still can display thumbnails

This commit is contained in:
2025-10-07 23:23:39 +02:00
parent 477d6bf538
commit 707507b128
6 changed files with 74 additions and 18 deletions

View File

@@ -14,6 +14,7 @@ from starlette.responses import Response
from app.api.dependencies import get_document_service, get_current_user
from app.models.document import DocumentResponse, FileDocument
from app.models.user import UserInDB
from app.services.document_service import DocumentService
logger = logging.getLogger(__name__)
@@ -123,7 +124,7 @@ def _map_file_document_to_response(
def list_documents(
skip: int = Query(0, ge=0, description="Number of documents to skip"),
limit: int = Query(100, ge=1, le=1000, description="Maximum number of documents to return"),
UserInDB=Depends(get_current_user),
user: UserInDB = Depends(get_current_user),
document_service: DocumentService = Depends(get_document_service)
) -> List[DocumentResponse]:
"""
@@ -163,7 +164,8 @@ def list_documents(
@router.get("/objects/{file_hash}")
async def get_object_by_hash(
file_hash: str = Path(..., description="SHA256 hash of the object to retrieve"),
document_service: DocumentService = Depends(get_document_service)
document_service: DocumentService = Depends(get_document_service),
user: UserInDB = Depends(get_current_user),
):
"""
Serve object content by its hash.

View File

@@ -13,7 +13,7 @@ const Header = () => {
};
return (
<div className="navbar bg-base-100 shadow-lg">
<div className="navbar bg-base-100">
<div className="navbar-start">
<h1 className="text-xl font-bold">MyDocManager</h1>
</div>

View File

@@ -1,15 +1,20 @@
import Header from './Header';
import {Outlet} from 'react-router-dom';
import Menu from "./Menu.jsx";
import styles from './Layout.module.css';
const Layout = () => {
return (
<div className="min-h-screen bg-base-200">
<div className={styles.layoutContainer}>
<Header/>
<div className="flex">
<aside className="w-64 min-h-screen bg-base-100 shadow-lg"><Menu/></aside>
<main className="flex-1 container mx-auto px-4 py-8">
<div className="flex flex-1 overflow-hidden">
<aside className={styles.sidebar}>
<Menu/>
</aside>
<main className={styles.mainContent}>
<div className={styles.mainContentInner}>
<Outlet/>
</div>
</main>
</div>
</div>

View File

@@ -0,0 +1,30 @@
/* Layout Container */
.layoutContainer {
height: 100vh;
display: flex;
flex-direction: column;
background-color: var(--color-base-200);
}
/* Sidebar */
.sidebar {
width: 16rem; /* 64px = 4rem, donc 256px = 16rem */
background-color: var(--color-base-100);
box-shadow: 0 10px 15px -3px rgb(0 0 0 / 0.1), 0 4px 6px -4px rgb(0 0 0 / 0.1);
overflow-y: auto;
}
/* Main Content Area */
.mainContent {
flex: 1;
overflow-y: auto;
}
/* Main Content Inner Container */
.mainContentInner {
max-width: 80rem; /* container max-width */
margin-left: auto;
margin-right: auto;
padding: 2rem 1rem;
}

View File

@@ -4,7 +4,8 @@
* Supports different view modes: small, large, and detail
*/
import React, { memo } from 'react';
import React, {memo} from 'react';
import {API_BASE_URL} from "../../utils/api.js";
/**
* Formats file size to human-readable format
@@ -32,6 +33,18 @@ const formatDate = (dateString) => {
});
};
/**
* Builds full URL from relative path
* @param {string} relativePath - Relative API path
* @returns {string} Full URL
*/
const buildFullUrl = (relativePath) => {
if (!relativePath) return '';
// Use the base URL from your API configuration
const baseUrl = import.meta.env.VITE_API_BASE_URL || API_BASE_URL;
return `${baseUrl}${relativePath}`;
};
/**
* DocumentCard component
* @param {Object} props
@@ -41,8 +54,8 @@ const formatDate = (dateString) => {
* @param {function(): void} props.onDelete - Callback when delete is clicked
* @returns {JSX.Element}
*/
const DocumentCard = memo(({ document, viewMode, onEdit, onDelete }) => {
const { name, originalFileType, thumbnailUrl, pageCount, fileSize, createdAt, tags, categories } = document;
const DocumentCard = memo(({document, viewMode, onEdit, onDelete}) => {
const {name, originalFileType, thumbnailUrl, pageCount, fileSize, createdAt, tags, categories} = document;
// Determine card classes based on view mode
const getCardClasses = () => {
@@ -64,9 +77,9 @@ const DocumentCard = memo(({ document, viewMode, onEdit, onDelete }) => {
const renderThumbnail = () => (
<figure className="relative overflow-hidden">
<img
src={`http://localhost:8000${thumbnailUrl}`}
alt={`${thumbnailUrl} thumbnail`}
className={`w-full object-cover ${
src={buildFullUrl(thumbnailUrl)}
alt={`${name}`}
className={`w-[200px] object-cover ${
viewMode === 'small' ? 'h-32' : viewMode === 'large' ? 'h-48' : 'h-64'
}`}
loading="lazy"
@@ -80,8 +93,10 @@ const DocumentCard = memo(({ document, viewMode, onEdit, onDelete }) => {
aria-label="Edit document"
title="Edit"
>
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" />
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4" fill="none" viewBox="0 0 24 24"
stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
d="M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z"/>
</svg>
</button>
<button
@@ -90,8 +105,10 @@ const DocumentCard = memo(({ document, viewMode, onEdit, onDelete }) => {
aria-label="Delete document"
title="Delete"
>
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" />
<svg xmlns="http://www.w3.org/2000/svg" className="h-4 w-4" fill="none" viewBox="0 0 24 24"
stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2}
d="M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16"/>
</svg>
</button>
</div>

View File

@@ -12,6 +12,8 @@ const api = axios.create({
},
});
export { API_BASE_URL };
// Request interceptor to add authentication token
api.interceptors.request.use(
(config) => {