v1.6.5: fix attendance unique constraint, schema sync, seed script
- Change attendance idx_attendance_user_date from unique to index (allow multiple shifts per day) - Reset migrations to single baseline init migration - Add seed script with admin user (admin/admin) - Update CLAUDE.md with migration workflow documentation - Various frontend fixes (queries, pages, hooks) Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
@@ -11,6 +11,13 @@ import {
|
||||
attendanceBalancesOptions,
|
||||
attendanceWorkFundOptions,
|
||||
attendanceProjectReportOptions,
|
||||
type BalanceEntry,
|
||||
type BalancesData,
|
||||
type FundData,
|
||||
type FundUserData,
|
||||
type MonthFundData,
|
||||
type ProjectData,
|
||||
type UserShort,
|
||||
} from "../lib/queries/attendance";
|
||||
|
||||
import apiFetch from "../utils/api";
|
||||
@@ -18,70 +25,6 @@ import { Skeleton } from "boneyard-js/react";
|
||||
import AttendanceBalancesFixture from "../fixtures/AttendanceBalancesFixture";
|
||||
const API_BASE = "/api/admin";
|
||||
|
||||
interface BalanceEntry {
|
||||
name: string;
|
||||
vacation_total: number;
|
||||
vacation_used: number;
|
||||
vacation_remaining: number;
|
||||
sick_used: number;
|
||||
}
|
||||
|
||||
interface UserShort {
|
||||
id: number | string;
|
||||
name: string;
|
||||
}
|
||||
|
||||
interface FundUserData {
|
||||
name: string;
|
||||
worked: number;
|
||||
covered: number;
|
||||
overtime: number;
|
||||
missing: number;
|
||||
}
|
||||
|
||||
interface MonthFundData {
|
||||
month_name: string;
|
||||
fund: number;
|
||||
fund_to_date: number;
|
||||
business_days: number;
|
||||
users?: Record<string, FundUserData>;
|
||||
}
|
||||
|
||||
interface ProjectUser {
|
||||
user_id: number;
|
||||
user_name: string;
|
||||
hours: number;
|
||||
}
|
||||
|
||||
interface ProjectEntry {
|
||||
project_id: number | null;
|
||||
project_number?: string;
|
||||
project_name?: string;
|
||||
hours: number;
|
||||
users: ProjectUser[];
|
||||
}
|
||||
|
||||
interface MonthProjectData {
|
||||
month_name: string;
|
||||
projects: ProjectEntry[];
|
||||
}
|
||||
|
||||
interface BalancesData {
|
||||
users: UserShort[];
|
||||
balances: Record<string, BalanceEntry>;
|
||||
}
|
||||
|
||||
interface FundData {
|
||||
months: Record<string, MonthFundData>;
|
||||
holidays: unknown[];
|
||||
users: UserShort[];
|
||||
balances: Record<string, unknown>;
|
||||
}
|
||||
|
||||
interface ProjectData {
|
||||
months: Record<string, MonthProjectData>;
|
||||
}
|
||||
|
||||
const getVacationClass = (remaining: number): string => {
|
||||
if (remaining <= 0) return "text-danger";
|
||||
if (remaining < 20) return "text-warning";
|
||||
@@ -144,18 +87,15 @@ export default function AttendanceBalances() {
|
||||
const { hasPermission } = useAuth();
|
||||
const queryClient = useQueryClient();
|
||||
const [year, setYear] = useState(new Date().getFullYear());
|
||||
const { data: balancesRaw, isPending: balancesPending } = useQuery(
|
||||
const { data: balancesData, isPending: balancesPending } = useQuery(
|
||||
attendanceBalancesOptions(year),
|
||||
);
|
||||
const { data: fundRaw, isPending: fundPending } = useQuery(
|
||||
const { data: fundData, isPending: fundPending } = useQuery(
|
||||
attendanceWorkFundOptions(year),
|
||||
);
|
||||
const { data: projectRaw, isPending: projectPending } = useQuery(
|
||||
const { data: projectData, isPending: projectPending } = useQuery(
|
||||
attendanceProjectReportOptions(year),
|
||||
);
|
||||
const balancesData = balancesRaw as BalancesData | undefined;
|
||||
const fundData = fundRaw as FundData | undefined;
|
||||
const projectData = projectRaw as ProjectData | undefined;
|
||||
|
||||
const [showEditModal, setShowEditModal] = useState(false);
|
||||
const [editingUser, setEditingUser] = useState<{
|
||||
|
||||
Reference in New Issue
Block a user