Zwiscshenstand - laufende Version
Dieser Commit ist enthalten in:
@ -1,6 +1,6 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import api from '../services/api'
|
||||
import { DeputyAssignment, Employee } from '@skillmate/shared'
|
||||
import type { DeputyAssignment, Employee } from '@skillmate/shared'
|
||||
import { useAuthStore } from '../stores/authStore'
|
||||
|
||||
export default function DeputyManagement() {
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useEffect, useState, useCallback } from 'react'
|
||||
import { OrganizationalUnit, EmployeeUnitAssignment } from '@skillmate/shared'
|
||||
import type { OrganizationalUnit, EmployeeUnitAssignment } from '@skillmate/shared'
|
||||
import api from '../services/api'
|
||||
import { useAuthStore } from '../stores/authStore'
|
||||
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { OrganizationalUnit } from '@skillmate/shared'
|
||||
import type { OrganizationalUnit } from '@skillmate/shared'
|
||||
import api from '../services/api'
|
||||
import { ChevronRight, Building2, Search, X } from 'lucide-react'
|
||||
|
||||
@ -277,4 +277,4 @@ export default function OrganizationSelector({ value, onChange, disabled }: Orga
|
||||
)}
|
||||
</>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { UserRole } from '@skillmate/shared'
|
||||
import type { UserRole } from '@skillmate/shared'
|
||||
import { useAuthStore } from '../stores/authStore'
|
||||
|
||||
// Define role permissions directly to avoid import issues
|
||||
@ -94,4 +94,4 @@ export function usePermissions() {
|
||||
user,
|
||||
isAuthenticated
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import axios from 'axios'
|
||||
import { Employee } from '@skillmate/shared'
|
||||
import type { Employee } from '@skillmate/shared'
|
||||
|
||||
const API_BASE_URL = (import.meta as any).env?.VITE_API_URL || 'http://localhost:3004/api'
|
||||
|
||||
@ -31,7 +31,8 @@ export const authApi = {
|
||||
|
||||
export const employeeApi = {
|
||||
getAll: async () => {
|
||||
const response = await api.get('/employees/public')
|
||||
// Hole vollständige Liste (berechtigt durch employees:read)
|
||||
const response = await api.get('/employees')
|
||||
return response.data.data
|
||||
},
|
||||
getById: async (id: string) => {
|
||||
|
||||
@ -1,7 +1,7 @@
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import { api } from '../services/api'
|
||||
import { Workspace, Booking, WorkspaceFilter } from '@skillmate/shared'
|
||||
import type { Workspace, Booking, WorkspaceFilter } from '@skillmate/shared'
|
||||
|
||||
export default function DeskBooking() {
|
||||
const navigate = useNavigate()
|
||||
@ -257,4 +257,4 @@ export default function DeskBooking() {
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,6 +4,7 @@ import type { Employee } from '@skillmate/shared'
|
||||
import { employeeApi } from '../services/api'
|
||||
import { SKILL_HIERARCHY, LANGUAGE_LEVELS } from '../data/skillCategories'
|
||||
import PhotoPreview from '../components/PhotoPreview'
|
||||
import OrganizationSelector from '../components/OrganizationSelector'
|
||||
|
||||
export default function EmployeeForm() {
|
||||
const navigate = useNavigate()
|
||||
@ -28,6 +29,8 @@ export default function EmployeeForm() {
|
||||
languages: [] as string[],
|
||||
specializations: [] as string[]
|
||||
})
|
||||
const [primaryUnitId, setPrimaryUnitId] = useState<string | null>(null)
|
||||
const [primaryUnitName, setPrimaryUnitName] = useState<string>('')
|
||||
|
||||
const [employeePhoto, setEmployeePhoto] = useState<string | null>(null)
|
||||
const [photoFile, setPhotoFile] = useState<File | null>(null)
|
||||
@ -178,6 +181,7 @@ export default function EmployeeForm() {
|
||||
if (!formData.email.trim()) errors.email = 'E-Mail ist erforderlich'
|
||||
else if (!/\S+@\S+\.\S+/.test(formData.email)) errors.email = 'Ungültige E-Mail-Adresse'
|
||||
if (!formData.phone.trim()) errors.phone = 'Telefonnummer ist erforderlich'
|
||||
if (!primaryUnitId) errors.primaryUnitId = 'Organisatorische Einheit ist erforderlich'
|
||||
|
||||
setValidationErrors(errors)
|
||||
return Object.keys(errors).length === 0
|
||||
@ -220,7 +224,7 @@ export default function EmployeeForm() {
|
||||
createdBy: 'admin'
|
||||
}
|
||||
|
||||
const result = await employeeApi.create(newEmployee)
|
||||
const result = await employeeApi.create({ ...newEmployee, primaryUnitId })
|
||||
const newEmployeeId = result.data.id
|
||||
|
||||
// Upload photo if we have one
|
||||
@ -407,6 +411,23 @@ export default function EmployeeForm() {
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div className="md:col-span-2">
|
||||
<label className="block text-sm font-medium text-secondary mb-2">
|
||||
Organisatorische Einheit (Primär) *
|
||||
</label>
|
||||
<OrganizationSelector
|
||||
value={primaryUnitId || undefined}
|
||||
onChange={(unitId, unitName) => {
|
||||
setPrimaryUnitId(unitId)
|
||||
setPrimaryUnitName(unitName)
|
||||
}}
|
||||
/>
|
||||
<p className="text-tertiary text-sm mt-2">{primaryUnitName || 'Bitte auswählen'}</p>
|
||||
{validationErrors.primaryUnitId && (
|
||||
<p className="mt-1 text-sm text-red-600">{validationErrors.primaryUnitId}</p>
|
||||
)}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className="block text-sm font-medium text-secondary mb-2">
|
||||
Telefon *
|
||||
|
||||
@ -1,10 +1,10 @@
|
||||
import { useState, useEffect } from 'react'
|
||||
import { useNavigate } from 'react-router-dom'
|
||||
import type { Employee } from '@skillmate/shared'
|
||||
import { SearchIcon } from '../components/icons'
|
||||
import EmployeeCard from '../components/EmployeeCard'
|
||||
import { employeeApi } from '../services/api'
|
||||
import { useAuthStore } from '../stores/authStore'
|
||||
import type { Employee } from '@skillmate/shared'
|
||||
import { usePermissions } from '../hooks/usePermissions'
|
||||
|
||||
export default function EmployeeList() {
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { api } from '../services/api'
|
||||
import { Workspace, Booking } from '@skillmate/shared'
|
||||
import type { Workspace, Booking } from '@skillmate/shared'
|
||||
|
||||
interface WorkspaceWithStatus extends Workspace {
|
||||
isBooked?: boolean
|
||||
@ -248,4 +248,4 @@ export default function FloorPlan() {
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -962,4 +962,4 @@ export default function TeamZusammenstellung() {
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -11,16 +11,33 @@ export default defineConfig({
|
||||
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV || 'production'),
|
||||
'process.platform': JSON.stringify('win32')
|
||||
},
|
||||
server: {
|
||||
port: 5173,
|
||||
strictPort: true,
|
||||
fs: {
|
||||
// erlaubt Zugriff auf Monorepo-Nachbarordner (z. B. ../shared)
|
||||
allow: ['..']
|
||||
}
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': path.resolve(__dirname, './src'),
|
||||
},
|
||||
// erhöht Kompatibilität mit verlinkten/local deps
|
||||
preserveSymlinks: true,
|
||||
},
|
||||
optimizeDeps: {
|
||||
include: ['@skillmate/shared'],
|
||||
},
|
||||
build: {
|
||||
outDir: 'dist',
|
||||
emptyOutDir: true,
|
||||
commonjsOptions: {
|
||||
include: [/node_modules/, /@skillmate\/shared/],
|
||||
transformMixedEsModules: true,
|
||||
},
|
||||
rollupOptions: {
|
||||
external: ['electron'],
|
||||
}
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
In neuem Issue referenzieren
Einen Benutzer sperren