// drive-page.jsx — Google Drive інтеграція function DrivePage({ role }) { const objects = window.DATA.OBJECTS; const [connected, setConnected] = React.useState(true); // demo const [openId, setOpenId] = React.useState(null); const stats = { objects: objects.length, files: 1247, folders: objects.length * 6, storage: "12.4 GB", limit: "100 GB", }; return (

Google Drive

сховище проєктної документації підключено акаунт files@ukrbudproiekt.ua
{/* Стан інтеграції */}
Інтеграція активна
Остання синхронізація · сьогодні о 14:32 · OAuth 2.0
синхронізовано
{/* KPI */}
Файлів у Drive
{stats.files}
PDF · DWG · DOCX · фото
Папок об'єктів
{stats.objects}
по 6 підпапок кожна
Зайнято
{stats.storage}
з {stats.limit} ліміту · 12%
Останнє оновлення
14:32
авто-синхронізація кожні 5 хв
Як працює: на кожен об'єкт автоматично створюється папка з шифром у Google Drive (наприклад [УКП-2025-47] ЖК Подільський) з підпапками: 01-Договір, 02-Вхідні дані, 03-Проєкт, 04-Кошторис, 05-Експертиза, 06-Фотофіксація. Завантаження документів зі сторінки об'єкта потрапляє безпосередньо в Drive.
{/* Папки об'єктів */}

Папки об'єктів

{objects.length} активних
{objects.map(o => ( setOpenId(o.id)} /> ))}
{/* Папки проєктів ГО */} {(window.DATA.PROJECTS || []).length > 0 && (

Папки проєктів ГО

{window.DATA.PROJECTS.length} проєктів
{window.DATA.PROJECTS.map(p => ( ))}
)} {openId && o.id === openId)} onClose={() => setOpenId(null)} />}
); } function DriveFolderCard({ obj, onOpen }) { // Симульована статистика const fileCount = 240 + (obj.id.charCodeAt(0) % 60); const sizeMb = 1800 + (obj.id.charCodeAt(0) % 800); return (
[{obj.code}]
{obj.name}
{fileCount} файлів · {(sizeMb / 1024).toFixed(1)} GB
); } function DriveFolderModal({ obj, onClose }) { React.useEffect(() => { const onKey = (e) => e.key === "Escape" && onClose(); window.addEventListener("keydown", onKey); return () => window.removeEventListener("keydown", onKey); }, [onClose]); const subfolders = [ { name: "01-Договір", files: 4, size: "12 MB", icon: "📄" }, { name: "02-Вхідні дані", files: 18, size: "245 MB", icon: "📥" }, { name: "03-Проєкт", files: 142, size: "1.2 GB", icon: "📐" }, { name: "04-Кошторис", files: 8, size: "34 MB", icon: "💰" }, { name: "05-Експертиза", files: 12, size: "186 MB", icon: "📋" }, { name: "06-Фотофіксація", files: 86, size: "412 MB", icon: "📷" }, ]; const recentFiles = [ { name: "КЖ_Розділ-3_фундаменти_v4.pdf", type: "pdf", folder: "03-Проєкт", size: "8.4 MB", changed: "Сьогодні 14:32", by: "Петренко А." }, { name: "Фасади_варіанти_v2.dwg", type: "dwg", folder: "03-Проєкт", size: "24 MB", changed: "Вчора 18:15", by: "Мельник Т." }, { name: "Кошторис_АВК-5_травень.docx", type: "doc", folder: "04-Кошторис", size: "1.2 MB", changed: "Вчора 11:42", by: "Кравченко О." }, { name: "Виїзд_25.05_фото.zip", type: "zip", folder: "06-Фотофіксація", size: "186 MB", changed: "25.05 17:30", by: "Кравченко О." }, { name: "Технічне_завдання_замовник.pdf", type: "pdf", folder: "02-Вхідні дані", size: "3.4 MB", changed: "20.05 09:00", by: "Гриценко О." }, ]; const fileIcon = (t) => ({ pdf: "file", dwg: "ruler", doc: "file", zip: "package", img: "image" })[t] || "file"; return ( <>
[{obj.code}] {obj.name}
{/* Підпапки */}

Структура папок

6 підпапок
{subfolders.map(sf => (
{sf.name}
{sf.files} файлів · {sf.size}
))}
{/* Останні файли */}

Останні зміни

{recentFiles.length} файлів
{recentFiles.map((f, i) => ( ))}
Файл Папка Розмір Автор Змінено
{f.name}
{f.folder} {f.size} {f.by} {f.changed}
); } function ProjectDriveCard({ project }) { const p = project; const partner = window.getNgoPartner(p.partner); const docCount = (p.docs || []).length; return (
window.open("https://drive.google.com", "_blank")}>
[{p.code}]
{p.name}
{partner?.short} · {docCount} {window.plural(docCount, "документ", "документи", "документів")}
); } window.DrivePage = DrivePage;