Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/dmaman86/shiftly/llms.txt

Use this file to discover all available pages before exploring further.

The Monthly view gives you a complete gross-salary picture for any month without requiring you to enter individual shifts. It reads the same globalBreakdown (MonthPayMap) that the Daily view builds incrementally, then resolves per-diem and meal-allowance rates from a historical timeline for the selected period. Enter your hourly base rate and the summary instantly converts accrued hours and allowance points into shekel amounts.
Both the Daily and Monthly views share the exact same domain calculation pipeline. The MonthPayMap that powers this page is built up incrementally in the Daily view by MonthPayMapReducer.accumulate() and .subtract() — switching to the Monthly view simply presents the same data in a summarised card layout.

What the Monthly View Shows

The MonthlySalarySummary component divides the breakdown into three card sections. Each section lists individual pay types with their quantity, per-unit rate (derived from the configured base rate and the relevant multiplier or historical rate), and running sub-total. A grand total line appears below all sections.

Section 1 — Base Hours

Aggregated hours at fixed or statutory rates:
Pay TypeSource FieldRate
Regular 100%regular.hours1001× base rate
Shabbat bonus 100%extra100Shabbat1× base rate
Sick hourshours100Sick1× base rate
Vacation hourshours100Vacation1× base rate

Section 2 — Extras & Overtime

Overtime tiers and time-of-day additions:
Pay TypeSource FieldRate
125% overtimeregular.hours1251.25× base rate
150% overtimeregular.hours1501.5× base rate
Shabbat 150%special.shabbat1501.5× base rate
Shabbat 200%special.shabbat2002× base rate
Evening bonus (20%)extra.hours200.2× base rate
Night bonus (50%)extra.hours500.5× base rate

Section 3 — Meal Allowance

Allowance points and amounts resolved at the historical rate for the selected year/month:
Pay TypeSource FieldDescription
Per-diem allowanceperDiem.points / perDiem.amountTier A/B/C per-diem; amount uses the rate timeline.
Large meal allowancemealAllowance.large.points / .amountLarge-allowance points × current historical rate.
Small meal allowancemealAllowance.small.points / .amountSmall-allowance points (shift C) × current historical rate.

Why Year and Month Selection Matters

Per-diem and meal-allowance monetary rates are not constant — they change over time via government-published updates. Shiftly stores a timeline of these historical rate periods. When the Monthly Summary renders, it looks up the applicable rate for the exact year and month you have selected in the Configuration panel. Selecting the wrong period will return an incorrect per-unit rate for allowances, even if the underlying points totals are accurate. Always confirm the year and month in the Configuration panel before reading the ₪ amounts in the summary.
// MonthlySalarySummary.tsx — sections update whenever year/month/baseRate change
useEffect(() => {
  updateSections(globalBreakdown, year, month, baseRate);
}, [globalBreakdown, year, month, baseRate, updateSections]);

The MonthPayMap Data Structure

The globalBreakdown held in Redux state is of type MonthPayMap. All fields are derived from accumulating individual WorkDayMap values throughout the month:
interface MonthPayMap {
  // Regular-hour tiers
  regular: RegularBreakdown;   // { hours100, hours125, hours150 }

  // Night and evening bonuses
  extra: ExtraBreakdown;       // { hours20, hours50 }

  // Shabbat and holiday rates
  special: SpecialBreakdown;   // { shabbat150, shabbat200 }

  // Fixed-rate absence segments
  hours100Sick: Segment;       // { percent: 1, hours: number }
  hours100Vacation: Segment;   // { percent: 1, hours: number }

  // Shabbat-eve extra 100% segment
  extra100Shabbat: Segment;

  // Per-diem allowance (rate resolved by historical timeline)
  perDiem: PerDiemInfo;        // { tier: "A" | "B" | "C" | null, points, amount }

  // Meal allowances (rates resolved by historical timeline)
  mealAllowance: MealAllowance; // { small: { points, amount }, large: { points, amount } }

  // Running total across all shifts
  totalHours: number;
}
Each Segment carries a percent multiplier (1 = 100%, 1.25 = 125%, etc.) and the accumulated hours for that category.

Incremental Accumulation via MonthPayMapReducer

The MonthPayMapReducer class is responsible for keeping globalBreakdown current without reprocessing the whole month. It exposes two mutating methods:
  • accumulate(base, add) — adds a WorkDayMap (one day’s pay result) into the running MonthPayMap. Called when a shift is saved or a sick/vacation day is confirmed.
  • subtract(base, sub) — removes a previously-accumulated WorkDayMap from the running total. Called when a shift is edited (the old value is subtracted before the new one is accumulated) or a day’s shifts are all deleted.
// globalSlice.ts — addDayPayMap reducer
addDayPayMap: (state, action) => {
  const { dateKey, dayPayMap } = action.payload;
  const prev = state.dailyPayMaps[dateKey];

  // Remove previous contribution for this day
  if (prev) {
    state.globalBreakdown = payMap.monthPayMapCalculator.subtract(
      state.globalBreakdown,
      prev,
    );
  }

  // Add the new contribution
  state.globalBreakdown = payMap.monthPayMapCalculator.accumulate(
    state.globalBreakdown,
    dayPayMap,
  );

  state.dailyPayMaps[dateKey] = dayPayMap;
},
Changing the year or month in the Configuration panel dispatches setYear or setMonth, which calls resetMonthData() internally. This clears globalBreakdown back to an empty MonthPayMap and empties dailyPayMaps — effectively starting a fresh calculation for the new period. The Monthly view is accessible from the top navigation bar under Monthly, and also via the link in the Daily view’s subtitle: “Want to calculate monthly salary without entering shifts? Go to Monthly Summary.” The page uses the same ConfigPanel in mode="monthly", which shows a blue info banner confirming which month and year the calculation is based on, and marks the base-rate field as required.

Daily View

Enter individual shifts and see per-day pay breakdowns that feed this monthly summary.

Calculation Rules

Understand the Israeli labor law rules — overtime tiers, night bonuses, and Shabbat rates — that determine every value in this summary.

Build docs developers (and LLMs) love