Initial commit: ArchiTools modular dashboard platform
Complete Next.js 16 application with 13 fully implemented modules: Email Signature, Word XML Generator, Registratura, Dashboard, Tag Manager, IT Inventory, Address Book, Password Vault, Mini Utilities, Prompt Generator, Digital Signatures, Word Templates, and AI Chat. Includes core platform systems (module registry, feature flags, storage abstraction, i18n, theming, auth stub, tagging), 16 technical documentation files, Docker deployment config, and legacy HTML tool reference. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
73
src/modules/digital-signatures/hooks/use-signatures.ts
Normal file
73
src/modules/digital-signatures/hooks/use-signatures.ts
Normal file
@@ -0,0 +1,73 @@
|
||||
'use client';
|
||||
|
||||
import { useState, useEffect, useCallback } from 'react';
|
||||
import { useStorage } from '@/core/storage';
|
||||
import { v4 as uuid } from 'uuid';
|
||||
import type { SignatureAsset, SignatureAssetType } from '../types';
|
||||
|
||||
const PREFIX = 'sig:';
|
||||
|
||||
export interface SignatureFilters {
|
||||
search: string;
|
||||
type: SignatureAssetType | 'all';
|
||||
}
|
||||
|
||||
export function useSignatures() {
|
||||
const storage = useStorage('digital-signatures');
|
||||
const [assets, setAssets] = useState<SignatureAsset[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [filters, setFilters] = useState<SignatureFilters>({ search: '', type: 'all' });
|
||||
|
||||
const refresh = useCallback(async () => {
|
||||
setLoading(true);
|
||||
const keys = await storage.list();
|
||||
const results: SignatureAsset[] = [];
|
||||
for (const key of keys) {
|
||||
if (key.startsWith(PREFIX)) {
|
||||
const item = await storage.get<SignatureAsset>(key);
|
||||
if (item) results.push(item);
|
||||
}
|
||||
}
|
||||
results.sort((a, b) => b.createdAt.localeCompare(a.createdAt));
|
||||
setAssets(results);
|
||||
setLoading(false);
|
||||
}, [storage]);
|
||||
|
||||
// eslint-disable-next-line react-hooks/set-state-in-effect
|
||||
useEffect(() => { refresh(); }, [refresh]);
|
||||
|
||||
const addAsset = useCallback(async (data: Omit<SignatureAsset, 'id' | 'createdAt'>) => {
|
||||
const asset: SignatureAsset = { ...data, id: uuid(), createdAt: new Date().toISOString() };
|
||||
await storage.set(`${PREFIX}${asset.id}`, asset);
|
||||
await refresh();
|
||||
return asset;
|
||||
}, [storage, refresh]);
|
||||
|
||||
const updateAsset = useCallback(async (id: string, updates: Partial<SignatureAsset>) => {
|
||||
const existing = assets.find((a) => a.id === id);
|
||||
if (!existing) return;
|
||||
const updated = { ...existing, ...updates, id: existing.id, createdAt: existing.createdAt };
|
||||
await storage.set(`${PREFIX}${id}`, updated);
|
||||
await refresh();
|
||||
}, [storage, refresh, assets]);
|
||||
|
||||
const removeAsset = useCallback(async (id: string) => {
|
||||
await storage.delete(`${PREFIX}${id}`);
|
||||
await refresh();
|
||||
}, [storage, refresh]);
|
||||
|
||||
const updateFilter = useCallback(<K extends keyof SignatureFilters>(key: K, value: SignatureFilters[K]) => {
|
||||
setFilters((prev) => ({ ...prev, [key]: value }));
|
||||
}, []);
|
||||
|
||||
const filteredAssets = assets.filter((a) => {
|
||||
if (filters.type !== 'all' && a.type !== filters.type) return false;
|
||||
if (filters.search) {
|
||||
const q = filters.search.toLowerCase();
|
||||
return a.label.toLowerCase().includes(q) || a.owner.toLowerCase().includes(q);
|
||||
}
|
||||
return true;
|
||||
});
|
||||
|
||||
return { assets: filteredAssets, allAssets: assets, loading, filters, updateFilter, addAsset, updateAsset, removeAsset, refresh };
|
||||
}
|
||||
Reference in New Issue
Block a user