carnet ui

This commit is contained in:
alma 2025-04-20 15:56:28 +02:00
parent 3a48565b7d
commit fb9c35712b
2 changed files with 73 additions and 13 deletions

View File

@ -124,7 +124,25 @@ async function getWebDAVCredentials(nextcloudUrl: string, username: string, admi
if (cachedCredentials) {
const cacheAge = Date.now() - cachedCredentials.timestamp;
if (cacheAge < 5 * 60 * 1000) { // 5 minutes cache
return cachedCredentials.password;
// Verify the cached credentials still work
const verifyResponse = await fetch(`${nextcloudUrl}/remote.php/dav/files/${encodeURIComponent(username)}/`, {
method: 'PROPFIND',
headers: {
'Authorization': `Basic ${Buffer.from(`${username}:${cachedCredentials.password}`).toString('base64')}`,
'Depth': '1',
'Content-Type': 'application/xml',
},
body: '<?xml version="1.0" encoding="UTF-8"?><d:propfind xmlns:d="DAV:"><d:prop><d:resourcetype/></d:prop></d:propfind>',
});
if (verifyResponse.ok) {
console.log('Using cached credentials');
return cachedCredentials.password;
}
// If verification failed, remove from cache
console.log('Cached credentials verification failed');
credentialsCache.delete(userId);
}
}
@ -145,7 +163,23 @@ async function getWebDAVCredentials(nextcloudUrl: string, username: string, admi
throw new Error(`Failed to get user info: ${userInfoResponse.status} ${userInfoResponse.statusText}`);
}
// Generate a new password
// Try to use the admin password first
const adminVerifyResponse = await fetch(`${nextcloudUrl}/remote.php/dav/files/${encodeURIComponent(username)}/`, {
method: 'PROPFIND',
headers: {
'Authorization': `Basic ${Buffer.from(`${username}:${adminPassword}`).toString('base64')}`,
'Depth': '1',
'Content-Type': 'application/xml',
},
body: '<?xml version="1.0" encoding="UTF-8"?><d:propfind xmlns:d="DAV:"><d:prop><d:resourcetype/></d:prop></d:propfind>',
});
if (adminVerifyResponse.ok) {
console.log('Using admin password for WebDAV access');
return adminPassword;
}
// If admin password doesn't work, generate a new password
const newPassword = Math.random().toString(36).slice(-12);
console.log('Setting new password for user');

View File

@ -1,7 +1,7 @@
"use client";
import React, { useState } from 'react';
import { Search, BookOpen, Tag, Trash2, Star, Archive, X, Folder } from 'lucide-react';
import { Search, BookOpen, Tag, Trash2, Star, Archive, X, Folder, FileText, Calendar, Heart, Users, LucideIcon } from 'lucide-react';
import { PaneLayout } from '@/app/carnet/page';
interface NavigationProps {
@ -11,9 +11,31 @@ interface NavigationProps {
onFolderSelect: (folder: string) => void;
}
type FolderType = 'Notes' | 'Diary' | 'Health' | 'Contacts';
interface FolderConfig {
icon: LucideIcon;
order: number;
}
// Define folder order and icons
const FOLDER_CONFIG: Record<FolderType, FolderConfig> = {
'Notes': { icon: FileText, order: 1 },
'Diary': { icon: Calendar, order: 2 },
'Health': { icon: Heart, order: 3 },
'Contacts': { icon: Users, order: 4 }
};
export default function Navigation({ layout, onLayoutChange, nextcloudFolders, onFolderSelect }: NavigationProps) {
const [searchQuery, setSearchQuery] = useState('');
// Sort folders according to the specified order
const sortedFolders = [...nextcloudFolders].sort((a, b) => {
const orderA = (FOLDER_CONFIG[a as FolderType]?.order) || 999;
const orderB = (FOLDER_CONFIG[b as FolderType]?.order) || 999;
return orderA - orderB;
});
return (
<div className="flex flex-col h-full bg-carnet-sidebar">
{/* Search */}
@ -78,19 +100,23 @@ export default function Navigation({ layout, onLayoutChange, nextcloudFolders, o
</div>
{/* Nextcloud Folders Section */}
{nextcloudFolders.length > 0 && (
{sortedFolders.length > 0 && (
<div className="mt-6 px-3">
<h3 className="px-3 mb-2 text-xs font-medium text-carnet-text-muted uppercase">Vues</h3>
<div className="space-y-0.5">
{nextcloudFolders.map((folder) => (
<div
key={folder}
className="flex items-center px-3 py-2 rounded-md hover:bg-carnet-hover cursor-pointer"
>
<Folder className="w-4 h-4 mr-3 text-carnet-text-muted" />
<span className="text-sm text-carnet-text-primary">{folder}</span>
</div>
))}
{sortedFolders.map((folder) => {
const Icon = FOLDER_CONFIG[folder as FolderType]?.icon || Folder;
return (
<div
key={folder}
className="flex items-center px-3 py-2 rounded-md hover:bg-carnet-hover cursor-pointer"
onClick={() => onFolderSelect(folder)}
>
<Icon className="w-4 h-4 mr-3 text-carnet-text-muted" />
<span className="text-sm text-carnet-text-primary">{folder}</span>
</div>
);
})}
</div>
</div>
)}