73 lines
3.8 KiB
Markdown
73 lines
3.8 KiB
Markdown
# EmployeeFormPage
|
|
|
|
**Namespace:** `FrymasterBadgeApp`
|
|
**Base Class:** `ContentPage`
|
|
**Purpose:** Modal page for creating or editing employee records. Handles form binding, photo capture/cropping/zooming, badge generation, and SQL persistence.
|
|
|
|
## 🔑 Fields & Properties
|
|
| Name | Type | Access | Description |
|
|
|------|------|--------|-------------|
|
|
| `_db` | `SqlService` | `private readonly` | Database access service. |
|
|
| `_existingEmployee` | `Dictionary<string, object>?` | `private readonly` | Holds employee data when in edit mode. |
|
|
| `OnSavedCallback` | `Action<Dictionary<string, object>>` | `public` | Callback triggered after successful save. |
|
|
| `_isEditMode` | `bool` | `private readonly` | Determines if page is adding or updating. |
|
|
| `_tempCapturePath` | `string` | `private` | Path to temporarily cached camera image. |
|
|
| `_editX`, `_editY` | `double` | `private` | Current pan offset for photo cropping. |
|
|
| `_photosBasePath` | `string` | `private readonly` | Directory for employee photos (from Preferences). |
|
|
| `IsSaved` | `bool` | `public` | Tracks if save operation completed successfully. |
|
|
| `SavedEmployee` | `Dictionary<string, object>?` | `public` | Stores minimal data of the saved record. |
|
|
|
|
## 🛠 Constructor
|
|
### `EmployeeFormPage(SqlService db, Dictionary<string, object>? employee = null)`
|
|
- **Access:** `public`
|
|
- **Parameters:** `db` (`SqlService`), `employee` (`Dictionary?`, optional)
|
|
- **Behavior:** Binds `ZoomSlider` to `Image.ScaleProperty`. Routes to `SetupEditMode` or `SetupAddMode` based on `employee` parameter.
|
|
|
|
## 📦 Methods
|
|
|
|
### `SetupEditMode(Dictionary<string, object> employee)`
|
|
- **Access:** `private`
|
|
- **Behavior:** Populates form fields, disables `Data1Entry`, parses dates/booleans safely, loads photo if exists, and applies saved crop/zoom state.
|
|
|
|
### `SetupAddMode()`
|
|
- **Access:** `private`
|
|
- **Behavior:** Resets form: title `"Add Employee"`, clears `Data1Entry`, sets date to today, checks `ActiveCheckBox`.
|
|
|
|
### `OnTakePhotoClicked(object sender, EventArgs e)`
|
|
- **Access:** `private async void`
|
|
- **Behavior:** Captures photo via `MediaPicker`, saves to cache as `temp_form_capture.jpg`, updates preview, resets transforms.
|
|
|
|
### `OnPanUpdated(object sender, PanUpdatedEventArgs e)`
|
|
- **Access:** `private`
|
|
- **Behavior:** Updates `TranslationX/Y` in real-time during `Running`; commits offsets to `_editX/_editY` on `Completed`.
|
|
|
|
### `OnFetchBadgeClicked(object sender, EventArgs e)`
|
|
- **Access:** `private async void`
|
|
- **Behavior:** Generates and assigns unique badge to `Data9Entry` via `GenerateUniqueBadgeNumberAsync()`.
|
|
|
|
### `OnSaveClicked(object sender, EventArgs e)`
|
|
- **Access:** `private async void`
|
|
- **Behavior:** Validates `Data2Entry`, copies temp photo to `_photosBasePath` with unique name, builds `SqlParameter` array, executes `INSERT`/`UPDATE`, invokes callback, sets `IsSaved = true`, and pops modal.
|
|
|
|
### `GenerateUniqueBadgeNumberAsync()`
|
|
- **Access:** `private async Task<string>`
|
|
- **Returns:** `Task<string>` (Format: `*$F{6-digit}$A*`)
|
|
|
|
### `GenerateNextRecordNumber()`
|
|
- **Access:** `private`
|
|
- **Returns:** `string`
|
|
- **Behavior:** Queries `MAX(CAST(Data1 AS INT))`, returns next sequential number (starts at `100001`). *Currently unused in save flow.*
|
|
|
|
### `SafeToDouble(object? val, double defaultVal)`
|
|
- **Access:** `private`
|
|
- **Returns:** `double`
|
|
- **Behavior:** Safely parses object to `double`, returns `defaultVal` on failure/null.
|
|
|
|
### `OnCancelClicked(object sender, EventArgs e)`
|
|
- **Access:** `private async void`
|
|
- **Behavior:** Closes modal without saving.
|
|
|
|
---
|
|
**⚠️ Developer Notes:**
|
|
- `OnSaveClicked` contains a nested `try/catch` that calls `Navigation.PopModalAsync()` twice on success. Remove the outer call to prevent `InvalidOperationException`.
|
|
- `GenerateNextRecordNumber()` is implemented but never invoked. Wire it to auto-fill `Data1Entry` or remove it. |