208 lines
6.0 KiB
JavaScript
208 lines
6.0 KiB
JavaScript
import { useState, useEffect, useCallback } from 'react'
|
|
import { databases, account, DATABASE_ID, COLLECTIONS, ID, Query } from '../lib/appwrite'
|
|
|
|
const DEMO_MODE = !import.meta.env.VITE_APPWRITE_PROJECT_ID
|
|
|
|
// Demo-Mitarbeiter für Testing
|
|
const DEMO_EMPLOYEES = [
|
|
{ $id: '1', userId: 'user1', displayName: 'Kenso Grimm', email: 'kenso@example.com', shortcode: 'KNSO' },
|
|
{ $id: '2', userId: 'user2', displayName: 'Christian Lehmann', email: 'christian@example.com', shortcode: 'CHLE' }
|
|
]
|
|
|
|
export function useEmployees() {
|
|
const [employees, setEmployees] = useState([])
|
|
const [loading, setLoading] = useState(true)
|
|
const [error, setError] = useState(null)
|
|
const [syncing, setSyncing] = useState(false)
|
|
|
|
const fetchEmployees = useCallback(async () => {
|
|
setLoading(true)
|
|
|
|
if (DEMO_MODE) {
|
|
setEmployees(DEMO_EMPLOYEES)
|
|
setLoading(false)
|
|
return
|
|
}
|
|
|
|
try {
|
|
const response = await databases.listDocuments(
|
|
DATABASE_ID,
|
|
COLLECTIONS.EMPLOYEES,
|
|
[Query.orderAsc('displayName')]
|
|
)
|
|
setEmployees(response.documents)
|
|
setError(null)
|
|
} catch (err) {
|
|
console.error('Error fetching employees:', err)
|
|
// Wenn Collection nicht existiert, setze leeres Array (kein Fehler)
|
|
if (err.code === 404 || err.message?.includes('not found')) {
|
|
setEmployees([])
|
|
setError(null) // Kein Fehler, Collection existiert einfach noch nicht
|
|
} else {
|
|
setError(err.message)
|
|
setEmployees([])
|
|
}
|
|
} finally {
|
|
setLoading(false)
|
|
}
|
|
}, [])
|
|
|
|
useEffect(() => {
|
|
fetchEmployees()
|
|
}, [fetchEmployees])
|
|
|
|
const createEmployee = async (data) => {
|
|
if (DEMO_MODE) {
|
|
const newEmployee = { ...data, $id: Date.now().toString() }
|
|
setEmployees(prev => [...prev, newEmployee])
|
|
return { success: true, data: newEmployee }
|
|
}
|
|
|
|
try {
|
|
// Validierung
|
|
if (!data.userId || !data.displayName) {
|
|
return { success: false, error: 'userId und displayName sind erforderlich' }
|
|
}
|
|
|
|
const response = await databases.createDocument(
|
|
DATABASE_ID,
|
|
COLLECTIONS.EMPLOYEES,
|
|
ID.unique(),
|
|
{
|
|
userId: data.userId,
|
|
displayName: data.displayName,
|
|
email: data.email || '',
|
|
shortcode: data.shortcode || ''
|
|
}
|
|
)
|
|
setEmployees(prev => [...prev, response])
|
|
return { success: true, data: response }
|
|
} catch (err) {
|
|
console.error('Error creating employee:', err)
|
|
return { success: false, error: err.message }
|
|
}
|
|
}
|
|
|
|
const updateEmployee = async (id, data) => {
|
|
if (DEMO_MODE) {
|
|
setEmployees(prev => prev.map(e => e.$id === id ? { ...e, ...data } : e))
|
|
return { success: true }
|
|
}
|
|
|
|
try {
|
|
const response = await databases.updateDocument(
|
|
DATABASE_ID,
|
|
COLLECTIONS.EMPLOYEES,
|
|
id,
|
|
data
|
|
)
|
|
setEmployees(prev => prev.map(e => e.$id === id ? response : e))
|
|
return { success: true, data: response }
|
|
} catch (err) {
|
|
console.error('Error updating employee:', err)
|
|
return { success: false, error: err.message }
|
|
}
|
|
}
|
|
|
|
const deleteEmployee = async (id) => {
|
|
if (DEMO_MODE) {
|
|
setEmployees(prev => prev.filter(e => e.$id !== id))
|
|
return { success: true }
|
|
}
|
|
|
|
try {
|
|
await databases.deleteDocument(
|
|
DATABASE_ID,
|
|
COLLECTIONS.EMPLOYEES,
|
|
id
|
|
)
|
|
setEmployees(prev => prev.filter(e => e.$id !== id))
|
|
return { success: true }
|
|
} catch (err) {
|
|
console.error('Error deleting employee:', err)
|
|
return { success: false, error: err.message }
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Synchronisiert Appwrite Auth Users mit der employees Collection
|
|
* Erstellt fehlende Einträge für neue Users
|
|
*/
|
|
const syncWithAuthUsers = async () => {
|
|
if (DEMO_MODE) {
|
|
return { success: true, message: 'Demo-Modus: Keine Synchronisierung nötig' }
|
|
}
|
|
|
|
setSyncing(true)
|
|
|
|
try {
|
|
// 1. Lade alle Appwrite Auth Users
|
|
// Hinweis: In Appwrite 1.5.7 gibt es möglicherweise keine direkte List-Users API
|
|
// für normale User. Diese Funktion benötigt Server-Side Code oder Admin-API-Key.
|
|
// Für jetzt implementieren wir einen Workaround: Wir bieten ein manuelles Add-Interface.
|
|
|
|
// Alternative: Wenn der User Appwrite Admin ist, können wir versuchen:
|
|
// const users = await account.listUsers() // Funktioniert nur mit Admin-Rechten
|
|
|
|
// Da das nicht direkt möglich ist, geben wir eine Info zurück
|
|
return {
|
|
success: false,
|
|
error: 'Automatische Synchronisierung erfordert Admin-API-Zugriff. Bitte füge Mitarbeiter manuell hinzu oder verwende die Appwrite Server API.'
|
|
}
|
|
} catch (err) {
|
|
console.error('Error syncing auth users:', err)
|
|
return { success: false, error: err.message }
|
|
} finally {
|
|
setSyncing(false)
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Erstellt einen Employee-Eintrag für den aktuell eingeloggten User
|
|
* Nützlich für Self-Service
|
|
*/
|
|
const createSelfEmployee = async (shortcode = '') => {
|
|
if (DEMO_MODE) {
|
|
return { success: true, message: 'Demo-Modus' }
|
|
}
|
|
|
|
try {
|
|
// Hole aktuellen User
|
|
const currentUser = await account.get()
|
|
|
|
// Prüfe, ob Employee bereits existiert
|
|
const existing = employees.find(e => e.userId === currentUser.$id)
|
|
if (existing) {
|
|
return { success: false, error: 'Mitarbeiter-Eintrag existiert bereits' }
|
|
}
|
|
|
|
// Erstelle Employee-Eintrag
|
|
const result = await createEmployee({
|
|
userId: currentUser.$id,
|
|
displayName: currentUser.name || currentUser.email,
|
|
email: currentUser.email,
|
|
shortcode: shortcode
|
|
})
|
|
|
|
return result
|
|
} catch (err) {
|
|
console.error('Error creating self employee:', err)
|
|
return { success: false, error: err.message }
|
|
}
|
|
}
|
|
|
|
return {
|
|
employees,
|
|
loading,
|
|
error,
|
|
syncing,
|
|
refresh: fetchEmployees,
|
|
createEmployee,
|
|
updateEmployee,
|
|
deleteEmployee,
|
|
syncWithAuthUsers,
|
|
createSelfEmployee
|
|
}
|
|
}
|
|
|