Compare commits
25 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5233db2002 | ||
|
|
dac45baaa8 | ||
|
|
f389c4b3cf | ||
|
|
fdc7037e60 | ||
|
|
b02f6afe93 | ||
|
|
1b2ab7b4eb | ||
|
|
29975ecad9 | ||
|
|
e846f15126 | ||
|
|
86bebf9776 | ||
|
|
7b7c6bde68 | ||
|
|
935fb235a6 | ||
|
|
d2d1cdbb92 | ||
|
|
5f08b0e086 | ||
|
|
637499a8ec | ||
|
|
f413bae348 | ||
|
|
2b1de583fd | ||
|
|
5500cdb118 | ||
|
|
2254a13ad0 | ||
|
|
1f5885de84 | ||
|
|
705f58e3d1 | ||
|
|
0330453ad6 | ||
|
|
66b98e2765 | ||
|
|
55648c9a30 | ||
|
|
cd6d3daf43 | ||
|
|
1db5060c42 |
@@ -1,43 +0,0 @@
|
||||
---
|
||||
name: compare-php
|
||||
description: Compare a feature between PHP boha-app and TS boha-app-ts to verify migration parity
|
||||
---
|
||||
|
||||
# Compare PHP vs TS Implementation
|
||||
|
||||
Compare a specific feature, component, or endpoint between the original PHP project (D:\cortex\boha-app) and the TypeScript migration (D:\cortex\boha-app-ts).
|
||||
|
||||
## Usage
|
||||
|
||||
The user will specify what to compare. Examples:
|
||||
- `/compare-php attendance print`
|
||||
- `/compare-php invoice PDF generation`
|
||||
- `/compare-php offer numbering logic`
|
||||
|
||||
## Process
|
||||
|
||||
1. Search the PHP codebase (D:\cortex\boha-app) for the relevant implementation
|
||||
2. Search the TS codebase (D:\cortex\boha-app-ts) for the same feature
|
||||
3. Compare:
|
||||
- API endpoints and request/response shape
|
||||
- Business logic and calculations
|
||||
- Database queries
|
||||
- Frontend behavior
|
||||
4. Report differences found — what's missing, what's different, what's extra
|
||||
|
||||
## Key directories
|
||||
|
||||
**PHP project:**
|
||||
- API handlers: `D:\cortex\boha-app\api\admin\handlers\`
|
||||
- API routes: `D:\cortex\boha-app\api\admin\`
|
||||
- Frontend pages: `D:\cortex\boha-app\src\admin\pages\`
|
||||
- Frontend components: `D:\cortex\boha-app\src\admin\components\`
|
||||
- Frontend hooks: `D:\cortex\boha-app\src\admin\hooks\`
|
||||
- Includes/utils: `D:\cortex\boha-app\api\includes\`
|
||||
|
||||
**TS project:**
|
||||
- API routes: `D:\cortex\boha-app-ts\src\routes\admin\`
|
||||
- Services: `D:\cortex\boha-app-ts\src\services\`
|
||||
- Frontend pages: `D:\cortex\boha-app-ts\src\admin\pages\`
|
||||
- Frontend components: `D:\cortex\boha-app-ts\src\admin\components\`
|
||||
- Frontend hooks: `D:\cortex\boha-app-ts\src\admin\hooks\`
|
||||
97
CLAUDE.md
97
CLAUDE.md
@@ -75,14 +75,20 @@ npm test # vitest run (single pass)
|
||||
npm run test:watch # vitest watch
|
||||
|
||||
# Database
|
||||
npx prisma migrate dev # Apply migrations (dev)
|
||||
npx prisma migrate deploy # Apply migrations (prod)
|
||||
npx prisma generate # Regenerate Prisma client after schema changes
|
||||
npx prisma studio # DB browser GUI
|
||||
npx prisma migrate dev # Create migration from schema changes + apply to dev
|
||||
npx prisma migrate dev --name <descriptive_name> # Named migration
|
||||
npx prisma migrate deploy # Apply pending migrations to production
|
||||
npx prisma generate # Regenerate Prisma client after schema changes
|
||||
npx prisma studio # DB browser GUI
|
||||
npx prisma db seed # (Re)seed the dev database
|
||||
npx prisma migrate diff --from-url <url> --to-schema-datamodel prisma/schema.prisma --script # Preview SQL before prod deploy
|
||||
npx prisma migrate resolve --applied <migration> # Mark migration as applied without running SQL
|
||||
```
|
||||
|
||||
**Do not start the dev server.** The user manages it separately.
|
||||
|
||||
**Before running `prisma migrate dev` or `prisma db push`, ask the user to stop their dev server and wait for confirmation.** Migrations can conflict with an active database connection from the running server.
|
||||
|
||||
---
|
||||
|
||||
## Environment Variables
|
||||
@@ -248,6 +254,24 @@ When adding new features, add tests in `src/__tests__/`. Name test files `<featu
|
||||
- Custom hooks: `useApiCall`, `useListData`, `useTableSort`, `useDebounce`, `useModalLock`.
|
||||
- Styling: CSS files in `src/admin/` — no CSS-in-JS, no Tailwind. Use CSS variables.
|
||||
|
||||
### Query Invalidation Convention
|
||||
|
||||
Mutations must invalidate the **full domain** of any entity they touch. Prefer broad invalidation:
|
||||
|
||||
- `["users"]` over `["users", "list"]`
|
||||
- `["trips"]` over `["trips", "vehicles"]`
|
||||
|
||||
Reason: React Query's `invalidateQueries` uses prefix matching, so `["trips"]` matches all
|
||||
`["trips", ...]` sub-queries. This means new queries are automatically invalidated without
|
||||
updating every mutation handler. Inactive queries are only marked stale, not refetched, so
|
||||
the performance cost is minimal. Optimize to targeted keys only when profiling shows a problem.
|
||||
|
||||
When entity A embeds/references entity B, A's mutation handlers invalidate B's domain:
|
||||
|
||||
- User CRUD invalidates `["trips"]` and `["attendance"]` (both embed user data)
|
||||
- Vehicle CRUD invalidates `["trips"]` (trips reference vehicles)
|
||||
- Invoice CRUD invalidates `["orders"]` (orders reference invoices)
|
||||
|
||||
---
|
||||
|
||||
## Database Conventions
|
||||
@@ -260,6 +284,69 @@ When adding new features, add tests in `src/__tests__/`. Name test files `<featu
|
||||
|
||||
---
|
||||
|
||||
## Database Migrations (Critical Workflow)
|
||||
|
||||
**Golden rule: NEVER use `prisma db push`.** It bypasses migration history and causes drift
|
||||
between the schema and migration tracking. Always use `prisma migrate dev` for every schema change.
|
||||
|
||||
### Making schema changes
|
||||
|
||||
```
|
||||
1. Edit prisma/schema.prisma
|
||||
2. npx prisma migrate dev --name descriptive_name
|
||||
→ This creates a migration in prisma/migrations/ AND applies it to dev DB
|
||||
3. npx prisma generate
|
||||
4. Commit BOTH schema.prisma AND the new migration folder
|
||||
git add prisma/schema.prisma prisma/migrations/
|
||||
```
|
||||
|
||||
### Verifying before production deploy
|
||||
|
||||
```bash
|
||||
# Preview what SQL will run on production (no changes applied)
|
||||
npx prisma migrate diff \
|
||||
--from-url "mysql://user:pass@prod:3306/app" \
|
||||
--to-schema-datamodel prisma/schema.prisma \
|
||||
--script
|
||||
|
||||
# Empty output = no diff. If it shows SQL, review it before deploying.
|
||||
```
|
||||
|
||||
### Deploying migrations to production
|
||||
|
||||
The release process runs `prisma migrate deploy` on production.
|
||||
This applies only pending migrations — safe, idempotent.
|
||||
|
||||
### If migrations get out of sync (drift)
|
||||
|
||||
```bash
|
||||
# Diff production DB against local schema to find drift
|
||||
npx prisma migrate diff \
|
||||
--from-url "mysql://prod" \
|
||||
--to-schema-datamodel prisma/schema.prisma \
|
||||
--script
|
||||
|
||||
# If drift is safe (CREATE only, no DROPs): apply with db push ONCE, then baseline
|
||||
# If drift includes DROPs: investigate before touching production
|
||||
```
|
||||
|
||||
### Baselinining a database that has no migrations
|
||||
|
||||
If production was synced with `db push` and has no `_prisma_migrations` table:
|
||||
|
||||
```bash
|
||||
# 1. Create initial migration locally
|
||||
npx prisma migrate dev --name init
|
||||
|
||||
# 2. Copy to production and mark as applied (no SQL runs)
|
||||
scp -r prisma/migrations user@prod:/var/www/app-ts/prisma/
|
||||
ssh user@prod
|
||||
cd /var/www/app-ts
|
||||
npx prisma migrate resolve --applied <migration_name>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Known Issues & Gotchas
|
||||
|
||||
1. **Date.prototype.toJSON override** — global monkey-patch in `src/config/env.ts`. Side-effects on third-party libraries that serialize dates. Do not remove without migrating all date serialization.
|
||||
@@ -276,7 +363,7 @@ When adding new features, add tests in `src/__tests__/`. Name test files `<featu
|
||||
|
||||
7. **NAS_PATH file access** — Project file uploads write to a network share path. In dev, this path may not be mounted. Features using `NAS_PATH` will fail gracefully (or not) if the path is unavailable.
|
||||
|
||||
8. **Prisma client regeneration** — After any schema change, run `npx prisma generate`. The generated client is not committed to git.
|
||||
8. **Prisma client regeneration** — After any schema change and migration, run `npx prisma generate`. The generated client is not committed to git.
|
||||
|
||||
9. **No CSRF tokens** — CSRF protection relies on `SameSite=Strict` cookies + CORS. Do not weaken CORS configuration.
|
||||
|
||||
|
||||
572
package-lock.json
generated
572
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "app-ts",
|
||||
"version": "1.6.3",
|
||||
"version": "1.8.0",
|
||||
"description": "",
|
||||
"main": "dist/server.js",
|
||||
"scripts": {
|
||||
@@ -18,7 +18,10 @@
|
||||
"db:studio": "prisma studio",
|
||||
"test": "vitest run",
|
||||
"test:watch": "vitest",
|
||||
"bones": "boneyard-js build http://localhost:3000"
|
||||
"seed": "tsx prisma/seed.ts"
|
||||
},
|
||||
"prisma": {
|
||||
"seed": "tsx prisma/seed.ts"
|
||||
},
|
||||
"keywords": [],
|
||||
"author": "",
|
||||
@@ -38,7 +41,6 @@
|
||||
"@tanstack/react-query": "^5.100.5",
|
||||
"@types/jsdom": "^28.0.1",
|
||||
"bcryptjs": "^3.0.3",
|
||||
"boneyard-js": "^1.8.1",
|
||||
"date-fns": "^4.1.0",
|
||||
"dompurify": "^3.3.3",
|
||||
"dotenv": "^17.3.1",
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
-- Add billing_text column to invoices table
|
||||
ALTER TABLE `invoices` ADD COLUMN `billing_text` VARCHAR(500) NULL AFTER `issued_by`;
|
||||
@@ -1,3 +0,0 @@
|
||||
-- Add lock fields to quotations table for pessimistic locking
|
||||
ALTER TABLE `quotations` ADD COLUMN `locked_by` INT NULL AFTER `scope_description`;
|
||||
ALTER TABLE `quotations` ADD COLUMN `locked_at` DATETIME NULL AFTER `locked_by`;
|
||||
@@ -1,9 +0,0 @@
|
||||
CREATE TABLE `invoice_alert_log` (
|
||||
`id` INT NOT NULL AUTO_INCREMENT,
|
||||
`invoice_type` VARCHAR(20) NOT NULL,
|
||||
`invoice_id` INT NOT NULL,
|
||||
`alert_type` VARCHAR(20) NOT NULL,
|
||||
`sent_at` DATETIME(0) NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `invoice_type_invoice_id_alert_type` (`invoice_type`, `invoice_id`, `alert_type`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
|
||||
@@ -1 +0,0 @@
|
||||
ALTER TABLE `invoices` ADD COLUMN `language` VARCHAR(5) DEFAULT 'cs' AFTER `billing_text`;
|
||||
@@ -1,2 +0,0 @@
|
||||
-- Add file_path column for NAS storage of received invoice files
|
||||
ALTER TABLE `received_invoices` ADD COLUMN `file_path` VARCHAR(500) NULL AFTER `file_data`;
|
||||
@@ -1,4 +0,0 @@
|
||||
-- Remove file_data (BLOB) and file_path columns — files are now stored on NAS
|
||||
-- Path is derived from year, month, and file_name
|
||||
ALTER TABLE `received_invoices` DROP COLUMN `file_data`;
|
||||
ALTER TABLE `received_invoices` DROP COLUMN `file_path`;
|
||||
@@ -1 +0,0 @@
|
||||
ALTER TABLE `company_settings` ADD COLUMN `logo_data_dark` MEDIUMBLOB NULL AFTER `logo_data`;
|
||||
@@ -1,4 +0,0 @@
|
||||
ALTER TABLE `company_settings`
|
||||
ADD COLUMN `offer_number_pattern` VARCHAR(100) NULL,
|
||||
ADD COLUMN `order_number_pattern` VARCHAR(100) NULL,
|
||||
ADD COLUMN `invoice_number_pattern` VARCHAR(100) NULL;
|
||||
@@ -1,3 +0,0 @@
|
||||
ALTER TABLE `company_settings`
|
||||
ADD COLUMN `smtp_from` VARCHAR(255) NULL,
|
||||
ADD COLUMN `smtp_from_name` VARCHAR(255) NULL;
|
||||
@@ -1,13 +0,0 @@
|
||||
-- System settings columns on company_settings
|
||||
ALTER TABLE `company_settings`
|
||||
ADD COLUMN `break_threshold_hours` DECIMAL(4,2) DEFAULT 6,
|
||||
ADD COLUMN `break_duration_short` INT DEFAULT 15,
|
||||
ADD COLUMN `break_duration_long` INT DEFAULT 30,
|
||||
ADD COLUMN `clock_rounding_minutes` INT DEFAULT 15,
|
||||
ADD COLUMN `invoice_alert_email` VARCHAR(255) NULL,
|
||||
ADD COLUMN `leave_notify_email` VARCHAR(255) NULL,
|
||||
ADD COLUMN `max_login_attempts` INT DEFAULT 5,
|
||||
ADD COLUMN `lockout_minutes` INT DEFAULT 15,
|
||||
ADD COLUMN `max_requests_per_minute` INT DEFAULT 300,
|
||||
ADD COLUMN `available_vat_rates` LONGTEXT NULL,
|
||||
ADD COLUMN `available_currencies` LONGTEXT NULL;
|
||||
@@ -1,18 +0,0 @@
|
||||
-- Create new unified permission
|
||||
INSERT INTO permissions (name, display_name, description, module)
|
||||
VALUES ('settings.manage', 'Správa nastavení', 'Správa všech nastavení systému', 'settings')
|
||||
ON DUPLICATE KEY UPDATE display_name = VALUES(display_name);
|
||||
|
||||
-- Grant to all roles that had any of the old 3
|
||||
INSERT IGNORE INTO role_permissions (role_id, permission_id)
|
||||
SELECT DISTINCT rp.role_id, (SELECT id FROM permissions WHERE name = 'settings.manage')
|
||||
FROM role_permissions rp
|
||||
JOIN permissions p ON p.id = rp.permission_id
|
||||
WHERE p.name IN ('offers.settings', 'settings.roles', 'settings.security');
|
||||
|
||||
-- Clean up old role_permissions
|
||||
DELETE FROM role_permissions
|
||||
WHERE permission_id IN (SELECT id FROM permissions WHERE name IN ('offers.settings', 'settings.roles', 'settings.security'));
|
||||
|
||||
-- Remove old permissions
|
||||
DELETE FROM permissions WHERE name IN ('offers.settings', 'settings.roles', 'settings.security');
|
||||
@@ -1,2 +0,0 @@
|
||||
-- Add unique constraint on number_sequences(type, year) for atomic numbering
|
||||
ALTER TABLE number_sequences ADD UNIQUE INDEX idx_number_sequences_type_year (`type`, `year`);
|
||||
@@ -1,2 +0,0 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `users` ADD COLUMN `totp_last_used_counter` INTEGER NULL;
|
||||
@@ -98,6 +98,7 @@ CREATE TABLE `company_settings` (
|
||||
`vat_id` VARCHAR(50) NULL,
|
||||
`custom_fields` LONGTEXT NULL,
|
||||
`logo_data` LONGBLOB NULL,
|
||||
`logo_data_dark` MEDIUMBLOB NULL,
|
||||
`quotation_prefix` VARCHAR(20) NULL,
|
||||
`default_currency` VARCHAR(10) NULL DEFAULT 'CZK',
|
||||
`default_vat_rate` DECIMAL(5, 2) NULL DEFAULT 21.00,
|
||||
@@ -108,7 +109,24 @@ CREATE TABLE `company_settings` (
|
||||
`order_type_code` VARCHAR(10) NULL,
|
||||
`invoice_type_code` VARCHAR(10) NULL,
|
||||
`require_2fa` BOOLEAN NOT NULL DEFAULT false,
|
||||
`break_threshold_hours` DECIMAL(4, 2) NULL DEFAULT 6.00,
|
||||
`break_duration_short` INTEGER NULL DEFAULT 15,
|
||||
`break_duration_long` INTEGER NULL DEFAULT 30,
|
||||
`clock_rounding_minutes` INTEGER NULL DEFAULT 15,
|
||||
`invoice_alert_email` VARCHAR(255) NULL,
|
||||
`leave_notify_email` VARCHAR(255) NULL,
|
||||
`max_login_attempts` INTEGER NULL DEFAULT 5,
|
||||
`lockout_minutes` INTEGER NULL DEFAULT 15,
|
||||
`max_requests_per_minute` INTEGER NULL DEFAULT 300,
|
||||
`available_vat_rates` LONGTEXT NULL,
|
||||
`available_currencies` LONGTEXT NULL,
|
||||
`smtp_from` VARCHAR(255) NULL,
|
||||
`smtp_from_name` VARCHAR(255) NULL,
|
||||
`offer_number_pattern` VARCHAR(100) NULL,
|
||||
`order_number_pattern` VARCHAR(100) NULL,
|
||||
`invoice_number_pattern` VARCHAR(100) NULL,
|
||||
|
||||
UNIQUE INDEX `company_settings_uuid_key`(`uuid`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
@@ -167,14 +185,18 @@ CREATE TABLE `invoices` (
|
||||
`tax_date` DATE NULL,
|
||||
`paid_date` DATE NULL,
|
||||
`issued_by` VARCHAR(255) NULL,
|
||||
`billing_text` VARCHAR(500) NULL,
|
||||
`language` VARCHAR(5) NULL DEFAULT 'cs',
|
||||
`notes` TEXT NULL,
|
||||
`internal_notes` TEXT NULL,
|
||||
`created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`modified_at` DATETIME(0) NULL,
|
||||
|
||||
UNIQUE INDEX `idx_invoices_number_unique`(`invoice_number`),
|
||||
INDEX `customer_id`(`customer_id`),
|
||||
INDEX `idx_invoices_due_date`(`due_date`),
|
||||
INDEX `idx_invoices_status_issue`(`status`, `issue_date`),
|
||||
INDEX `idx_invoices_status_due`(`status`, `due_date`),
|
||||
INDEX `order_id`(`order_id`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
@@ -239,6 +261,7 @@ CREATE TABLE `number_sequences` (
|
||||
`year` INTEGER NULL,
|
||||
`last_number` INTEGER NULL DEFAULT 0,
|
||||
|
||||
UNIQUE INDEX `idx_number_sequences_type_year`(`type`, `year`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
@@ -294,6 +317,7 @@ CREATE TABLE `orders` (
|
||||
`created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`modified_at` DATETIME(0) NULL,
|
||||
|
||||
UNIQUE INDEX `idx_orders_number_unique`(`order_number`),
|
||||
INDEX `customer_id`(`customer_id`),
|
||||
INDEX `quotation_id`(`quotation_id`),
|
||||
PRIMARY KEY (`id`)
|
||||
@@ -341,6 +365,7 @@ CREATE TABLE `projects` (
|
||||
`created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`modified_at` DATETIME(0) NULL,
|
||||
|
||||
UNIQUE INDEX `projects_project_number_key`(`project_number`),
|
||||
INDEX `customer_id`(`customer_id`),
|
||||
INDEX `fk_projects_responsible_user`(`responsible_user_id`),
|
||||
INDEX `order_id`(`order_id`),
|
||||
@@ -386,10 +411,13 @@ CREATE TABLE `quotations` (
|
||||
`status` VARCHAR(20) NOT NULL DEFAULT 'active',
|
||||
`scope_title` VARCHAR(500) NULL,
|
||||
`scope_description` TEXT NULL,
|
||||
`locked_by` INTEGER NULL,
|
||||
`locked_at` DATETIME(0) NULL,
|
||||
`uuid` VARCHAR(36) NULL,
|
||||
`modified_at` DATETIME(0) NULL,
|
||||
`sync_version` INTEGER NULL DEFAULT 0,
|
||||
|
||||
UNIQUE INDEX `quotations_quotation_number_key`(`quotation_number`),
|
||||
INDEX `customer_id`(`customer_id`),
|
||||
INDEX `idx_quotations_number`(`quotation_number`),
|
||||
PRIMARY KEY (`id`)
|
||||
@@ -411,7 +439,6 @@ CREATE TABLE `received_invoices` (
|
||||
`due_date` DATE NULL,
|
||||
`paid_date` DATE NULL,
|
||||
`status` ENUM('unpaid', 'paid') NOT NULL DEFAULT 'unpaid',
|
||||
`file_data` MEDIUMBLOB NULL,
|
||||
`file_name` VARCHAR(255) NULL,
|
||||
`file_mime` VARCHAR(100) NULL,
|
||||
`file_size` INTEGER UNSIGNED NULL,
|
||||
@@ -572,6 +599,7 @@ CREATE TABLE `users` (
|
||||
`totp_secret` VARCHAR(255) NULL,
|
||||
`totp_enabled` BOOLEAN NOT NULL DEFAULT false,
|
||||
`totp_backup_codes` TEXT NULL,
|
||||
`totp_last_used_counter` INTEGER NULL,
|
||||
|
||||
UNIQUE INDEX `username`(`username`),
|
||||
UNIQUE INDEX `email`(`email`),
|
||||
@@ -597,12 +625,28 @@ CREATE TABLE `vehicles` (
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `invoice_alert_log` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`invoice_type` VARCHAR(20) NOT NULL,
|
||||
`invoice_id` INTEGER NOT NULL,
|
||||
`alert_type` VARCHAR(20) NOT NULL,
|
||||
`sent_at` DATETIME(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`created_at` DATETIME(0) NOT NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
|
||||
UNIQUE INDEX `invoice_type_invoice_id_alert_type`(`invoice_type`, `invoice_id`, `alert_type`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `attendance` ADD CONSTRAINT `attendance_ibfk_1` FOREIGN KEY (`user_id`) REFERENCES `users`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `attendance_project_logs` ADD CONSTRAINT `attendance_project_logs_attendance_id_fkey` FOREIGN KEY (`attendance_id`) REFERENCES `attendance`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `attendance_project_logs` ADD CONSTRAINT `attendance_project_logs_project_id_fkey` FOREIGN KEY (`project_id`) REFERENCES `projects`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `invoice_items` ADD CONSTRAINT `invoice_items_ibfk_1` FOREIGN KEY (`invoice_id`) REFERENCES `invoices`(`id`) ON DELETE CASCADE ON UPDATE NO ACTION;
|
||||
|
||||
@@ -674,4 +718,3 @@ ALTER TABLE `trips` ADD CONSTRAINT `trips_vehicle_fk` FOREIGN KEY (`vehicle_id`)
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `users` ADD CONSTRAINT `users_ibfk_1` FOREIGN KEY (`role_id`) REFERENCES `roles`(`id`) ON DELETE SET NULL ON UPDATE NO ACTION;
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
-- Insert the settings.system permission (also available via seed)
|
||||
INSERT INTO `permissions` (`name`, `display_name`, `module`, `description`)
|
||||
VALUES ('settings.system', 'Systémová nastavení', 'settings', 'Spravovat systémová nastavení, 2FA, e-maily, limity')
|
||||
ON DUPLICATE KEY UPDATE `name` = `name`;
|
||||
@@ -0,0 +1,3 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `quotations` DROP COLUMN `exchange_rate`;
|
||||
ALTER TABLE `quotations` DROP COLUMN `exchange_rate_date`;
|
||||
@@ -0,0 +1,2 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `invoice_items` ADD COLUMN `item_description` TEXT NULL;
|
||||
@@ -0,0 +1,14 @@
|
||||
-- AlterTable: quotation_items
|
||||
ALTER TABLE `quotation_items` DROP COLUMN `uuid`;
|
||||
ALTER TABLE `quotation_items` DROP COLUMN `is_deleted`;
|
||||
ALTER TABLE `quotation_items` DROP COLUMN `sync_version`;
|
||||
|
||||
-- AlterTable: quotations
|
||||
ALTER TABLE `quotations` DROP COLUMN `uuid`;
|
||||
ALTER TABLE `quotations` DROP COLUMN `sync_version`;
|
||||
|
||||
-- AlterTable: scope_sections
|
||||
ALTER TABLE `scope_sections` DROP COLUMN `content_editor_height`;
|
||||
ALTER TABLE `scope_sections` DROP COLUMN `uuid`;
|
||||
ALTER TABLE `scope_sections` DROP COLUMN `is_deleted`;
|
||||
ALTER TABLE `scope_sections` DROP COLUMN `sync_version`;
|
||||
@@ -0,0 +1,277 @@
|
||||
-- CreateTable
|
||||
CREATE TABLE `sklad_categories` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`sort_order` INTEGER NOT NULL DEFAULT 0,
|
||||
`created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`modified_at` DATETIME(0) NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `sklad_suppliers` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`ico` VARCHAR(20) NULL,
|
||||
`dic` VARCHAR(20) NULL,
|
||||
`contact_person` VARCHAR(255) NULL,
|
||||
`email` VARCHAR(255) NULL,
|
||||
`phone` VARCHAR(50) NULL,
|
||||
`address` TEXT NULL,
|
||||
`notes` TEXT NULL,
|
||||
`is_active` BOOLEAN NOT NULL DEFAULT true,
|
||||
`created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`modified_at` DATETIME(0) NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `sklad_locations` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`code` VARCHAR(20) NOT NULL,
|
||||
`name` VARCHAR(100) NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`is_active` BOOLEAN NOT NULL DEFAULT true,
|
||||
`created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`modified_at` DATETIME(0) NULL,
|
||||
|
||||
UNIQUE INDEX `sklad_locations_code_key`(`code`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `sklad_items` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`item_number` VARCHAR(50) NULL,
|
||||
`name` VARCHAR(255) NOT NULL,
|
||||
`description` TEXT NULL,
|
||||
`category_id` INTEGER NULL,
|
||||
`unit` VARCHAR(20) NOT NULL,
|
||||
`min_quantity` DECIMAL(12, 3) NULL,
|
||||
`is_active` BOOLEAN NOT NULL DEFAULT true,
|
||||
`notes` TEXT NULL,
|
||||
`created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`modified_at` DATETIME(0) NULL,
|
||||
|
||||
UNIQUE INDEX `sklad_items_item_number_key`(`item_number`),
|
||||
INDEX `sklad_items_category_id`(`category_id`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `sklad_batches` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`item_id` INTEGER NOT NULL,
|
||||
`receipt_line_id` INTEGER NOT NULL,
|
||||
`quantity` DECIMAL(12, 3) NOT NULL,
|
||||
`original_qty` DECIMAL(12, 3) NOT NULL,
|
||||
`unit_price` DECIMAL(12, 2) NOT NULL,
|
||||
`received_at` DATETIME(0) NULL,
|
||||
`is_consumed` BOOLEAN NOT NULL DEFAULT false,
|
||||
|
||||
UNIQUE INDEX `sklad_batches_receipt_line_id_key`(`receipt_line_id`),
|
||||
INDEX `sklad_batches_fifo`(`item_id`, `is_consumed`, `received_at`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `sklad_item_locations` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`item_id` INTEGER NOT NULL,
|
||||
`location_id` INTEGER NOT NULL,
|
||||
`quantity` DECIMAL(12, 3) NOT NULL DEFAULT 0,
|
||||
|
||||
UNIQUE INDEX `sklad_item_locations_unique`(`item_id`, `location_id`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `sklad_receipts` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`receipt_number` VARCHAR(50) NULL,
|
||||
`supplier_id` INTEGER NULL,
|
||||
`delivery_note_number` VARCHAR(100) NULL,
|
||||
`delivery_note_date` DATETIME(0) NULL,
|
||||
`received_by` INTEGER NULL,
|
||||
`notes` TEXT NULL,
|
||||
`status` ENUM('DRAFT', 'CONFIRMED', 'CANCELLED') NOT NULL DEFAULT 'DRAFT',
|
||||
`created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`modified_at` DATETIME(0) NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `sklad_receipt_lines` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`receipt_id` INTEGER NOT NULL,
|
||||
`item_id` INTEGER NOT NULL,
|
||||
`quantity` DECIMAL(12, 3) NOT NULL,
|
||||
`unit_price` DECIMAL(12, 2) NOT NULL,
|
||||
`location_id` INTEGER NULL,
|
||||
`notes` VARCHAR(255) NULL,
|
||||
|
||||
INDEX `sklad_receipt_lines_receipt_id`(`receipt_id`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `sklad_receipt_attachments` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`receipt_id` INTEGER NOT NULL,
|
||||
`file_name` VARCHAR(255) NOT NULL,
|
||||
`file_mime` VARCHAR(100) NOT NULL,
|
||||
`file_size` INTEGER NOT NULL,
|
||||
`file_path` VARCHAR(500) NOT NULL,
|
||||
`created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `sklad_issues` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`issue_number` VARCHAR(50) NULL,
|
||||
`project_id` INTEGER NOT NULL,
|
||||
`issued_by` INTEGER NULL,
|
||||
`notes` TEXT NULL,
|
||||
`status` ENUM('DRAFT', 'CONFIRMED', 'CANCELLED') NOT NULL DEFAULT 'DRAFT',
|
||||
`created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`modified_at` DATETIME(0) NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `sklad_issue_lines` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`issue_id` INTEGER NOT NULL,
|
||||
`item_id` INTEGER NOT NULL,
|
||||
`batch_id` INTEGER NOT NULL,
|
||||
`quantity` DECIMAL(12, 3) NOT NULL,
|
||||
`location_id` INTEGER NULL,
|
||||
`reservation_id` INTEGER NULL,
|
||||
`notes` VARCHAR(255) NULL,
|
||||
|
||||
INDEX `sklad_issue_lines_issue_id`(`issue_id`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `sklad_reservations` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`item_id` INTEGER NOT NULL,
|
||||
`project_id` INTEGER NOT NULL,
|
||||
`quantity` DECIMAL(12, 3) NOT NULL,
|
||||
`remaining_qty` DECIMAL(12, 3) NOT NULL,
|
||||
`reserved_by` INTEGER NULL,
|
||||
`notes` TEXT NULL,
|
||||
`status` ENUM('ACTIVE', 'FULFILLED', 'CANCELLED') NOT NULL DEFAULT 'ACTIVE',
|
||||
`created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`modified_at` DATETIME(0) NULL,
|
||||
|
||||
INDEX `sklad_reservations_item_status`(`item_id`, `status`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `sklad_inventory_sessions` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`session_number` VARCHAR(50) NULL,
|
||||
`notes` TEXT NULL,
|
||||
`status` ENUM('DRAFT', 'CONFIRMED') NOT NULL DEFAULT 'DRAFT',
|
||||
`created_at` DATETIME(0) NULL DEFAULT CURRENT_TIMESTAMP(0),
|
||||
`modified_at` DATETIME(0) NULL,
|
||||
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- CreateTable
|
||||
CREATE TABLE `sklad_inventory_lines` (
|
||||
`id` INTEGER NOT NULL AUTO_INCREMENT,
|
||||
`session_id` INTEGER NOT NULL,
|
||||
`item_id` INTEGER NOT NULL,
|
||||
`location_id` INTEGER NULL,
|
||||
`system_qty` DECIMAL(12, 3) NOT NULL,
|
||||
`actual_qty` DECIMAL(12, 3) NOT NULL,
|
||||
`difference` DECIMAL(12, 3) NOT NULL,
|
||||
`notes` VARCHAR(255) NULL,
|
||||
|
||||
INDEX `sklad_inventory_lines_session_id`(`session_id`),
|
||||
PRIMARY KEY (`id`)
|
||||
) DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_items` ADD CONSTRAINT `sklad_items_category_id_fkey` FOREIGN KEY (`category_id`) REFERENCES `sklad_categories`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_batches` ADD CONSTRAINT `sklad_batches_item_id_fkey` FOREIGN KEY (`item_id`) REFERENCES `sklad_items`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_batches` ADD CONSTRAINT `sklad_batches_receipt_line_id_fkey` FOREIGN KEY (`receipt_line_id`) REFERENCES `sklad_receipt_lines`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_item_locations` ADD CONSTRAINT `sklad_item_locations_item_id_fkey` FOREIGN KEY (`item_id`) REFERENCES `sklad_items`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_item_locations` ADD CONSTRAINT `sklad_item_locations_location_id_fkey` FOREIGN KEY (`location_id`) REFERENCES `sklad_locations`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_receipts` ADD CONSTRAINT `sklad_receipts_supplier_id_fkey` FOREIGN KEY (`supplier_id`) REFERENCES `sklad_suppliers`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_receipts` ADD CONSTRAINT `sklad_receipts_received_by_fkey` FOREIGN KEY (`received_by`) REFERENCES `users`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_receipt_lines` ADD CONSTRAINT `sklad_receipt_lines_receipt_id_fkey` FOREIGN KEY (`receipt_id`) REFERENCES `sklad_receipts`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_receipt_lines` ADD CONSTRAINT `sklad_receipt_lines_item_id_fkey` FOREIGN KEY (`item_id`) REFERENCES `sklad_items`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_receipt_lines` ADD CONSTRAINT `sklad_receipt_lines_location_id_fkey` FOREIGN KEY (`location_id`) REFERENCES `sklad_locations`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_receipt_attachments` ADD CONSTRAINT `sklad_receipt_attachments_receipt_id_fkey` FOREIGN KEY (`receipt_id`) REFERENCES `sklad_receipts`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_issues` ADD CONSTRAINT `sklad_issues_project_id_fkey` FOREIGN KEY (`project_id`) REFERENCES `projects`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_issues` ADD CONSTRAINT `sklad_issues_issued_by_fkey` FOREIGN KEY (`issued_by`) REFERENCES `users`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_issue_lines` ADD CONSTRAINT `sklad_issue_lines_issue_id_fkey` FOREIGN KEY (`issue_id`) REFERENCES `sklad_issues`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_issue_lines` ADD CONSTRAINT `sklad_issue_lines_item_id_fkey` FOREIGN KEY (`item_id`) REFERENCES `sklad_items`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_issue_lines` ADD CONSTRAINT `sklad_issue_lines_batch_id_fkey` FOREIGN KEY (`batch_id`) REFERENCES `sklad_batches`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_issue_lines` ADD CONSTRAINT `sklad_issue_lines_location_id_fkey` FOREIGN KEY (`location_id`) REFERENCES `sklad_locations`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_issue_lines` ADD CONSTRAINT `sklad_issue_lines_reservation_id_fkey` FOREIGN KEY (`reservation_id`) REFERENCES `sklad_reservations`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_reservations` ADD CONSTRAINT `sklad_reservations_item_id_fkey` FOREIGN KEY (`item_id`) REFERENCES `sklad_items`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_reservations` ADD CONSTRAINT `sklad_reservations_project_id_fkey` FOREIGN KEY (`project_id`) REFERENCES `projects`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_reservations` ADD CONSTRAINT `sklad_reservations_reserved_by_fkey` FOREIGN KEY (`reserved_by`) REFERENCES `users`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_inventory_lines` ADD CONSTRAINT `sklad_inventory_lines_session_id_fkey` FOREIGN KEY (`session_id`) REFERENCES `sklad_inventory_sessions`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_inventory_lines` ADD CONSTRAINT `sklad_inventory_lines_item_id_fkey` FOREIGN KEY (`item_id`) REFERENCES `sklad_items`(`id`) ON DELETE RESTRICT ON UPDATE CASCADE;
|
||||
|
||||
-- AddForeignKey
|
||||
ALTER TABLE `sklad_inventory_lines` ADD CONSTRAINT `sklad_inventory_lines_location_id_fkey` FOREIGN KEY (`location_id`) REFERENCES `sklad_locations`(`id`) ON DELETE SET NULL ON UPDATE CASCADE;
|
||||
@@ -0,0 +1,17 @@
|
||||
-- AlterTable
|
||||
ALTER TABLE `company_settings` ADD COLUMN `warehouse_inventory_number_pattern` VARCHAR(100) NULL,
|
||||
ADD COLUMN `warehouse_inventory_prefix` VARCHAR(20) NULL,
|
||||
ADD COLUMN `warehouse_issue_number_pattern` VARCHAR(100) NULL,
|
||||
ADD COLUMN `warehouse_issue_prefix` VARCHAR(20) NULL,
|
||||
ADD COLUMN `warehouse_receipt_number_pattern` VARCHAR(100) NULL,
|
||||
ADD COLUMN `warehouse_receipt_prefix` VARCHAR(20) NULL;
|
||||
|
||||
-- Set backward-compatible defaults for existing installations
|
||||
UPDATE `company_settings`
|
||||
SET
|
||||
`warehouse_receipt_prefix` = 'PRI',
|
||||
`warehouse_receipt_number_pattern` = '{PREFIX}-{YYYY}-{NNN}',
|
||||
`warehouse_issue_prefix` = 'VYD',
|
||||
`warehouse_issue_number_pattern` = '{PREFIX}-{YYYY}-{NNN}',
|
||||
`warehouse_inventory_prefix` = 'INV',
|
||||
`warehouse_inventory_number_pattern` = '{PREFIX}-{YYYY}-{NNN}';
|
||||
@@ -1,3 +1,3 @@
|
||||
# Please do not edit this file manually
|
||||
# It should be added in your version-control system (i.e. Git)
|
||||
# It should be added in your version-control system (e.g., Git)
|
||||
provider = "mysql"
|
||||
|
||||
@@ -32,7 +32,7 @@ model attendance {
|
||||
users users @relation(fields: [user_id], references: [id], onDelete: Cascade, onUpdate: NoAction, map: "attendance_ibfk_1")
|
||||
attendance_project_logs attendance_project_logs[]
|
||||
|
||||
@@unique([user_id, shift_date], map: "idx_attendance_user_date")
|
||||
@@index([user_id, shift_date], map: "idx_attendance_user_date")
|
||||
@@index([user_id, departure_time], map: "idx_attendance_user_departure")
|
||||
@@index([project_id], map: "idx_project_id")
|
||||
}
|
||||
@@ -101,7 +101,7 @@ model company_settings {
|
||||
vat_id String? @db.VarChar(50)
|
||||
custom_fields String? @db.LongText
|
||||
logo_data Bytes?
|
||||
logo_data_dark Bytes?
|
||||
logo_data_dark Bytes? @db.MediumBlob
|
||||
quotation_prefix String? @db.VarChar(20)
|
||||
default_currency String? @default("CZK") @db.VarChar(10)
|
||||
default_vat_rate Decimal? @default(21.00) @db.Decimal(5, 2)
|
||||
@@ -112,7 +112,7 @@ model company_settings {
|
||||
order_type_code String? @db.VarChar(10)
|
||||
invoice_type_code String? @db.VarChar(10)
|
||||
require_2fa Boolean @default(false)
|
||||
break_threshold_hours Decimal? @default(6) @db.Decimal(4, 2)
|
||||
break_threshold_hours Decimal? @default(6.00) @db.Decimal(4, 2)
|
||||
break_duration_short Int? @default(15)
|
||||
break_duration_long Int? @default(30)
|
||||
clock_rounding_minutes Int? @default(15)
|
||||
@@ -128,6 +128,12 @@ model company_settings {
|
||||
offer_number_pattern String? @db.VarChar(100)
|
||||
order_number_pattern String? @db.VarChar(100)
|
||||
invoice_number_pattern String? @db.VarChar(100)
|
||||
warehouse_receipt_prefix String? @db.VarChar(20)
|
||||
warehouse_receipt_number_pattern String? @db.VarChar(100)
|
||||
warehouse_issue_prefix String? @db.VarChar(20)
|
||||
warehouse_issue_number_pattern String? @db.VarChar(100)
|
||||
warehouse_inventory_prefix String? @db.VarChar(20)
|
||||
warehouse_inventory_number_pattern String? @db.VarChar(100)
|
||||
}
|
||||
|
||||
model customers {
|
||||
@@ -153,8 +159,9 @@ model customers {
|
||||
model invoice_items {
|
||||
id Int @id @default(autoincrement())
|
||||
invoice_id Int
|
||||
description String? @db.VarChar(500)
|
||||
quantity Decimal? @default(1.000) @db.Decimal(12, 3)
|
||||
description String? @db.VarChar(500)
|
||||
item_description String? @db.Text
|
||||
quantity Decimal? @default(1.000) @db.Decimal(12, 3)
|
||||
unit String? @db.VarChar(20)
|
||||
unit_price Decimal? @default(0.00) @db.Decimal(12, 2)
|
||||
vat_rate Decimal? @default(21.00) @db.Decimal(5, 2)
|
||||
@@ -356,6 +363,8 @@ model projects {
|
||||
modified_at DateTime? @db.DateTime(0)
|
||||
attendance_project_logs attendance_project_logs[]
|
||||
project_notes project_notes[]
|
||||
sklad_issues sklad_issues[]
|
||||
sklad_reservations sklad_reservations[]
|
||||
users users? @relation(fields: [responsible_user_id], references: [id], onUpdate: NoAction, map: "fk_projects_responsible_user")
|
||||
customers customers? @relation(fields: [customer_id], references: [id], onUpdate: NoAction, map: "projects_ibfk_1")
|
||||
quotations quotations? @relation(fields: [quotation_id], references: [id], onUpdate: NoAction, map: "projects_ibfk_2")
|
||||
@@ -377,10 +386,7 @@ model quotation_items {
|
||||
unit String? @db.VarChar(20)
|
||||
unit_price Decimal? @default(0.00) @db.Decimal(12, 2)
|
||||
is_included_in_total Boolean? @default(true)
|
||||
uuid String? @db.VarChar(36)
|
||||
modified_at DateTime? @db.DateTime(0)
|
||||
is_deleted Boolean? @default(false)
|
||||
sync_version Int? @default(0)
|
||||
quotations quotations @relation(fields: [quotation_id], references: [id], onDelete: Cascade, onUpdate: NoAction, map: "quotation_items_ibfk_1")
|
||||
|
||||
@@index([quotation_id], map: "quotation_id")
|
||||
@@ -389,7 +395,7 @@ model quotation_items {
|
||||
model quotations {
|
||||
id Int @id @default(autoincrement())
|
||||
quotation_number String? @unique @db.VarChar(50)
|
||||
project_code String? @db.VarChar(50)
|
||||
project_code String? @db.VarChar(100)
|
||||
customer_id Int?
|
||||
created_at DateTime? @default(now()) @db.DateTime(0)
|
||||
valid_until DateTime? @db.Date
|
||||
@@ -397,17 +403,13 @@ model quotations {
|
||||
language String? @default("cs") @db.VarChar(5)
|
||||
vat_rate Decimal? @default(21.00) @db.Decimal(5, 2)
|
||||
apply_vat Boolean? @default(true)
|
||||
exchange_rate Decimal? @default(1.0000) @db.Decimal(10, 4)
|
||||
exchange_rate_date DateTime? @db.Date
|
||||
order_id Int?
|
||||
status String @default("active") @db.VarChar(20)
|
||||
scope_title String? @db.VarChar(500)
|
||||
scope_description String? @db.Text
|
||||
locked_by Int?
|
||||
locked_at DateTime? @db.DateTime(0)
|
||||
uuid String? @db.VarChar(36)
|
||||
modified_at DateTime? @db.DateTime(0)
|
||||
sync_version Int? @default(0)
|
||||
orders orders[]
|
||||
projects projects[]
|
||||
quotation_items quotation_items[]
|
||||
@@ -437,7 +439,7 @@ model received_invoices {
|
||||
file_mime String? @db.VarChar(100)
|
||||
file_size Int? @db.UnsignedInt
|
||||
notes String? @db.Text
|
||||
uploaded_by Int?
|
||||
uploaded_by Int? @db.UnsignedInt
|
||||
created_at DateTime @default(now()) @db.DateTime(0)
|
||||
modified_at DateTime @default(now()) @db.DateTime(0)
|
||||
|
||||
@@ -449,7 +451,7 @@ model received_invoices {
|
||||
/// This model or at least one of its fields has comments in the database, and requires an additional setup for migrations: Read more: https://pris.ly/d/database-comments
|
||||
model refresh_tokens {
|
||||
id Int @id @default(autoincrement()) @db.UnsignedInt
|
||||
user_id Int
|
||||
user_id Int @db.UnsignedInt
|
||||
token_hash String @unique(map: "token_hash") @db.VarChar(64)
|
||||
expires_at DateTime @db.DateTime(0)
|
||||
replaced_at DateTime? @db.DateTime(0)
|
||||
@@ -492,11 +494,7 @@ model scope_sections {
|
||||
title String? @db.VarChar(500)
|
||||
title_cz String? @db.VarChar(500)
|
||||
content String? @db.Text
|
||||
content_editor_height Int?
|
||||
uuid String? @db.VarChar(36)
|
||||
modified_at DateTime? @db.DateTime(0)
|
||||
is_deleted Boolean? @default(false)
|
||||
sync_version Int? @default(0)
|
||||
quotations quotations @relation(fields: [quotation_id], references: [id], onDelete: Cascade, onUpdate: NoAction, map: "scope_sections_ibfk_1")
|
||||
|
||||
@@index([quotation_id], map: "quotation_id")
|
||||
@@ -590,6 +588,9 @@ model users {
|
||||
leave_requests_leave_requests_reviewer_idTousers leave_requests[] @relation("leave_requests_reviewer_idTousers")
|
||||
projects projects[]
|
||||
trips trips[]
|
||||
sklad_receipts_received sklad_receipts[] @relation("SkladReceivedBy")
|
||||
sklad_issues_issued sklad_issues[] @relation("SkladIssuedBy")
|
||||
sklad_reservations sklad_reservations[] @relation("SkladReservedBy")
|
||||
roles roles? @relation(fields: [role_id], references: [id], onUpdate: NoAction, map: "users_ibfk_1")
|
||||
|
||||
@@index([is_active], map: "idx_users_is_active")
|
||||
@@ -632,7 +633,7 @@ model invoice_alert_log {
|
||||
sent_at DateTime @default(now()) @db.DateTime(0)
|
||||
created_at DateTime @default(now()) @db.DateTime(0)
|
||||
|
||||
@@unique([invoice_type, invoice_id, alert_type])
|
||||
@@unique([invoice_type, invoice_id, alert_type], map: "invoice_type_invoice_id_alert_type")
|
||||
}
|
||||
|
||||
enum received_invoices_status {
|
||||
@@ -647,3 +648,272 @@ enum attendance_leave_type {
|
||||
holiday
|
||||
unpaid
|
||||
}
|
||||
|
||||
enum sklad_receipt_status {
|
||||
DRAFT
|
||||
CONFIRMED
|
||||
CANCELLED
|
||||
}
|
||||
|
||||
enum sklad_issue_status {
|
||||
DRAFT
|
||||
CONFIRMED
|
||||
CANCELLED
|
||||
}
|
||||
|
||||
enum sklad_reservation_status {
|
||||
ACTIVE
|
||||
FULFILLED
|
||||
CANCELLED
|
||||
}
|
||||
|
||||
enum sklad_inventory_status {
|
||||
DRAFT
|
||||
CONFIRMED
|
||||
}
|
||||
|
||||
model sklad_categories {
|
||||
id Int @id @default(autoincrement())
|
||||
name String @db.VarChar(100)
|
||||
description String? @db.Text
|
||||
sort_order Int @default(0)
|
||||
created_at DateTime? @default(now()) @db.DateTime(0)
|
||||
modified_at DateTime? @db.DateTime(0)
|
||||
|
||||
items sklad_items[]
|
||||
|
||||
@@map("sklad_categories")
|
||||
}
|
||||
|
||||
model sklad_suppliers {
|
||||
id Int @id @default(autoincrement())
|
||||
name String @db.VarChar(255)
|
||||
ico String? @db.VarChar(20)
|
||||
dic String? @db.VarChar(20)
|
||||
contact_person String? @db.VarChar(255)
|
||||
email String? @db.VarChar(255)
|
||||
phone String? @db.VarChar(50)
|
||||
address String? @db.Text
|
||||
notes String? @db.Text
|
||||
is_active Boolean @default(true)
|
||||
created_at DateTime? @default(now()) @db.DateTime(0)
|
||||
modified_at DateTime? @db.DateTime(0)
|
||||
|
||||
receipts sklad_receipts[]
|
||||
|
||||
@@map("sklad_suppliers")
|
||||
}
|
||||
|
||||
model sklad_locations {
|
||||
id Int @id @default(autoincrement())
|
||||
code String @unique @db.VarChar(20)
|
||||
name String @db.VarChar(100)
|
||||
description String? @db.Text
|
||||
is_active Boolean @default(true)
|
||||
created_at DateTime? @default(now()) @db.DateTime(0)
|
||||
modified_at DateTime? @db.DateTime(0)
|
||||
|
||||
items sklad_item_locations[]
|
||||
receipt_lines sklad_receipt_lines[]
|
||||
issue_lines sklad_issue_lines[]
|
||||
inventory_lines sklad_inventory_lines[]
|
||||
|
||||
@@map("sklad_locations")
|
||||
}
|
||||
|
||||
model sklad_items {
|
||||
id Int @id @default(autoincrement())
|
||||
item_number String? @unique @db.VarChar(50)
|
||||
name String @db.VarChar(255)
|
||||
description String? @db.Text
|
||||
category_id Int?
|
||||
unit String @db.VarChar(20)
|
||||
min_quantity Decimal? @db.Decimal(12, 3)
|
||||
is_active Boolean @default(true)
|
||||
notes String? @db.Text
|
||||
created_at DateTime? @default(now()) @db.DateTime(0)
|
||||
modified_at DateTime? @db.DateTime(0)
|
||||
|
||||
category sklad_categories? @relation(fields: [category_id], references: [id])
|
||||
batches sklad_batches[]
|
||||
item_locations sklad_item_locations[]
|
||||
receipt_lines sklad_receipt_lines[]
|
||||
issue_lines sklad_issue_lines[]
|
||||
reservations sklad_reservations[]
|
||||
inventory_lines sklad_inventory_lines[]
|
||||
|
||||
@@index([category_id], map: "sklad_items_category_id")
|
||||
@@map("sklad_items")
|
||||
}
|
||||
|
||||
model sklad_batches {
|
||||
id Int @id @default(autoincrement())
|
||||
item_id Int
|
||||
receipt_line_id Int @unique
|
||||
quantity Decimal @db.Decimal(12, 3)
|
||||
original_qty Decimal @db.Decimal(12, 3)
|
||||
unit_price Decimal @db.Decimal(12, 2)
|
||||
received_at DateTime? @db.DateTime(0)
|
||||
is_consumed Boolean @default(false)
|
||||
|
||||
item sklad_items @relation(fields: [item_id], references: [id])
|
||||
receipt_line sklad_receipt_lines @relation(fields: [receipt_line_id], references: [id])
|
||||
issue_lines sklad_issue_lines[]
|
||||
|
||||
@@index([item_id, is_consumed, received_at], map: "sklad_batches_fifo")
|
||||
@@map("sklad_batches")
|
||||
}
|
||||
|
||||
model sklad_item_locations {
|
||||
id Int @id @default(autoincrement())
|
||||
item_id Int
|
||||
location_id Int
|
||||
quantity Decimal @default(0) @db.Decimal(12, 3)
|
||||
|
||||
item sklad_items @relation(fields: [item_id], references: [id])
|
||||
location sklad_locations @relation(fields: [location_id], references: [id])
|
||||
|
||||
@@unique([item_id, location_id], map: "sklad_item_locations_unique")
|
||||
@@map("sklad_item_locations")
|
||||
}
|
||||
|
||||
model sklad_receipts {
|
||||
id Int @id @default(autoincrement())
|
||||
receipt_number String? @db.VarChar(50)
|
||||
supplier_id Int?
|
||||
delivery_note_number String? @db.VarChar(100)
|
||||
delivery_note_date DateTime? @db.DateTime(0)
|
||||
received_by Int?
|
||||
notes String? @db.Text
|
||||
status sklad_receipt_status @default(DRAFT)
|
||||
created_at DateTime? @default(now()) @db.DateTime(0)
|
||||
modified_at DateTime? @db.DateTime(0)
|
||||
|
||||
supplier sklad_suppliers? @relation(fields: [supplier_id], references: [id])
|
||||
received_by_user users? @relation("SkladReceivedBy", fields: [received_by], references: [id])
|
||||
items sklad_receipt_lines[]
|
||||
attachments sklad_receipt_attachments[]
|
||||
|
||||
@@map("sklad_receipts")
|
||||
}
|
||||
|
||||
model sklad_receipt_lines {
|
||||
id Int @id @default(autoincrement())
|
||||
receipt_id Int
|
||||
item_id Int
|
||||
quantity Decimal @db.Decimal(12, 3)
|
||||
unit_price Decimal @db.Decimal(12, 2)
|
||||
location_id Int?
|
||||
notes String? @db.VarChar(255)
|
||||
|
||||
receipt sklad_receipts @relation(fields: [receipt_id], references: [id])
|
||||
item sklad_items @relation(fields: [item_id], references: [id])
|
||||
location sklad_locations? @relation(fields: [location_id], references: [id])
|
||||
batch sklad_batches?
|
||||
|
||||
@@index([receipt_id], map: "sklad_receipt_lines_receipt_id")
|
||||
@@map("sklad_receipt_lines")
|
||||
}
|
||||
|
||||
model sklad_receipt_attachments {
|
||||
id Int @id @default(autoincrement())
|
||||
receipt_id Int
|
||||
file_name String @db.VarChar(255)
|
||||
file_mime String @db.VarChar(100)
|
||||
file_size Int
|
||||
file_path String @db.VarChar(500)
|
||||
created_at DateTime? @default(now()) @db.DateTime(0)
|
||||
|
||||
receipt sklad_receipts @relation(fields: [receipt_id], references: [id])
|
||||
|
||||
@@map("sklad_receipt_attachments")
|
||||
}
|
||||
|
||||
model sklad_issues {
|
||||
id Int @id @default(autoincrement())
|
||||
issue_number String? @db.VarChar(50)
|
||||
project_id Int
|
||||
issued_by Int?
|
||||
notes String? @db.Text
|
||||
status sklad_issue_status @default(DRAFT)
|
||||
created_at DateTime? @default(now()) @db.DateTime(0)
|
||||
modified_at DateTime? @db.DateTime(0)
|
||||
|
||||
project projects @relation(fields: [project_id], references: [id])
|
||||
issued_by_user users? @relation("SkladIssuedBy", fields: [issued_by], references: [id])
|
||||
items sklad_issue_lines[]
|
||||
|
||||
@@map("sklad_issues")
|
||||
}
|
||||
|
||||
model sklad_issue_lines {
|
||||
id Int @id @default(autoincrement())
|
||||
issue_id Int
|
||||
item_id Int
|
||||
batch_id Int
|
||||
quantity Decimal @db.Decimal(12, 3)
|
||||
location_id Int?
|
||||
reservation_id Int?
|
||||
notes String? @db.VarChar(255)
|
||||
|
||||
issue sklad_issues @relation(fields: [issue_id], references: [id])
|
||||
item sklad_items @relation(fields: [item_id], references: [id])
|
||||
batch sklad_batches @relation(fields: [batch_id], references: [id])
|
||||
location sklad_locations? @relation(fields: [location_id], references: [id])
|
||||
reservation sklad_reservations? @relation(fields: [reservation_id], references: [id])
|
||||
|
||||
@@index([issue_id], map: "sklad_issue_lines_issue_id")
|
||||
@@map("sklad_issue_lines")
|
||||
}
|
||||
|
||||
model sklad_reservations {
|
||||
id Int @id @default(autoincrement())
|
||||
item_id Int
|
||||
project_id Int
|
||||
quantity Decimal @db.Decimal(12, 3)
|
||||
remaining_qty Decimal @db.Decimal(12, 3)
|
||||
reserved_by Int?
|
||||
notes String? @db.Text
|
||||
status sklad_reservation_status @default(ACTIVE)
|
||||
created_at DateTime? @default(now()) @db.DateTime(0)
|
||||
modified_at DateTime? @db.DateTime(0)
|
||||
|
||||
item sklad_items @relation(fields: [item_id], references: [id])
|
||||
project projects @relation(fields: [project_id], references: [id])
|
||||
reserved_by_user users? @relation("SkladReservedBy", fields: [reserved_by], references: [id])
|
||||
issue_lines sklad_issue_lines[]
|
||||
|
||||
@@index([item_id, status], map: "sklad_reservations_item_status")
|
||||
@@map("sklad_reservations")
|
||||
}
|
||||
|
||||
model sklad_inventory_sessions {
|
||||
id Int @id @default(autoincrement())
|
||||
session_number String? @db.VarChar(50)
|
||||
notes String? @db.Text
|
||||
status sklad_inventory_status @default(DRAFT)
|
||||
created_at DateTime? @default(now()) @db.DateTime(0)
|
||||
modified_at DateTime? @db.DateTime(0)
|
||||
|
||||
items sklad_inventory_lines[]
|
||||
|
||||
@@map("sklad_inventory_sessions")
|
||||
}
|
||||
|
||||
model sklad_inventory_lines {
|
||||
id Int @id @default(autoincrement())
|
||||
session_id Int
|
||||
item_id Int
|
||||
location_id Int?
|
||||
system_qty Decimal @db.Decimal(12, 3)
|
||||
actual_qty Decimal @db.Decimal(12, 3)
|
||||
difference Decimal @db.Decimal(12, 3)
|
||||
notes String? @db.VarChar(255)
|
||||
|
||||
session sklad_inventory_sessions @relation(fields: [session_id], references: [id])
|
||||
item sklad_items @relation(fields: [item_id], references: [id])
|
||||
location sklad_locations? @relation(fields: [location_id], references: [id])
|
||||
|
||||
@@index([session_id], map: "sklad_inventory_lines_session_id")
|
||||
@@map("sklad_inventory_lines")
|
||||
}
|
||||
|
||||
469
prisma/seed.ts
Normal file
469
prisma/seed.ts
Normal file
@@ -0,0 +1,469 @@
|
||||
import { PrismaClient } from "@prisma/client";
|
||||
import bcrypt from "bcryptjs";
|
||||
|
||||
const prisma = new PrismaClient();
|
||||
|
||||
const PERMISSIONS: {
|
||||
name: string;
|
||||
display_name: string;
|
||||
module: string;
|
||||
description: string;
|
||||
}[] = [
|
||||
// Docházka
|
||||
{
|
||||
name: "attendance.record",
|
||||
display_name: "Záznam docházky",
|
||||
module: "attendance",
|
||||
description: "Zapisovat příchody/odchody",
|
||||
},
|
||||
{
|
||||
name: "attendance.history",
|
||||
display_name: "Historie docházky",
|
||||
module: "attendance",
|
||||
description: "Prohlížet vlastní historii docházky",
|
||||
},
|
||||
{
|
||||
name: "attendance.approve",
|
||||
display_name: "Schvalování docházky",
|
||||
module: "attendance",
|
||||
description: "Schvalovat žádosti o dovolenou/nemoc",
|
||||
},
|
||||
{
|
||||
name: "attendance.manage",
|
||||
display_name: "Správa docházky",
|
||||
module: "attendance",
|
||||
description: "Spravovat všechny záznamy, vytvářet/editovat/mazat",
|
||||
},
|
||||
{
|
||||
name: "attendance.balances",
|
||||
display_name: "Správa bilancí",
|
||||
module: "attendance",
|
||||
description: "Spravovat zůstatky dovolené a sick days",
|
||||
},
|
||||
|
||||
// Kniha jízd
|
||||
{
|
||||
name: "trips.record",
|
||||
display_name: "Záznam jízd",
|
||||
module: "trips",
|
||||
description: "Zapisovat jízdy",
|
||||
},
|
||||
{
|
||||
name: "trips.history",
|
||||
display_name: "Historie jízd",
|
||||
module: "trips",
|
||||
description: "Prohlížet vlastní historii jízd",
|
||||
},
|
||||
{
|
||||
name: "trips.manage",
|
||||
display_name: "Správa jízd",
|
||||
module: "trips",
|
||||
description: "Spravovat všechny jízdy",
|
||||
},
|
||||
|
||||
// Vozidla
|
||||
{
|
||||
name: "vehicles.manage",
|
||||
display_name: "Správa vozidel",
|
||||
module: "vehicles",
|
||||
description: "Spravovat vozový park",
|
||||
},
|
||||
|
||||
// Nabídky
|
||||
{
|
||||
name: "offers.view",
|
||||
display_name: "Zobrazit nabídky",
|
||||
module: "offers",
|
||||
description: "Prohlížet seznam nabídek",
|
||||
},
|
||||
{
|
||||
name: "offers.create",
|
||||
display_name: "Vytvořit nabídku",
|
||||
module: "offers",
|
||||
description: "Vytvářet nové nabídky",
|
||||
},
|
||||
{
|
||||
name: "offers.edit",
|
||||
display_name: "Upravit nabídku",
|
||||
module: "offers",
|
||||
description: "Upravovat existující nabídky",
|
||||
},
|
||||
{
|
||||
name: "offers.delete",
|
||||
display_name: "Smazat nabídku",
|
||||
module: "offers",
|
||||
description: "Mazat nabídky",
|
||||
},
|
||||
{
|
||||
name: "offers.export",
|
||||
display_name: "Exportovat nabídku",
|
||||
module: "offers",
|
||||
description: "Exportovat nabídky do PDF",
|
||||
},
|
||||
|
||||
// Objednávky
|
||||
{
|
||||
name: "orders.view",
|
||||
display_name: "Zobrazit objednávky",
|
||||
module: "orders",
|
||||
description: "Prohlížet seznam objednávek",
|
||||
},
|
||||
{
|
||||
name: "orders.create",
|
||||
display_name: "Vytvořit objednávku",
|
||||
module: "orders",
|
||||
description: "Vytvářet nové objednávky",
|
||||
},
|
||||
{
|
||||
name: "orders.edit",
|
||||
display_name: "Upravit objednávku",
|
||||
module: "orders",
|
||||
description: "Upravovat existující objednávky",
|
||||
},
|
||||
{
|
||||
name: "orders.delete",
|
||||
display_name: "Smazat objednávku",
|
||||
module: "orders",
|
||||
description: "Mazat objednávky",
|
||||
},
|
||||
{
|
||||
name: "orders.export",
|
||||
display_name: "Exportovat objednávku",
|
||||
module: "orders",
|
||||
description: "Exportovat objednávky do PDF",
|
||||
},
|
||||
|
||||
// Faktury
|
||||
{
|
||||
name: "invoices.view",
|
||||
display_name: "Zobrazit faktury",
|
||||
module: "invoices",
|
||||
description: "Prohlížet seznam faktur",
|
||||
},
|
||||
{
|
||||
name: "invoices.create",
|
||||
display_name: "Vytvořit fakturu",
|
||||
module: "invoices",
|
||||
description: "Vytvářet nové faktury",
|
||||
},
|
||||
{
|
||||
name: "invoices.edit",
|
||||
display_name: "Upravit fakturu",
|
||||
module: "invoices",
|
||||
description: "Upravovat existující faktury",
|
||||
},
|
||||
{
|
||||
name: "invoices.delete",
|
||||
display_name: "Smazat fakturu",
|
||||
module: "invoices",
|
||||
description: "Mazat faktury",
|
||||
},
|
||||
{
|
||||
name: "invoices.export",
|
||||
display_name: "Exportovat fakturu",
|
||||
module: "invoices",
|
||||
description: "Exportovat faktury do PDF",
|
||||
},
|
||||
|
||||
// Projekty
|
||||
{
|
||||
name: "projects.view",
|
||||
display_name: "Zobrazit projekty",
|
||||
module: "projects",
|
||||
description: "Prohlížet seznam projektů",
|
||||
},
|
||||
{
|
||||
name: "projects.edit",
|
||||
display_name: "Upravit projekt",
|
||||
module: "projects",
|
||||
description: "Upravovat existující projekty",
|
||||
},
|
||||
{
|
||||
name: "projects.delete",
|
||||
display_name: "Smazat projekt",
|
||||
module: "projects",
|
||||
description: "Mazat projekty",
|
||||
},
|
||||
{
|
||||
name: "projects.files",
|
||||
display_name: "Soubory projektu",
|
||||
module: "projects",
|
||||
description: "Spravovat soubory a složky projektu",
|
||||
},
|
||||
|
||||
// Zákazníci
|
||||
{
|
||||
name: "customers.view",
|
||||
display_name: "Zobrazit zákazníky",
|
||||
module: "customers",
|
||||
description: "Prohlížet seznam zákazníků",
|
||||
},
|
||||
{
|
||||
name: "customers.create",
|
||||
display_name: "Vytvořit zákazníka",
|
||||
module: "customers",
|
||||
description: "Vytvářet nové zákazníky",
|
||||
},
|
||||
{
|
||||
name: "customers.edit",
|
||||
display_name: "Upravit zákazníka",
|
||||
module: "customers",
|
||||
description: "Upravovat existující zákazníky",
|
||||
},
|
||||
{
|
||||
name: "customers.delete",
|
||||
display_name: "Smazat zákazníka",
|
||||
module: "customers",
|
||||
description: "Mazat zákazníky",
|
||||
},
|
||||
|
||||
// Uživatelé
|
||||
{
|
||||
name: "users.view",
|
||||
display_name: "Zobrazit uživatele",
|
||||
module: "users",
|
||||
description: "Prohlížet seznam uživatelů",
|
||||
},
|
||||
{
|
||||
name: "users.create",
|
||||
display_name: "Vytvořit uživatele",
|
||||
module: "users",
|
||||
description: "Vytvářet nové uživatele",
|
||||
},
|
||||
{
|
||||
name: "users.edit",
|
||||
display_name: "Upravit uživatele",
|
||||
module: "users",
|
||||
description: "Upravovat existující uživatele",
|
||||
},
|
||||
{
|
||||
name: "users.delete",
|
||||
display_name: "Smazat uživatele",
|
||||
module: "users",
|
||||
description: "Mazat uživatele",
|
||||
},
|
||||
|
||||
// Nastavení
|
||||
{
|
||||
name: "settings.company",
|
||||
display_name: "Nastavení společnosti",
|
||||
module: "settings",
|
||||
description: "Upravovat údaje o společnosti, logo",
|
||||
},
|
||||
{
|
||||
name: "settings.system",
|
||||
display_name: "Systémová nastavení",
|
||||
module: "settings",
|
||||
description: "Spravovat systémová nastavení, 2FA, e-maily, limity",
|
||||
},
|
||||
{
|
||||
name: "settings.banking",
|
||||
display_name: "Bankovní účty",
|
||||
module: "settings",
|
||||
description: "Spravovat bankovní účty společnosti",
|
||||
},
|
||||
{
|
||||
name: "settings.roles",
|
||||
display_name: "Role a oprávnění",
|
||||
module: "settings",
|
||||
description: "Spravovat role a přiřazovat oprávnění",
|
||||
},
|
||||
{
|
||||
name: "settings.templates",
|
||||
display_name: "Šablony",
|
||||
module: "settings",
|
||||
description: "Spravovat šablony nabídek a položek",
|
||||
},
|
||||
{
|
||||
name: "settings.audit",
|
||||
display_name: "Audit log",
|
||||
module: "settings",
|
||||
description: "Prohlížet auditní logy",
|
||||
},
|
||||
|
||||
// Sklad
|
||||
{
|
||||
name: "warehouse.view",
|
||||
display_name: "Zobrazit sklad",
|
||||
module: "warehouse",
|
||||
description: "Prohlížet stav skladu, položky, reporty a historii pohybů",
|
||||
},
|
||||
{
|
||||
name: "warehouse.operate",
|
||||
display_name: "Příjem a výdej",
|
||||
module: "warehouse",
|
||||
description: "Vytvářet a potvrzovat příjmy, výdeje a rezervace",
|
||||
},
|
||||
{
|
||||
name: "warehouse.manage",
|
||||
display_name: "Správa skladu",
|
||||
module: "warehouse",
|
||||
description: "Spravovat katalog materiálů, dodavatele, lokace a kategorie",
|
||||
},
|
||||
{
|
||||
name: "warehouse.inventory",
|
||||
display_name: "Inventura",
|
||||
module: "warehouse",
|
||||
description: "Vytvářet a potvrzovat inventurní sčítkání",
|
||||
},
|
||||
];
|
||||
|
||||
async function main() {
|
||||
console.log("Seeding permissions...");
|
||||
|
||||
// 1. Clear existing permissions and re-insert current set
|
||||
await prisma.role_permissions.deleteMany({});
|
||||
await prisma.permissions.deleteMany({});
|
||||
console.log(" Cleared old permissions");
|
||||
|
||||
for (const perm of PERMISSIONS) {
|
||||
await prisma.permissions.create({ data: perm });
|
||||
}
|
||||
console.log(` Inserted ${PERMISSIONS.length} permissions`);
|
||||
|
||||
// 2. Ensure admin role exists
|
||||
let adminRole = await prisma.roles.findFirst({ where: { name: "admin" } });
|
||||
if (!adminRole) {
|
||||
adminRole = await prisma.roles.create({
|
||||
data: {
|
||||
name: "admin",
|
||||
display_name: "Administrátor",
|
||||
description: "Hlavní administrátor s plným přístupem",
|
||||
},
|
||||
});
|
||||
console.log(" Created admin role");
|
||||
} else {
|
||||
console.log(" Admin role already exists (id=" + adminRole.id + ")");
|
||||
}
|
||||
|
||||
// 3. Assign all permissions to admin role
|
||||
const allPerms = await prisma.permissions.findMany();
|
||||
const existingAssignments = await prisma.role_permissions.findMany({
|
||||
where: { role_id: adminRole.id },
|
||||
});
|
||||
|
||||
// Delete stale assignments (permissions no longer in the list)
|
||||
const validIds = new Set(allPerms.map((p) => p.id));
|
||||
const staleIds = existingAssignments.filter(
|
||||
(a) => !validIds.has(a.permission_id),
|
||||
);
|
||||
if (staleIds.length > 0) {
|
||||
for (const s of staleIds) {
|
||||
await prisma.role_permissions.delete({
|
||||
where: {
|
||||
role_id_permission_id: {
|
||||
role_id: adminRole.id,
|
||||
permission_id: s.permission_id,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
console.log(` Removed ${staleIds.length} stale role_permissions`);
|
||||
}
|
||||
|
||||
// Add missing assignments
|
||||
const existingIds = new Set(existingAssignments.map((a) => a.permission_id));
|
||||
let added = 0;
|
||||
for (const perm of allPerms) {
|
||||
if (!existingIds.has(perm.id)) {
|
||||
await prisma.role_permissions.create({
|
||||
data: { role_id: adminRole.id, permission_id: perm.id },
|
||||
});
|
||||
added++;
|
||||
}
|
||||
}
|
||||
if (added > 0) console.log(` Added ${added} role_permission assignments`);
|
||||
console.log(` Admin role now has all ${allPerms.length} permissions`);
|
||||
|
||||
// 4. Ensure admin user exists
|
||||
let adminUser = await prisma.users.findFirst({
|
||||
where: { username: "admin" },
|
||||
});
|
||||
if (!adminUser) {
|
||||
const hash = bcrypt.hashSync("admin", 10);
|
||||
adminUser = await prisma.users.create({
|
||||
data: {
|
||||
username: "admin",
|
||||
email: "admin@boha.local",
|
||||
password_hash: hash,
|
||||
first_name: "Admin",
|
||||
last_name: "BOHA",
|
||||
role_id: adminRole.id,
|
||||
is_active: true,
|
||||
},
|
||||
});
|
||||
console.log(" Created admin user (admin / admin)");
|
||||
} else if (adminUser.role_id !== adminRole.id) {
|
||||
await prisma.users.update({
|
||||
where: { id: adminUser.id },
|
||||
data: { role_id: adminRole.id },
|
||||
});
|
||||
console.log(" Updated admin user role_id to admin role");
|
||||
} else {
|
||||
console.log(" Admin user already exists with correct role");
|
||||
}
|
||||
|
||||
// 5. Create default company_settings if not exists
|
||||
const existingSettings = await prisma.company_settings.findFirst();
|
||||
if (!existingSettings) {
|
||||
await prisma.company_settings.create({
|
||||
data: {
|
||||
company_name: "BOHA s.r.o.",
|
||||
default_currency: "CZK",
|
||||
default_vat_rate: 21.0,
|
||||
available_vat_rates: JSON.stringify([0, 10, 15, 21]),
|
||||
available_currencies: JSON.stringify(["CZK", "EUR"]),
|
||||
offer_number_pattern: "NAB-{YYYY}-{NNN}",
|
||||
order_number_pattern: "OBJ-{YYYY}-{NNN}",
|
||||
invoice_number_pattern: "FV-{YYYY}-{NNN}",
|
||||
break_threshold_hours: 6.0,
|
||||
break_duration_short: 15,
|
||||
break_duration_long: 30,
|
||||
clock_rounding_minutes: 15,
|
||||
require_2fa: false,
|
||||
max_login_attempts: 5,
|
||||
lockout_minutes: 15,
|
||||
max_requests_per_minute: 300,
|
||||
},
|
||||
});
|
||||
console.log(" Created default company_settings");
|
||||
} else {
|
||||
console.log(" company_settings already exists");
|
||||
}
|
||||
|
||||
// 6. Initialize number_sequences for current year
|
||||
const year = new Date().getFullYear();
|
||||
const types = [
|
||||
"quotation",
|
||||
"order",
|
||||
"invoice",
|
||||
"warehouse_receipt",
|
||||
"warehouse_issue",
|
||||
"warehouse_inventory",
|
||||
];
|
||||
for (const type of types) {
|
||||
const existing = await prisma.number_sequences.findFirst({
|
||||
where: { type, year },
|
||||
});
|
||||
if (!existing) {
|
||||
await prisma.number_sequences.create({
|
||||
data: { type, year, last_number: 0 },
|
||||
});
|
||||
console.log(` Created number_sequence: ${type}/${year}`);
|
||||
}
|
||||
}
|
||||
console.log(" number_sequences ready");
|
||||
|
||||
console.log(
|
||||
"\nSeed complete — " +
|
||||
PERMISSIONS.length +
|
||||
" permissions, 1 admin role, company_settings + number_sequences ready.",
|
||||
);
|
||||
}
|
||||
|
||||
main()
|
||||
.catch((e) => {
|
||||
console.error("Seed failed:", e);
|
||||
process.exit(1);
|
||||
})
|
||||
.finally(() => prisma.$disconnect());
|
||||
1244
src/__tests__/warehouse.test.ts
Normal file
1244
src/__tests__/warehouse.test.ts
Normal file
File diff suppressed because it is too large
Load Diff
@@ -17,7 +17,6 @@ import "./layout.css";
|
||||
import "./components.css";
|
||||
import "./tables.css";
|
||||
import "./datepicker.css";
|
||||
import "./bones/registry";
|
||||
import "./filemanager.css";
|
||||
import "./pagination.css";
|
||||
import "./responsive.css";
|
||||
@@ -27,6 +26,7 @@ import "./attendance.css";
|
||||
import "./settings.css";
|
||||
import "./offers.css";
|
||||
import "./invoices.css";
|
||||
import "./warehouse.css";
|
||||
|
||||
const Users = lazy(() => import("./pages/Users"));
|
||||
const Attendance = lazy(() => import("./pages/Attendance"));
|
||||
@@ -54,6 +54,31 @@ const InvoiceDetail = lazy(() => import("./pages/InvoiceDetail"));
|
||||
const Settings = lazy(() => import("./pages/Settings"));
|
||||
const AuditLog = lazy(() => import("./pages/AuditLog"));
|
||||
const NotFound = lazy(() => import("./pages/NotFound"));
|
||||
const Warehouse = lazy(() => import("./pages/Warehouse"));
|
||||
const WarehouseItems = lazy(() => import("./pages/WarehouseItems"));
|
||||
const WarehouseItemDetail = lazy(() => import("./pages/WarehouseItemDetail"));
|
||||
const WarehouseReceipts = lazy(() => import("./pages/WarehouseReceipts"));
|
||||
const WarehouseReceiptDetail = lazy(
|
||||
() => import("./pages/WarehouseReceiptDetail"),
|
||||
);
|
||||
const WarehouseReceiptForm = lazy(() => import("./pages/WarehouseReceiptForm"));
|
||||
const WarehouseIssues = lazy(() => import("./pages/WarehouseIssues"));
|
||||
const WarehouseIssueDetail = lazy(() => import("./pages/WarehouseIssueDetail"));
|
||||
const WarehouseIssueForm = lazy(() => import("./pages/WarehouseIssueForm"));
|
||||
const WarehouseReservations = lazy(
|
||||
() => import("./pages/WarehouseReservations"),
|
||||
);
|
||||
const WarehouseInventory = lazy(() => import("./pages/WarehouseInventory"));
|
||||
const WarehouseInventoryDetail = lazy(
|
||||
() => import("./pages/WarehouseInventoryDetail"),
|
||||
);
|
||||
const WarehouseInventoryForm = lazy(
|
||||
() => import("./pages/WarehouseInventoryForm"),
|
||||
);
|
||||
const WarehouseReports = lazy(() => import("./pages/WarehouseReports"));
|
||||
const WarehouseSuppliers = lazy(() => import("./pages/WarehouseSuppliers"));
|
||||
const WarehouseLocations = lazy(() => import("./pages/WarehouseLocations"));
|
||||
const WarehouseCategories = lazy(() => import("./pages/WarehouseCategories"));
|
||||
|
||||
export default function AdminApp() {
|
||||
return (
|
||||
@@ -127,6 +152,76 @@ export default function AdminApp() {
|
||||
<Route path="invoices/:id" element={<InvoiceDetail />} />
|
||||
<Route path="settings" element={<Settings />} />
|
||||
<Route path="audit-log" element={<AuditLog />} />
|
||||
<Route path="warehouse" element={<Warehouse />} />
|
||||
<Route path="warehouse/items" element={<WarehouseItems />} />
|
||||
<Route
|
||||
path="warehouse/items/:id"
|
||||
element={<WarehouseItemDetail />}
|
||||
/>
|
||||
<Route
|
||||
path="warehouse/receipts"
|
||||
element={<WarehouseReceipts />}
|
||||
/>
|
||||
<Route
|
||||
path="warehouse/receipts/new"
|
||||
element={<WarehouseReceiptForm />}
|
||||
/>
|
||||
<Route
|
||||
path="warehouse/receipts/:id"
|
||||
element={<WarehouseReceiptDetail />}
|
||||
/>
|
||||
<Route
|
||||
path="warehouse/receipts/:id/edit"
|
||||
element={<WarehouseReceiptForm />}
|
||||
/>
|
||||
<Route
|
||||
path="warehouse/issues"
|
||||
element={<WarehouseIssues />}
|
||||
/>
|
||||
<Route
|
||||
path="warehouse/issues/new"
|
||||
element={<WarehouseIssueForm />}
|
||||
/>
|
||||
<Route
|
||||
path="warehouse/issues/:id"
|
||||
element={<WarehouseIssueDetail />}
|
||||
/>
|
||||
<Route
|
||||
path="warehouse/issues/:id/edit"
|
||||
element={<WarehouseIssueForm />}
|
||||
/>
|
||||
<Route
|
||||
path="warehouse/reservations"
|
||||
element={<WarehouseReservations />}
|
||||
/>
|
||||
<Route
|
||||
path="warehouse/inventory"
|
||||
element={<WarehouseInventory />}
|
||||
/>
|
||||
<Route
|
||||
path="warehouse/inventory/new"
|
||||
element={<WarehouseInventoryForm />}
|
||||
/>
|
||||
<Route
|
||||
path="warehouse/inventory/:id"
|
||||
element={<WarehouseInventoryDetail />}
|
||||
/>
|
||||
<Route
|
||||
path="warehouse/reports"
|
||||
element={<WarehouseReports />}
|
||||
/>
|
||||
<Route
|
||||
path="warehouse/suppliers"
|
||||
element={<WarehouseSuppliers />}
|
||||
/>
|
||||
<Route
|
||||
path="warehouse/locations"
|
||||
element={<WarehouseLocations />}
|
||||
/>
|
||||
<Route
|
||||
path="warehouse/categories"
|
||||
element={<WarehouseCategories />}
|
||||
/>
|
||||
</Route>
|
||||
<Route path="*" element={<NotFound />} />
|
||||
</Routes>
|
||||
|
||||
@@ -318,12 +318,14 @@
|
||||
|
||||
/* Leave Type Badges */
|
||||
.attendance-leave-badge {
|
||||
display: inline-block;
|
||||
padding: 0.25rem 0.5rem;
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
padding: 0.25rem 0.55rem;
|
||||
border-radius: var(--border-radius-sm);
|
||||
font-size: 0.75rem;
|
||||
font-weight: 500;
|
||||
margin-right: 0.25rem;
|
||||
line-height: 1.2;
|
||||
background: var(--bg-tertiary);
|
||||
color: var(--text-secondary);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,263 +0,0 @@
|
||||
{
|
||||
"breakpoints": {
|
||||
"375": {
|
||||
"name": "attendance-create",
|
||||
"viewportWidth": 351,
|
||||
"width": 351,
|
||||
"height": 403,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
22,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
42,
|
||||
100,
|
||||
361,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
55,
|
||||
92.5926,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
83,
|
||||
92.5926,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
127,
|
||||
92.5926,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
156,
|
||||
92.5926,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
200,
|
||||
92.5926,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
229,
|
||||
92.5926,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
273,
|
||||
92.5926,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
302,
|
||||
92.5926,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
346,
|
||||
19.2352,
|
||||
44,
|
||||
8
|
||||
]
|
||||
]
|
||||
},
|
||||
"768": {
|
||||
"name": "attendance-create",
|
||||
"viewportWidth": 736,
|
||||
"width": 736,
|
||||
"height": 420,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
23.3738,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
46,
|
||||
81.5217,
|
||||
373,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
65,
|
||||
76.3587,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
94,
|
||||
76.3587,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
138,
|
||||
76.3587,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
167,
|
||||
76.3587,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
211,
|
||||
76.3587,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
240,
|
||||
76.3587,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
284,
|
||||
76.3587,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
313,
|
||||
76.3587,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
357,
|
||||
9.1733,
|
||||
44,
|
||||
8
|
||||
]
|
||||
]
|
||||
},
|
||||
"1280": {
|
||||
"name": "attendance-create",
|
||||
"viewportWidth": 996,
|
||||
"width": 996,
|
||||
"height": 369,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
17.2722,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
46,
|
||||
60.241,
|
||||
323,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
65,
|
||||
56.4257,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
93,
|
||||
56.4257,
|
||||
36,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
129,
|
||||
56.4257,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
156,
|
||||
56.4257,
|
||||
36,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
192,
|
||||
56.4257,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
219,
|
||||
56.4257,
|
||||
36,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
255,
|
||||
56.4257,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
282,
|
||||
56.4257,
|
||||
36,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
318,
|
||||
6.3771,
|
||||
32,
|
||||
8
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"_hash": "7c4e446bf97f164a0fba87e2dd7df7d1"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,506 +0,0 @@
|
||||
{
|
||||
"breakpoints": {
|
||||
"375": {
|
||||
"name": "dash-sessions",
|
||||
"viewportWidth": 341,
|
||||
"width": 341,
|
||||
"height": 304,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
304,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
3.8123,
|
||||
17,
|
||||
34.9386,
|
||||
17,
|
||||
8
|
||||
],
|
||||
[
|
||||
59.3383,
|
||||
13,
|
||||
36.8493,
|
||||
37,
|
||||
8
|
||||
],
|
||||
[
|
||||
0.2933,
|
||||
63,
|
||||
99.4135,
|
||||
83,
|
||||
8,
|
||||
true
|
||||
],
|
||||
[
|
||||
4.9853,
|
||||
86,
|
||||
10.5572,
|
||||
36,
|
||||
8,
|
||||
true
|
||||
],
|
||||
[
|
||||
7.6246,
|
||||
95,
|
||||
5.2786,
|
||||
18,
|
||||
"50%"
|
||||
],
|
||||
[
|
||||
63.0407,
|
||||
79,
|
||||
19.5152,
|
||||
27,
|
||||
9999
|
||||
],
|
||||
[
|
||||
19.0616,
|
||||
110,
|
||||
21.6734,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
43.081,
|
||||
110,
|
||||
1.0585,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
46.4855,
|
||||
110,
|
||||
26.8649,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
4.9853,
|
||||
167,
|
||||
10.5572,
|
||||
36,
|
||||
8,
|
||||
true
|
||||
],
|
||||
[
|
||||
7.6246,
|
||||
176,
|
||||
5.2786,
|
||||
18,
|
||||
"50%"
|
||||
],
|
||||
[
|
||||
19.0616,
|
||||
162,
|
||||
75.9531,
|
||||
22,
|
||||
8
|
||||
],
|
||||
[
|
||||
19.0616,
|
||||
189,
|
||||
21.6734,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
43.081,
|
||||
189,
|
||||
1.0585,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
46.4855,
|
||||
189,
|
||||
26.8649,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
4.9853,
|
||||
246,
|
||||
10.5572,
|
||||
36,
|
||||
8,
|
||||
true
|
||||
],
|
||||
[
|
||||
7.6246,
|
||||
255,
|
||||
5.2786,
|
||||
18,
|
||||
"50%"
|
||||
],
|
||||
[
|
||||
19.0616,
|
||||
241,
|
||||
75.9531,
|
||||
22,
|
||||
8
|
||||
],
|
||||
[
|
||||
19.0616,
|
||||
267,
|
||||
21.6734,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
43.081,
|
||||
267,
|
||||
1.0585,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
46.4855,
|
||||
267,
|
||||
26.8649,
|
||||
19,
|
||||
8
|
||||
]
|
||||
]
|
||||
},
|
||||
"768": {
|
||||
"name": "dash-sessions",
|
||||
"viewportWidth": 726,
|
||||
"width": 726,
|
||||
"height": 319,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
319,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
2.6171,
|
||||
19,
|
||||
16.4106,
|
||||
17,
|
||||
8
|
||||
],
|
||||
[
|
||||
80.0749,
|
||||
15,
|
||||
17.308,
|
||||
37,
|
||||
8
|
||||
],
|
||||
[
|
||||
0.1377,
|
||||
67,
|
||||
99.7245,
|
||||
85,
|
||||
8,
|
||||
true
|
||||
],
|
||||
[
|
||||
3.4435,
|
||||
89,
|
||||
5.5096,
|
||||
40,
|
||||
8,
|
||||
true
|
||||
],
|
||||
[
|
||||
4.9587,
|
||||
100,
|
||||
2.4793,
|
||||
18,
|
||||
"50%"
|
||||
],
|
||||
[
|
||||
34.5278,
|
||||
83,
|
||||
9.1662,
|
||||
27,
|
||||
9999
|
||||
],
|
||||
[
|
||||
11.157,
|
||||
114,
|
||||
11.0279,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
23.2868,
|
||||
114,
|
||||
0.5381,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
24.9268,
|
||||
114,
|
||||
13.6686,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.4435,
|
||||
173,
|
||||
5.5096,
|
||||
40,
|
||||
8,
|
||||
true
|
||||
],
|
||||
[
|
||||
4.9587,
|
||||
184,
|
||||
2.4793,
|
||||
18,
|
||||
"50%"
|
||||
],
|
||||
[
|
||||
11.157,
|
||||
168,
|
||||
85.3994,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
11.157,
|
||||
198,
|
||||
11.0279,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
23.2868,
|
||||
198,
|
||||
0.5381,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
24.9268,
|
||||
198,
|
||||
13.6686,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.4435,
|
||||
257,
|
||||
5.5096,
|
||||
40,
|
||||
8,
|
||||
true
|
||||
],
|
||||
[
|
||||
4.9587,
|
||||
268,
|
||||
2.4793,
|
||||
18,
|
||||
"50%"
|
||||
],
|
||||
[
|
||||
11.157,
|
||||
251,
|
||||
85.3994,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
11.157,
|
||||
281,
|
||||
11.0279,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
23.2868,
|
||||
281,
|
||||
0.5381,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
24.9268,
|
||||
281,
|
||||
13.6686,
|
||||
21,
|
||||
8
|
||||
]
|
||||
]
|
||||
},
|
||||
"1280": {
|
||||
"name": "dash-sessions",
|
||||
"viewportWidth": 484,
|
||||
"width": 484,
|
||||
"height": 309,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
309,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
3.9256,
|
||||
15,
|
||||
24.6158,
|
||||
17,
|
||||
8
|
||||
],
|
||||
[
|
||||
72.1785,
|
||||
15,
|
||||
23.8959,
|
||||
29,
|
||||
8
|
||||
],
|
||||
[
|
||||
0.2066,
|
||||
59,
|
||||
99.5868,
|
||||
83,
|
||||
8,
|
||||
true
|
||||
],
|
||||
[
|
||||
5.1653,
|
||||
80,
|
||||
8.2645,
|
||||
40,
|
||||
8,
|
||||
true
|
||||
],
|
||||
[
|
||||
7.438,
|
||||
91,
|
||||
3.719,
|
||||
18,
|
||||
"50%"
|
||||
],
|
||||
[
|
||||
51.7917,
|
||||
76,
|
||||
12.9358,
|
||||
24,
|
||||
9999
|
||||
],
|
||||
[
|
||||
16.7355,
|
||||
105,
|
||||
16.5418,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
34.9303,
|
||||
105,
|
||||
0.8071,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
37.3902,
|
||||
105,
|
||||
20.503,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
5.1653,
|
||||
164,
|
||||
8.2645,
|
||||
40,
|
||||
8,
|
||||
true
|
||||
],
|
||||
[
|
||||
7.438,
|
||||
175,
|
||||
3.719,
|
||||
18,
|
||||
"50%"
|
||||
],
|
||||
[
|
||||
16.7355,
|
||||
158,
|
||||
78.0992,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
16.7355,
|
||||
188,
|
||||
16.5418,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
34.9303,
|
||||
188,
|
||||
0.8071,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
37.3902,
|
||||
188,
|
||||
20.503,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
5.1653,
|
||||
247,
|
||||
8.2645,
|
||||
40,
|
||||
8,
|
||||
true
|
||||
],
|
||||
[
|
||||
7.438,
|
||||
258,
|
||||
3.719,
|
||||
18,
|
||||
"50%"
|
||||
],
|
||||
[
|
||||
16.7355,
|
||||
242,
|
||||
78.0992,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
16.7355,
|
||||
271,
|
||||
16.5418,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
34.9303,
|
||||
271,
|
||||
0.8071,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
37.3902,
|
||||
271,
|
||||
20.503,
|
||||
21,
|
||||
8
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"_hash": "e057ca7b36a30c5971a4225ec3ad4680"
|
||||
}
|
||||
@@ -1,707 +0,0 @@
|
||||
{
|
||||
"breakpoints": {
|
||||
"375": {
|
||||
"name": "invoice-detail",
|
||||
"viewportWidth": 351,
|
||||
"width": 351,
|
||||
"height": 466,
|
||||
"bones": [
|
||||
[
|
||||
3.4188,
|
||||
12,
|
||||
5.698,
|
||||
20,
|
||||
"50%"
|
||||
],
|
||||
[
|
||||
14.8148,
|
||||
9,
|
||||
30.0881,
|
||||
22,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
52,
|
||||
30.6713,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
34.0901,
|
||||
52,
|
||||
31.2455,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
68.7545,
|
||||
52,
|
||||
31.2455,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
112,
|
||||
100,
|
||||
152,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
125,
|
||||
44.0171,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
154,
|
||||
44.0171,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
52.2792,
|
||||
125,
|
||||
44.0171,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
52.2792,
|
||||
154,
|
||||
44.0171,
|
||||
27,
|
||||
9999
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
197,
|
||||
44.0171,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
226,
|
||||
44.0171,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
52.2792,
|
||||
197,
|
||||
44.0171,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
52.2792,
|
||||
226,
|
||||
44.0171,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
280,
|
||||
100,
|
||||
186,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
293,
|
||||
92.5926,
|
||||
17,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
322,
|
||||
33.3066,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
37.0103,
|
||||
322,
|
||||
35.1718,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.1822,
|
||||
322,
|
||||
36.9836,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
109.1658,
|
||||
322,
|
||||
36.9881,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
353,
|
||||
33.3066,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
37.0103,
|
||||
353,
|
||||
35.1718,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.1822,
|
||||
353,
|
||||
36.9836,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
109.1658,
|
||||
353,
|
||||
36.9881,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
387,
|
||||
33.3066,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
37.0103,
|
||||
387,
|
||||
35.1718,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.1822,
|
||||
387,
|
||||
36.9836,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
109.1658,
|
||||
387,
|
||||
36.9881,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
420,
|
||||
33.3066,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
37.0103,
|
||||
420,
|
||||
35.1718,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.1822,
|
||||
420,
|
||||
36.9836,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
109.1658,
|
||||
420,
|
||||
36.9881,
|
||||
33,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"768": {
|
||||
"name": "invoice-detail",
|
||||
"viewportWidth": 736,
|
||||
"width": 736,
|
||||
"height": 444,
|
||||
"bones": [
|
||||
[
|
||||
1.6304,
|
||||
12,
|
||||
2.7174,
|
||||
20,
|
||||
"50%"
|
||||
],
|
||||
[
|
||||
7.0652,
|
||||
7,
|
||||
17.5378,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
62.9692,
|
||||
0,
|
||||
9.1733,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
73.7729,
|
||||
0,
|
||||
13.6379,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
89.0413,
|
||||
0,
|
||||
10.9587,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
60,
|
||||
100,
|
||||
164,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
79,
|
||||
46.3315,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
108,
|
||||
46.3315,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
51.087,
|
||||
79,
|
||||
46.3315,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
51.087,
|
||||
108,
|
||||
46.3315,
|
||||
27,
|
||||
9999
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
151,
|
||||
46.3315,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
180,
|
||||
46.3315,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
51.087,
|
||||
151,
|
||||
46.3315,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
51.087,
|
||||
180,
|
||||
46.3315,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
240,
|
||||
100,
|
||||
204,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
259,
|
||||
94.837,
|
||||
17,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
288,
|
||||
22.3803,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
24.9618,
|
||||
288,
|
||||
23.5882,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.55,
|
||||
288,
|
||||
24.431,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.9811,
|
||||
288,
|
||||
24.4374,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
321,
|
||||
22.3803,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
24.9618,
|
||||
321,
|
||||
23.5882,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.55,
|
||||
321,
|
||||
24.431,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.9811,
|
||||
321,
|
||||
24.4374,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
356,
|
||||
22.3803,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
24.9618,
|
||||
356,
|
||||
23.5882,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.55,
|
||||
356,
|
||||
24.431,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.9811,
|
||||
356,
|
||||
24.4374,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
391,
|
||||
22.3803,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
24.9618,
|
||||
391,
|
||||
23.5882,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.55,
|
||||
391,
|
||||
24.431,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.9811,
|
||||
391,
|
||||
24.4374,
|
||||
35,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"1280": {
|
||||
"name": "invoice-detail",
|
||||
"viewportWidth": 996,
|
||||
"width": 996,
|
||||
"height": 457,
|
||||
"bones": [
|
||||
[
|
||||
0.6024,
|
||||
7,
|
||||
2.008,
|
||||
20,
|
||||
"50%"
|
||||
],
|
||||
[
|
||||
4.0161,
|
||||
2,
|
||||
12.9597,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
73.8407,
|
||||
0,
|
||||
6.3771,
|
||||
34,
|
||||
8
|
||||
],
|
||||
[
|
||||
81.4226,
|
||||
0,
|
||||
9.6762,
|
||||
34,
|
||||
8
|
||||
],
|
||||
[
|
||||
92.3036,
|
||||
0,
|
||||
7.6964,
|
||||
34,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
50,
|
||||
100,
|
||||
160,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
69,
|
||||
47.2892,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
96,
|
||||
47.2892,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
50.8032,
|
||||
69,
|
||||
47.2892,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
50.8032,
|
||||
96,
|
||||
47.2892,
|
||||
24,
|
||||
9999
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
138,
|
||||
47.2892,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
165,
|
||||
47.2892,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
50.8032,
|
||||
138,
|
||||
47.2892,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
50.8032,
|
||||
165,
|
||||
47.2892,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
226,
|
||||
100,
|
||||
232,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
245,
|
||||
96.1847,
|
||||
17,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
273,
|
||||
22.9606,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
24.8682,
|
||||
273,
|
||||
24.065,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.9332,
|
||||
273,
|
||||
24.578,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
73.5112,
|
||||
273,
|
||||
24.5811,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
311,
|
||||
22.9606,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
24.8682,
|
||||
311,
|
||||
24.065,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.9332,
|
||||
311,
|
||||
24.578,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
73.5112,
|
||||
311,
|
||||
24.5811,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
354,
|
||||
22.9606,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
24.8682,
|
||||
354,
|
||||
24.065,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.9332,
|
||||
354,
|
||||
24.578,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
73.5112,
|
||||
354,
|
||||
24.5811,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
396,
|
||||
22.9606,
|
||||
42,
|
||||
0
|
||||
],
|
||||
[
|
||||
24.8682,
|
||||
396,
|
||||
24.065,
|
||||
42,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.9332,
|
||||
396,
|
||||
24.578,
|
||||
42,
|
||||
0
|
||||
],
|
||||
[
|
||||
73.5112,
|
||||
396,
|
||||
24.5811,
|
||||
42,
|
||||
0
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"_hash": "934452d45a0bef9320dc379fb3f43bb5"
|
||||
}
|
||||
@@ -1,599 +0,0 @@
|
||||
{
|
||||
"breakpoints": {
|
||||
"375": {
|
||||
"name": "leave-approval",
|
||||
"viewportWidth": 351,
|
||||
"width": 351,
|
||||
"height": 294,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
22,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
26,
|
||||
100,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
61,
|
||||
100,
|
||||
233,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
74,
|
||||
19.2753,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
22.979,
|
||||
74,
|
||||
18.7812,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
41.7601,
|
||||
74,
|
||||
23.0502,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
64.8104,
|
||||
74,
|
||||
23.0502,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.8606,
|
||||
74,
|
||||
9.4373,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
97.2979,
|
||||
74,
|
||||
54.4471,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
105,
|
||||
19.2753,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
22.979,
|
||||
105,
|
||||
18.7812,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
41.7601,
|
||||
105,
|
||||
23.0502,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
64.8104,
|
||||
105,
|
||||
23.0502,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.8606,
|
||||
105,
|
||||
9.4373,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
97.2979,
|
||||
105,
|
||||
54.4471,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
159,
|
||||
19.2753,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
22.979,
|
||||
159,
|
||||
18.7812,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
41.7601,
|
||||
159,
|
||||
23.0502,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
64.8104,
|
||||
159,
|
||||
23.0502,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.8606,
|
||||
159,
|
||||
9.4373,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
97.2979,
|
||||
159,
|
||||
54.4471,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
213,
|
||||
19.2753,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
22.979,
|
||||
213,
|
||||
18.7812,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
41.7601,
|
||||
213,
|
||||
23.0502,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
64.8104,
|
||||
213,
|
||||
23.0502,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.8606,
|
||||
213,
|
||||
9.4373,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
97.2979,
|
||||
213,
|
||||
54.4471,
|
||||
54,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"768": {
|
||||
"name": "leave-approval",
|
||||
"viewportWidth": 736,
|
||||
"width": 736,
|
||||
"height": 299,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
29.4264,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
30,
|
||||
29.4264,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
67,
|
||||
100,
|
||||
232,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
86,
|
||||
12.6911,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
15.2726,
|
||||
86,
|
||||
12.3769,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.6495,
|
||||
86,
|
||||
15.0921,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
42.7416,
|
||||
86,
|
||||
15.0921,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
57.8337,
|
||||
86,
|
||||
6.4856,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
64.3194,
|
||||
86,
|
||||
33.0991,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
119,
|
||||
12.6911,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
15.2726,
|
||||
119,
|
||||
12.3769,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.6495,
|
||||
119,
|
||||
15.0921,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
42.7416,
|
||||
119,
|
||||
15.0921,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
57.8337,
|
||||
119,
|
||||
6.4856,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
64.3194,
|
||||
119,
|
||||
33.0991,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
173,
|
||||
12.6911,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
15.2726,
|
||||
173,
|
||||
12.3769,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.6495,
|
||||
173,
|
||||
15.0921,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
42.7416,
|
||||
173,
|
||||
15.0921,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
57.8337,
|
||||
173,
|
||||
6.4856,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
64.3194,
|
||||
173,
|
||||
33.0991,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
227,
|
||||
12.6911,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
15.2726,
|
||||
227,
|
||||
12.3769,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.6495,
|
||||
227,
|
||||
15.0921,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
42.7416,
|
||||
227,
|
||||
15.0921,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
57.8337,
|
||||
227,
|
||||
6.4856,
|
||||
54,
|
||||
0
|
||||
],
|
||||
[
|
||||
64.3194,
|
||||
227,
|
||||
33.0991,
|
||||
54,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"1280": {
|
||||
"name": "leave-approval",
|
||||
"viewportWidth": 996,
|
||||
"width": 996,
|
||||
"height": 299,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
21.7448,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
30,
|
||||
21.7448,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
67,
|
||||
100,
|
||||
232,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
86,
|
||||
13.8664,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
15.774,
|
||||
86,
|
||||
13.5589,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
29.333,
|
||||
86,
|
||||
16.196,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
45.529,
|
||||
86,
|
||||
16.196,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
61.725,
|
||||
86,
|
||||
7.8878,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
69.6128,
|
||||
86,
|
||||
28.4795,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
124,
|
||||
13.8664,
|
||||
52,
|
||||
0
|
||||
],
|
||||
[
|
||||
15.774,
|
||||
124,
|
||||
13.5589,
|
||||
52,
|
||||
0
|
||||
],
|
||||
[
|
||||
29.333,
|
||||
124,
|
||||
16.196,
|
||||
52,
|
||||
0
|
||||
],
|
||||
[
|
||||
45.529,
|
||||
124,
|
||||
16.196,
|
||||
52,
|
||||
0
|
||||
],
|
||||
[
|
||||
61.725,
|
||||
124,
|
||||
7.8878,
|
||||
52,
|
||||
0
|
||||
],
|
||||
[
|
||||
69.6128,
|
||||
124,
|
||||
28.4795,
|
||||
52,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
176,
|
||||
13.8664,
|
||||
52,
|
||||
0
|
||||
],
|
||||
[
|
||||
15.774,
|
||||
176,
|
||||
13.5589,
|
||||
52,
|
||||
0
|
||||
],
|
||||
[
|
||||
29.333,
|
||||
176,
|
||||
16.196,
|
||||
52,
|
||||
0
|
||||
],
|
||||
[
|
||||
45.529,
|
||||
176,
|
||||
16.196,
|
||||
52,
|
||||
0
|
||||
],
|
||||
[
|
||||
61.725,
|
||||
176,
|
||||
7.8878,
|
||||
52,
|
||||
0
|
||||
],
|
||||
[
|
||||
69.6128,
|
||||
176,
|
||||
28.4795,
|
||||
52,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
228,
|
||||
13.8664,
|
||||
52,
|
||||
0
|
||||
],
|
||||
[
|
||||
15.774,
|
||||
228,
|
||||
13.5589,
|
||||
52,
|
||||
0
|
||||
],
|
||||
[
|
||||
29.333,
|
||||
228,
|
||||
16.196,
|
||||
52,
|
||||
0
|
||||
],
|
||||
[
|
||||
45.529,
|
||||
228,
|
||||
16.196,
|
||||
52,
|
||||
0
|
||||
],
|
||||
[
|
||||
61.725,
|
||||
228,
|
||||
7.8878,
|
||||
52,
|
||||
0
|
||||
],
|
||||
[
|
||||
69.6128,
|
||||
228,
|
||||
28.4795,
|
||||
52,
|
||||
0
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"_hash": "4b74917f659334073252a738cfa9c4ac"
|
||||
}
|
||||
@@ -1,704 +0,0 @@
|
||||
{
|
||||
"breakpoints": {
|
||||
"375": {
|
||||
"name": "leave-requests",
|
||||
"viewportWidth": 351,
|
||||
"width": 351,
|
||||
"height": 367,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
22,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
26,
|
||||
100,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
53,
|
||||
100,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
113,
|
||||
100,
|
||||
254,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
126,
|
||||
21.1806,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
24.8843,
|
||||
126,
|
||||
20.6375,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
45.5217,
|
||||
126,
|
||||
25.3294,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.8511,
|
||||
126,
|
||||
25.3294,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
96.1806,
|
||||
126,
|
||||
10.3677,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
106.5483,
|
||||
126,
|
||||
20.7977,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
127.346,
|
||||
126,
|
||||
18.8079,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
157,
|
||||
21.1806,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
24.8843,
|
||||
157,
|
||||
20.6375,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
45.5217,
|
||||
157,
|
||||
25.3294,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.8511,
|
||||
157,
|
||||
25.3294,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
96.1806,
|
||||
157,
|
||||
10.3677,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
106.5483,
|
||||
157,
|
||||
20.7977,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
127.346,
|
||||
157,
|
||||
18.8079,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
218,
|
||||
21.1806,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
24.8843,
|
||||
218,
|
||||
20.6375,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
45.5217,
|
||||
218,
|
||||
25.3294,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.8511,
|
||||
218,
|
||||
25.3294,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
96.1806,
|
||||
218,
|
||||
10.3677,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
106.5483,
|
||||
218,
|
||||
20.7977,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
127.346,
|
||||
218,
|
||||
18.8079,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
279,
|
||||
21.1806,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
24.8843,
|
||||
279,
|
||||
20.6375,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
45.5217,
|
||||
279,
|
||||
25.3294,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.8511,
|
||||
279,
|
||||
25.3294,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
96.1806,
|
||||
279,
|
||||
10.3677,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
106.5483,
|
||||
279,
|
||||
20.7977,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
127.346,
|
||||
279,
|
||||
18.8079,
|
||||
61,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"768": {
|
||||
"name": "leave-requests",
|
||||
"viewportWidth": 736,
|
||||
"width": 736,
|
||||
"height": 320,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
27.1888,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
30,
|
||||
27.1888,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
83.6914,
|
||||
4,
|
||||
16.3086,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
67,
|
||||
100,
|
||||
253,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
86,
|
||||
14.313,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
16.8945,
|
||||
86,
|
||||
13.9585,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
30.853,
|
||||
86,
|
||||
17.0219,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.8749,
|
||||
86,
|
||||
17.0219,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
64.8968,
|
||||
86,
|
||||
7.3157,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.2126,
|
||||
86,
|
||||
13.2006,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
85.4131,
|
||||
86,
|
||||
12.0053,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
119,
|
||||
14.313,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
16.8945,
|
||||
119,
|
||||
13.9585,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
30.853,
|
||||
119,
|
||||
17.0219,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.8749,
|
||||
119,
|
||||
17.0219,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
64.8968,
|
||||
119,
|
||||
7.3157,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.2126,
|
||||
119,
|
||||
13.2006,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
85.4131,
|
||||
119,
|
||||
12.0053,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
180,
|
||||
14.313,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
16.8945,
|
||||
180,
|
||||
13.9585,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
30.853,
|
||||
180,
|
||||
17.0219,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.8749,
|
||||
180,
|
||||
17.0219,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
64.8968,
|
||||
180,
|
||||
7.3157,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.2126,
|
||||
180,
|
||||
13.2006,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
85.4131,
|
||||
180,
|
||||
12.0053,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
241,
|
||||
14.313,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
16.8945,
|
||||
241,
|
||||
13.9585,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
30.853,
|
||||
241,
|
||||
17.0219,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.8749,
|
||||
241,
|
||||
17.0219,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
64.8968,
|
||||
241,
|
||||
7.3157,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.2126,
|
||||
241,
|
||||
13.2006,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
85.4131,
|
||||
241,
|
||||
12.0053,
|
||||
61,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"1280": {
|
||||
"name": "leave-requests",
|
||||
"viewportWidth": 996,
|
||||
"width": 996,
|
||||
"height": 308,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
20.0913,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
30,
|
||||
20.0913,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
88.3503,
|
||||
10,
|
||||
11.6497,
|
||||
32,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
67,
|
||||
100,
|
||||
241,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
86,
|
||||
14.9787,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
16.8863,
|
||||
86,
|
||||
14.6461,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
31.5324,
|
||||
86,
|
||||
17.495,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
49.0274,
|
||||
86,
|
||||
17.495,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
66.5223,
|
||||
86,
|
||||
8.52,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
75.0424,
|
||||
86,
|
||||
12.74,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.7824,
|
||||
86,
|
||||
10.31,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
124,
|
||||
14.9787,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
16.8863,
|
||||
124,
|
||||
14.6461,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
31.5324,
|
||||
124,
|
||||
17.495,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
49.0274,
|
||||
124,
|
||||
17.495,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
66.5223,
|
||||
124,
|
||||
8.52,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
75.0424,
|
||||
124,
|
||||
12.74,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.7824,
|
||||
124,
|
||||
10.31,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
179,
|
||||
14.9787,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
16.8863,
|
||||
179,
|
||||
14.6461,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
31.5324,
|
||||
179,
|
||||
17.495,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
49.0274,
|
||||
179,
|
||||
17.495,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
66.5223,
|
||||
179,
|
||||
8.52,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
75.0424,
|
||||
179,
|
||||
12.74,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.7824,
|
||||
179,
|
||||
10.31,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
234,
|
||||
14.9787,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
16.8863,
|
||||
234,
|
||||
14.6461,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
31.5324,
|
||||
234,
|
||||
17.495,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
49.0274,
|
||||
234,
|
||||
17.495,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
66.5223,
|
||||
234,
|
||||
8.52,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
75.0424,
|
||||
234,
|
||||
12.74,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.7824,
|
||||
234,
|
||||
10.31,
|
||||
55,
|
||||
0
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"_hash": "125231cbf4c6abc4e73bb48732dc9353"
|
||||
}
|
||||
@@ -1,620 +0,0 @@
|
||||
{
|
||||
"breakpoints": {
|
||||
"375": {
|
||||
"name": "offer-detail",
|
||||
"viewportWidth": 351,
|
||||
"width": 351,
|
||||
"height": 483,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
12.5356,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
52,
|
||||
100,
|
||||
22,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
86,
|
||||
100,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
146,
|
||||
100,
|
||||
338,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
159,
|
||||
44.0171,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
187,
|
||||
44.0171,
|
||||
46,
|
||||
8
|
||||
],
|
||||
[
|
||||
52.2792,
|
||||
159,
|
||||
44.0171,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
52.2792,
|
||||
187,
|
||||
44.0171,
|
||||
46,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
249,
|
||||
44.0171,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
278,
|
||||
44.0171,
|
||||
46,
|
||||
8
|
||||
],
|
||||
[
|
||||
52.2792,
|
||||
249,
|
||||
44.0171,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
52.2792,
|
||||
278,
|
||||
44.0171,
|
||||
46,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
339,
|
||||
34.4062,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.1099,
|
||||
339,
|
||||
34.8157,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.9256,
|
||||
339,
|
||||
36.6097,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
109.5353,
|
||||
339,
|
||||
36.6186,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
370,
|
||||
34.4062,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.1099,
|
||||
370,
|
||||
34.8157,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.9256,
|
||||
370,
|
||||
36.6097,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
109.5353,
|
||||
370,
|
||||
36.6186,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
404,
|
||||
34.4062,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.1099,
|
||||
404,
|
||||
34.8157,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.9256,
|
||||
404,
|
||||
36.6097,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
109.5353,
|
||||
404,
|
||||
36.6186,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
437,
|
||||
34.4062,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.1099,
|
||||
437,
|
||||
34.8157,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.9256,
|
||||
437,
|
||||
36.6097,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
109.5353,
|
||||
437,
|
||||
36.6186,
|
||||
33,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"768": {
|
||||
"name": "offer-detail",
|
||||
"viewportWidth": 736,
|
||||
"width": 736,
|
||||
"height": 416,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
5.9783,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
38.4829,
|
||||
7,
|
||||
19.8412,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
90.8267,
|
||||
0,
|
||||
9.1733,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
60,
|
||||
100,
|
||||
356,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
79,
|
||||
46.3315,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
108,
|
||||
46.3315,
|
||||
46,
|
||||
8
|
||||
],
|
||||
[
|
||||
51.087,
|
||||
79,
|
||||
46.3315,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
51.087,
|
||||
108,
|
||||
46.3315,
|
||||
46,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
169,
|
||||
46.3315,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
198,
|
||||
46.3315,
|
||||
46,
|
||||
8
|
||||
],
|
||||
[
|
||||
51.087,
|
||||
169,
|
||||
46.3315,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
51.087,
|
||||
198,
|
||||
46.3315,
|
||||
46,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
260,
|
||||
22.8558,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.4373,
|
||||
260,
|
||||
23.4333,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.8706,
|
||||
260,
|
||||
24.2718,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
73.1424,
|
||||
260,
|
||||
24.2761,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
292,
|
||||
22.8558,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.4373,
|
||||
292,
|
||||
23.4333,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.8706,
|
||||
292,
|
||||
24.2718,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
73.1424,
|
||||
292,
|
||||
24.2761,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
327,
|
||||
22.8558,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.4373,
|
||||
327,
|
||||
23.4333,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.8706,
|
||||
327,
|
||||
24.2718,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
73.1424,
|
||||
327,
|
||||
24.2761,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
362,
|
||||
22.8558,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.4373,
|
||||
362,
|
||||
23.4333,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.8706,
|
||||
362,
|
||||
24.2718,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
73.1424,
|
||||
362,
|
||||
24.2761,
|
||||
35,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"1280": {
|
||||
"name": "offer-detail",
|
||||
"viewportWidth": 996,
|
||||
"width": 996,
|
||||
"height": 419,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
3.2129,
|
||||
32,
|
||||
8
|
||||
],
|
||||
[
|
||||
41.0878,
|
||||
1,
|
||||
14.6618,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
93.6229,
|
||||
0,
|
||||
6.3771,
|
||||
32,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
48,
|
||||
100,
|
||||
371,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
67,
|
||||
47.2892,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
94,
|
||||
47.2892,
|
||||
41,
|
||||
8
|
||||
],
|
||||
[
|
||||
50.8032,
|
||||
67,
|
||||
47.2892,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
50.8032,
|
||||
94,
|
||||
47.2892,
|
||||
41,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
151,
|
||||
47.2892,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
178,
|
||||
47.2892,
|
||||
41,
|
||||
8
|
||||
],
|
||||
[
|
||||
50.8032,
|
||||
151,
|
||||
47.2892,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
50.8032,
|
||||
178,
|
||||
47.2892,
|
||||
41,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
235,
|
||||
23.2194,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.1271,
|
||||
235,
|
||||
23.9787,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
49.1058,
|
||||
235,
|
||||
24.4917,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
73.5975,
|
||||
235,
|
||||
24.4949,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
273,
|
||||
23.2194,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.1271,
|
||||
273,
|
||||
23.9787,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
49.1058,
|
||||
273,
|
||||
24.4917,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
73.5975,
|
||||
273,
|
||||
24.4949,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
316,
|
||||
23.2194,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.1271,
|
||||
316,
|
||||
23.9787,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
49.1058,
|
||||
316,
|
||||
24.4917,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
73.5975,
|
||||
316,
|
||||
24.4949,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
358,
|
||||
23.2194,
|
||||
42,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.1271,
|
||||
358,
|
||||
23.9787,
|
||||
42,
|
||||
0
|
||||
],
|
||||
[
|
||||
49.1058,
|
||||
358,
|
||||
24.4917,
|
||||
42,
|
||||
0
|
||||
],
|
||||
[
|
||||
73.5975,
|
||||
358,
|
||||
24.4949,
|
||||
42,
|
||||
0
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"_hash": "67676fde7dd5c432922d819fc9bf48db"
|
||||
}
|
||||
@@ -1,641 +0,0 @@
|
||||
{
|
||||
"breakpoints": {
|
||||
"375": {
|
||||
"name": "offers-customers",
|
||||
"viewportWidth": 351,
|
||||
"width": 351,
|
||||
"height": 549,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
22,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
26,
|
||||
100,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
53,
|
||||
100,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
113,
|
||||
100,
|
||||
436,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
126,
|
||||
92.5926,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
186,
|
||||
34.562,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.2657,
|
||||
186,
|
||||
23.7936,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
62.0593,
|
||||
186,
|
||||
32.4653,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
94.5246,
|
||||
186,
|
||||
51.6293,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
217,
|
||||
34.562,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.2657,
|
||||
217,
|
||||
23.7936,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
62.0593,
|
||||
217,
|
||||
32.4653,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
94.5246,
|
||||
217,
|
||||
51.6293,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
278,
|
||||
34.562,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.2657,
|
||||
278,
|
||||
23.7936,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
62.0593,
|
||||
278,
|
||||
32.4653,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
94.5246,
|
||||
278,
|
||||
51.6293,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
339,
|
||||
34.562,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.2657,
|
||||
339,
|
||||
23.7936,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
62.0593,
|
||||
339,
|
||||
32.4653,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
94.5246,
|
||||
339,
|
||||
51.6293,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
400,
|
||||
34.562,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.2657,
|
||||
400,
|
||||
23.7936,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
62.0593,
|
||||
400,
|
||||
32.4653,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
94.5246,
|
||||
400,
|
||||
51.6293,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
461,
|
||||
34.562,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.2657,
|
||||
461,
|
||||
23.7936,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
62.0593,
|
||||
461,
|
||||
32.4653,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
94.5246,
|
||||
461,
|
||||
51.6293,
|
||||
61,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"768": {
|
||||
"name": "offers-customers",
|
||||
"viewportWidth": 736,
|
||||
"width": 736,
|
||||
"height": 502,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
12.9458,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
30,
|
||||
12.9458,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
80.6322,
|
||||
4,
|
||||
19.3678,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
67,
|
||||
100,
|
||||
435,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
86,
|
||||
94.837,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
146,
|
||||
23.2868,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.8683,
|
||||
146,
|
||||
16.453,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
42.3212,
|
||||
146,
|
||||
21.9175,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
64.2387,
|
||||
146,
|
||||
33.1798,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
179,
|
||||
23.2868,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.8683,
|
||||
179,
|
||||
16.453,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
42.3212,
|
||||
179,
|
||||
21.9175,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
64.2387,
|
||||
179,
|
||||
33.1798,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
240,
|
||||
23.2868,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.8683,
|
||||
240,
|
||||
16.453,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
42.3212,
|
||||
240,
|
||||
21.9175,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
64.2387,
|
||||
240,
|
||||
33.1798,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
301,
|
||||
23.2868,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.8683,
|
||||
301,
|
||||
16.453,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
42.3212,
|
||||
301,
|
||||
21.9175,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
64.2387,
|
||||
301,
|
||||
33.1798,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
362,
|
||||
23.2868,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.8683,
|
||||
362,
|
||||
16.453,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
42.3212,
|
||||
362,
|
||||
21.9175,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
64.2387,
|
||||
362,
|
||||
33.1798,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
423,
|
||||
23.2868,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.8683,
|
||||
423,
|
||||
16.453,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
42.3212,
|
||||
423,
|
||||
21.9175,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
64.2387,
|
||||
423,
|
||||
33.1798,
|
||||
61,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"1280": {
|
||||
"name": "offers-customers",
|
||||
"viewportWidth": 996,
|
||||
"width": 996,
|
||||
"height": 470,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
9.5664,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
30,
|
||||
9.5664,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
86.0897,
|
||||
10,
|
||||
13.9103,
|
||||
32,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
67,
|
||||
100,
|
||||
403,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
86,
|
||||
96.1847,
|
||||
36,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
138,
|
||||
25.673,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.5806,
|
||||
138,
|
||||
19.0904,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
46.6711,
|
||||
138,
|
||||
24.3254,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.9965,
|
||||
138,
|
||||
27.0959,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
176,
|
||||
25.673,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.5806,
|
||||
176,
|
||||
19.0904,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
46.6711,
|
||||
176,
|
||||
24.3254,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.9965,
|
||||
176,
|
||||
27.0959,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
231,
|
||||
25.673,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.5806,
|
||||
231,
|
||||
19.0904,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
46.6711,
|
||||
231,
|
||||
24.3254,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.9965,
|
||||
231,
|
||||
27.0959,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
286,
|
||||
25.673,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.5806,
|
||||
286,
|
||||
19.0904,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
46.6711,
|
||||
286,
|
||||
24.3254,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.9965,
|
||||
286,
|
||||
27.0959,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
341,
|
||||
25.673,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.5806,
|
||||
341,
|
||||
19.0904,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
46.6711,
|
||||
341,
|
||||
24.3254,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.9965,
|
||||
341,
|
||||
27.0959,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
396,
|
||||
25.673,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.5806,
|
||||
396,
|
||||
19.0904,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
46.6711,
|
||||
396,
|
||||
24.3254,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.9965,
|
||||
396,
|
||||
27.0959,
|
||||
55,
|
||||
0
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"_hash": "63b2dec2b6ceb84d931a000ab8b669dd"
|
||||
}
|
||||
@@ -1,452 +0,0 @@
|
||||
{
|
||||
"breakpoints": {
|
||||
"375": {
|
||||
"name": "offers-templates",
|
||||
"viewportWidth": 351,
|
||||
"width": 351,
|
||||
"height": 436,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
436,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
13,
|
||||
92.5926,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
73,
|
||||
39.659,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
43.3627,
|
||||
73,
|
||||
39.6857,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
83.0484,
|
||||
73,
|
||||
63.1054,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
104,
|
||||
39.659,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
43.3627,
|
||||
104,
|
||||
39.6857,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
83.0484,
|
||||
104,
|
||||
63.1054,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
165,
|
||||
39.659,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
43.3627,
|
||||
165,
|
||||
39.6857,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
83.0484,
|
||||
165,
|
||||
63.1054,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
226,
|
||||
39.659,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
43.3627,
|
||||
226,
|
||||
39.6857,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
83.0484,
|
||||
226,
|
||||
63.1054,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
287,
|
||||
39.659,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
43.3627,
|
||||
287,
|
||||
39.6857,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
83.0484,
|
||||
287,
|
||||
63.1054,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
348,
|
||||
39.659,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
43.3627,
|
||||
348,
|
||||
39.6857,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
83.0484,
|
||||
348,
|
||||
63.1054,
|
||||
61,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"768": {
|
||||
"name": "offers-templates",
|
||||
"viewportWidth": 736,
|
||||
"width": 736,
|
||||
"height": 435,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
435,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
19,
|
||||
94.837,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
79,
|
||||
26.9744,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
29.5559,
|
||||
79,
|
||||
26.9977,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
56.5536,
|
||||
79,
|
||||
40.8649,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
112,
|
||||
26.9744,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
29.5559,
|
||||
112,
|
||||
26.9977,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
56.5536,
|
||||
112,
|
||||
40.8649,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
173,
|
||||
26.9744,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
29.5559,
|
||||
173,
|
||||
26.9977,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
56.5536,
|
||||
173,
|
||||
40.8649,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
234,
|
||||
26.9744,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
29.5559,
|
||||
234,
|
||||
26.9977,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
56.5536,
|
||||
234,
|
||||
40.8649,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
295,
|
||||
26.9744,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
29.5559,
|
||||
295,
|
||||
26.9977,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
56.5536,
|
||||
295,
|
||||
40.8649,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
356,
|
||||
26.9744,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
29.5559,
|
||||
356,
|
||||
26.9977,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
56.5536,
|
||||
356,
|
||||
40.8649,
|
||||
61,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"1280": {
|
||||
"name": "offers-templates",
|
||||
"viewportWidth": 996,
|
||||
"width": 996,
|
||||
"height": 403,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
403,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
19,
|
||||
96.1847,
|
||||
36,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
71,
|
||||
30.8719,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
32.7796,
|
||||
71,
|
||||
30.897,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
63.6766,
|
||||
71,
|
||||
34.4158,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
109,
|
||||
30.8719,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
32.7796,
|
||||
109,
|
||||
30.897,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
63.6766,
|
||||
109,
|
||||
34.4158,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
164,
|
||||
30.8719,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
32.7796,
|
||||
164,
|
||||
30.897,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
63.6766,
|
||||
164,
|
||||
34.4158,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
219,
|
||||
30.8719,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
32.7796,
|
||||
219,
|
||||
30.897,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
63.6766,
|
||||
219,
|
||||
34.4158,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
274,
|
||||
30.8719,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
32.7796,
|
||||
274,
|
||||
30.897,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
63.6766,
|
||||
274,
|
||||
34.4158,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
329,
|
||||
30.8719,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
32.7796,
|
||||
329,
|
||||
30.897,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
63.6766,
|
||||
329,
|
||||
34.4158,
|
||||
55,
|
||||
0
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"_hash": "5e5881859bd932a42345c69a6a30ca65"
|
||||
}
|
||||
@@ -1,872 +0,0 @@
|
||||
{
|
||||
"breakpoints": {
|
||||
"375": {
|
||||
"name": "offers",
|
||||
"viewportWidth": 351,
|
||||
"width": 351,
|
||||
"height": 497,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
22,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
26,
|
||||
100,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
61,
|
||||
100,
|
||||
436,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
74,
|
||||
92.5926,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
134,
|
||||
26.7495,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
30.4532,
|
||||
134,
|
||||
20.6019,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
51.055,
|
||||
134,
|
||||
21.4165,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.4715,
|
||||
134,
|
||||
23.0502,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
95.5217,
|
||||
134,
|
||||
23.0502,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
118.5719,
|
||||
134,
|
||||
30.7692,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
165,
|
||||
26.7495,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
30.4532,
|
||||
165,
|
||||
20.6019,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
51.055,
|
||||
165,
|
||||
21.4165,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.4715,
|
||||
165,
|
||||
23.0502,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
95.5217,
|
||||
165,
|
||||
23.0502,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
118.5719,
|
||||
165,
|
||||
30.7692,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
226,
|
||||
26.7495,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
30.4532,
|
||||
226,
|
||||
20.6019,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
51.055,
|
||||
226,
|
||||
21.4165,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.4715,
|
||||
226,
|
||||
23.0502,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
95.5217,
|
||||
226,
|
||||
23.0502,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
118.5719,
|
||||
226,
|
||||
30.7692,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
287,
|
||||
26.7495,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
30.4532,
|
||||
287,
|
||||
20.6019,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
51.055,
|
||||
287,
|
||||
21.4165,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.4715,
|
||||
287,
|
||||
23.0502,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
95.5217,
|
||||
287,
|
||||
23.0502,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
118.5719,
|
||||
287,
|
||||
30.7692,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
348,
|
||||
26.7495,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
30.4532,
|
||||
348,
|
||||
20.6019,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
51.055,
|
||||
348,
|
||||
21.4165,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.4715,
|
||||
348,
|
||||
23.0502,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
95.5217,
|
||||
348,
|
||||
23.0502,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
118.5719,
|
||||
348,
|
||||
30.7692,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
409,
|
||||
26.7495,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
30.4532,
|
||||
409,
|
||||
20.6019,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
51.055,
|
||||
409,
|
||||
21.4165,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.4715,
|
||||
409,
|
||||
23.0502,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
95.5217,
|
||||
409,
|
||||
23.0502,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
118.5719,
|
||||
409,
|
||||
30.7692,
|
||||
61,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"768": {
|
||||
"name": "offers",
|
||||
"viewportWidth": 736,
|
||||
"width": 736,
|
||||
"height": 502,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
11.3451,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
30,
|
||||
11.3451,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
67,
|
||||
100,
|
||||
435,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
86,
|
||||
94.837,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
146,
|
||||
17.6779,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
20.2594,
|
||||
146,
|
||||
13.7101,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
33.9695,
|
||||
146,
|
||||
13.3301,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.2996,
|
||||
146,
|
||||
15.2917,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
62.5913,
|
||||
146,
|
||||
15.2917,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
77.883,
|
||||
146,
|
||||
19.5355,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
179,
|
||||
17.6779,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
20.2594,
|
||||
179,
|
||||
13.7101,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
33.9695,
|
||||
179,
|
||||
13.3301,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.2996,
|
||||
179,
|
||||
15.2917,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
62.5913,
|
||||
179,
|
||||
15.2917,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
77.883,
|
||||
179,
|
||||
19.5355,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
240,
|
||||
17.6779,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
20.2594,
|
||||
240,
|
||||
13.7101,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
33.9695,
|
||||
240,
|
||||
13.3301,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.2996,
|
||||
240,
|
||||
15.2917,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
62.5913,
|
||||
240,
|
||||
15.2917,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
77.883,
|
||||
240,
|
||||
19.5355,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
301,
|
||||
17.6779,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
20.2594,
|
||||
301,
|
||||
13.7101,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
33.9695,
|
||||
301,
|
||||
13.3301,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.2996,
|
||||
301,
|
||||
15.2917,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
62.5913,
|
||||
301,
|
||||
15.2917,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
77.883,
|
||||
301,
|
||||
19.5355,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
362,
|
||||
17.6779,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
20.2594,
|
||||
362,
|
||||
13.7101,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
33.9695,
|
||||
362,
|
||||
13.3301,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.2996,
|
||||
362,
|
||||
15.2917,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
62.5913,
|
||||
362,
|
||||
15.2917,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
77.883,
|
||||
362,
|
||||
19.5355,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
423,
|
||||
17.6779,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
20.2594,
|
||||
423,
|
||||
13.7101,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
33.9695,
|
||||
423,
|
||||
13.3301,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.2996,
|
||||
423,
|
||||
15.2917,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
62.5913,
|
||||
423,
|
||||
15.2917,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
77.883,
|
||||
423,
|
||||
19.5355,
|
||||
61,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"1280": {
|
||||
"name": "offers",
|
||||
"viewportWidth": 996,
|
||||
"width": 996,
|
||||
"height": 470,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
8.3835,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
30,
|
||||
8.3835,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
67,
|
||||
100,
|
||||
403,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
86,
|
||||
96.1847,
|
||||
36,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
138,
|
||||
18.8912,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
20.7988,
|
||||
138,
|
||||
15.0085,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.8073,
|
||||
138,
|
||||
13.333,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
49.1403,
|
||||
138,
|
||||
16.5553,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.6956,
|
||||
138,
|
||||
16.5553,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
82.2509,
|
||||
138,
|
||||
15.8415,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
176,
|
||||
18.8912,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
20.7988,
|
||||
176,
|
||||
15.0085,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.8073,
|
||||
176,
|
||||
13.333,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
49.1403,
|
||||
176,
|
||||
16.5553,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.6956,
|
||||
176,
|
||||
16.5553,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
82.2509,
|
||||
176,
|
||||
15.8415,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
231,
|
||||
18.8912,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
20.7988,
|
||||
231,
|
||||
15.0085,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.8073,
|
||||
231,
|
||||
13.333,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
49.1403,
|
||||
231,
|
||||
16.5553,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.6956,
|
||||
231,
|
||||
16.5553,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
82.2509,
|
||||
231,
|
||||
15.8415,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
286,
|
||||
18.8912,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
20.7988,
|
||||
286,
|
||||
15.0085,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.8073,
|
||||
286,
|
||||
13.333,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
49.1403,
|
||||
286,
|
||||
16.5553,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.6956,
|
||||
286,
|
||||
16.5553,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
82.2509,
|
||||
286,
|
||||
15.8415,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
341,
|
||||
18.8912,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
20.7988,
|
||||
341,
|
||||
15.0085,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.8073,
|
||||
341,
|
||||
13.333,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
49.1403,
|
||||
341,
|
||||
16.5553,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.6956,
|
||||
341,
|
||||
16.5553,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
82.2509,
|
||||
341,
|
||||
15.8415,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
396,
|
||||
18.8912,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
20.7988,
|
||||
396,
|
||||
15.0085,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.8073,
|
||||
396,
|
||||
13.333,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
49.1403,
|
||||
396,
|
||||
16.5553,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.6956,
|
||||
396,
|
||||
16.5553,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
82.2509,
|
||||
396,
|
||||
15.8415,
|
||||
55,
|
||||
0
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"_hash": "62d793eb0343d832087d687b76639e09"
|
||||
}
|
||||
@@ -1,998 +0,0 @@
|
||||
{
|
||||
"breakpoints": {
|
||||
"375": {
|
||||
"name": "orders",
|
||||
"viewportWidth": 351,
|
||||
"width": 351,
|
||||
"height": 497,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
22,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
26,
|
||||
100,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
61,
|
||||
100,
|
||||
436,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
74,
|
||||
92.5926,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
134,
|
||||
26.7495,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
30.4532,
|
||||
134,
|
||||
29.1043,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
59.5575,
|
||||
134,
|
||||
20.6019,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
80.1594,
|
||||
134,
|
||||
26.6515,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
106.8109,
|
||||
134,
|
||||
23.0502,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
129.8611,
|
||||
134,
|
||||
21.2028,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
151.0639,
|
||||
134,
|
||||
17.094,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
165,
|
||||
26.7495,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
30.4532,
|
||||
165,
|
||||
29.1043,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
59.5575,
|
||||
165,
|
||||
20.6019,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
80.1594,
|
||||
165,
|
||||
26.6515,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
106.8109,
|
||||
165,
|
||||
23.0502,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
129.8611,
|
||||
165,
|
||||
21.2028,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
151.0639,
|
||||
165,
|
||||
17.094,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
226,
|
||||
26.7495,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
30.4532,
|
||||
226,
|
||||
29.1043,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
59.5575,
|
||||
226,
|
||||
20.6019,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
80.1594,
|
||||
226,
|
||||
26.6515,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
106.8109,
|
||||
226,
|
||||
23.0502,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
129.8611,
|
||||
226,
|
||||
21.2028,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
151.0639,
|
||||
226,
|
||||
17.094,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
287,
|
||||
26.7495,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
30.4532,
|
||||
287,
|
||||
29.1043,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
59.5575,
|
||||
287,
|
||||
20.6019,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
80.1594,
|
||||
287,
|
||||
26.6515,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
106.8109,
|
||||
287,
|
||||
23.0502,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
129.8611,
|
||||
287,
|
||||
21.2028,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
151.0639,
|
||||
287,
|
||||
17.094,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
348,
|
||||
26.7495,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
30.4532,
|
||||
348,
|
||||
29.1043,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
59.5575,
|
||||
348,
|
||||
20.6019,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
80.1594,
|
||||
348,
|
||||
26.6515,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
106.8109,
|
||||
348,
|
||||
23.0502,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
129.8611,
|
||||
348,
|
||||
21.2028,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
151.0639,
|
||||
348,
|
||||
17.094,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
409,
|
||||
26.7495,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
30.4532,
|
||||
409,
|
||||
29.1043,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
59.5575,
|
||||
409,
|
||||
20.6019,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
80.1594,
|
||||
409,
|
||||
26.6515,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
106.8109,
|
||||
409,
|
||||
23.0502,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
129.8611,
|
||||
409,
|
||||
21.2028,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
151.0639,
|
||||
409,
|
||||
17.094,
|
||||
61,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"768": {
|
||||
"name": "orders",
|
||||
"viewportWidth": 736,
|
||||
"width": 736,
|
||||
"height": 502,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
16.6461,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
30,
|
||||
16.6461,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
67,
|
||||
100,
|
||||
435,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
86,
|
||||
94.837,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
146,
|
||||
15.642,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
18.2235,
|
||||
146,
|
||||
16.9837,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.2072,
|
||||
146,
|
||||
12.1306,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.3378,
|
||||
146,
|
||||
14.5338,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
61.8716,
|
||||
146,
|
||||
13.5296,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
75.4012,
|
||||
146,
|
||||
12.4745,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.8758,
|
||||
146,
|
||||
9.5427,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
179,
|
||||
15.642,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
18.2235,
|
||||
179,
|
||||
16.9837,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.2072,
|
||||
179,
|
||||
12.1306,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.3378,
|
||||
179,
|
||||
14.5338,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
61.8716,
|
||||
179,
|
||||
13.5296,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
75.4012,
|
||||
179,
|
||||
12.4745,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.8758,
|
||||
179,
|
||||
9.5427,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
240,
|
||||
15.642,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
18.2235,
|
||||
240,
|
||||
16.9837,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.2072,
|
||||
240,
|
||||
12.1306,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.3378,
|
||||
240,
|
||||
14.5338,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
61.8716,
|
||||
240,
|
||||
13.5296,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
75.4012,
|
||||
240,
|
||||
12.4745,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.8758,
|
||||
240,
|
||||
9.5427,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
301,
|
||||
15.642,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
18.2235,
|
||||
301,
|
||||
16.9837,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.2072,
|
||||
301,
|
||||
12.1306,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.3378,
|
||||
301,
|
||||
14.5338,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
61.8716,
|
||||
301,
|
||||
13.5296,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
75.4012,
|
||||
301,
|
||||
12.4745,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.8758,
|
||||
301,
|
||||
9.5427,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
362,
|
||||
15.642,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
18.2235,
|
||||
362,
|
||||
16.9837,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.2072,
|
||||
362,
|
||||
12.1306,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.3378,
|
||||
362,
|
||||
14.5338,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
61.8716,
|
||||
362,
|
||||
13.5296,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
75.4012,
|
||||
362,
|
||||
12.4745,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.8758,
|
||||
362,
|
||||
9.5427,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
423,
|
||||
15.642,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
18.2235,
|
||||
423,
|
||||
16.9837,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.2072,
|
||||
423,
|
||||
12.1306,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.3378,
|
||||
423,
|
||||
14.5338,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
61.8716,
|
||||
423,
|
||||
13.5296,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
75.4012,
|
||||
423,
|
||||
12.4745,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.8758,
|
||||
423,
|
||||
9.5427,
|
||||
61,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"1280": {
|
||||
"name": "orders",
|
||||
"viewportWidth": 996,
|
||||
"width": 996,
|
||||
"height": 470,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
12.3008,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
30,
|
||||
12.3008,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
67,
|
||||
100,
|
||||
403,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
86,
|
||||
96.1847,
|
||||
36,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
138,
|
||||
16.2243,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
18.1319,
|
||||
138,
|
||||
17.5044,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.6363,
|
||||
138,
|
||||
12.8891,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.5254,
|
||||
138,
|
||||
13.7535,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
62.2788,
|
||||
138,
|
||||
14.2178,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
76.4966,
|
||||
138,
|
||||
13.2138,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
89.7104,
|
||||
138,
|
||||
8.382,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
176,
|
||||
16.2243,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
18.1319,
|
||||
176,
|
||||
17.5044,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.6363,
|
||||
176,
|
||||
12.8891,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.5254,
|
||||
176,
|
||||
13.7535,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
62.2788,
|
||||
176,
|
||||
14.2178,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
76.4966,
|
||||
176,
|
||||
13.2138,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
89.7104,
|
||||
176,
|
||||
8.382,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
231,
|
||||
16.2243,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
18.1319,
|
||||
231,
|
||||
17.5044,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.6363,
|
||||
231,
|
||||
12.8891,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.5254,
|
||||
231,
|
||||
13.7535,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
62.2788,
|
||||
231,
|
||||
14.2178,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
76.4966,
|
||||
231,
|
||||
13.2138,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
89.7104,
|
||||
231,
|
||||
8.382,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
286,
|
||||
16.2243,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
18.1319,
|
||||
286,
|
||||
17.5044,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.6363,
|
||||
286,
|
||||
12.8891,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.5254,
|
||||
286,
|
||||
13.7535,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
62.2788,
|
||||
286,
|
||||
14.2178,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
76.4966,
|
||||
286,
|
||||
13.2138,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
89.7104,
|
||||
286,
|
||||
8.382,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
341,
|
||||
16.2243,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
18.1319,
|
||||
341,
|
||||
17.5044,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.6363,
|
||||
341,
|
||||
12.8891,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.5254,
|
||||
341,
|
||||
13.7535,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
62.2788,
|
||||
341,
|
||||
14.2178,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
76.4966,
|
||||
341,
|
||||
13.2138,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
89.7104,
|
||||
341,
|
||||
8.382,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
396,
|
||||
16.2243,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
18.1319,
|
||||
396,
|
||||
17.5044,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.6363,
|
||||
396,
|
||||
12.8891,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.5254,
|
||||
396,
|
||||
13.7535,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
62.2788,
|
||||
396,
|
||||
14.2178,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
76.4966,
|
||||
396,
|
||||
13.2138,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
89.7104,
|
||||
396,
|
||||
8.382,
|
||||
55,
|
||||
0
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"_hash": "677a0002aa805c9f7790bc68c6374bb5"
|
||||
}
|
||||
@@ -1,371 +0,0 @@
|
||||
{
|
||||
"breakpoints": {
|
||||
"375": {
|
||||
"name": "project-detail",
|
||||
"viewportWidth": 351,
|
||||
"width": 351,
|
||||
"height": 481,
|
||||
"bones": [
|
||||
[
|
||||
3.4188,
|
||||
12,
|
||||
5.698,
|
||||
20,
|
||||
"50%"
|
||||
],
|
||||
[
|
||||
14.8148,
|
||||
9,
|
||||
50.2315,
|
||||
22,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
52,
|
||||
48.0057,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
51.4245,
|
||||
52,
|
||||
48.5755,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
112,
|
||||
100,
|
||||
188,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
125,
|
||||
48.1481,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
154,
|
||||
48.1481,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
56.4103,
|
||||
125,
|
||||
48.1481,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
56.4103,
|
||||
154,
|
||||
48.1481,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
214,
|
||||
48.1481,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
243,
|
||||
48.1481,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
56.4103,
|
||||
214,
|
||||
48.1481,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
56.4103,
|
||||
243,
|
||||
48.1481,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
316,
|
||||
100,
|
||||
165,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
329,
|
||||
92.5926,
|
||||
17,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
357,
|
||||
92.5926,
|
||||
104,
|
||||
8
|
||||
]
|
||||
]
|
||||
},
|
||||
"768": {
|
||||
"name": "project-detail",
|
||||
"viewportWidth": 736,
|
||||
"width": 736,
|
||||
"height": 453,
|
||||
"bones": [
|
||||
[
|
||||
1.6304,
|
||||
12,
|
||||
2.7174,
|
||||
20,
|
||||
"50%"
|
||||
],
|
||||
[
|
||||
7.0652,
|
||||
7,
|
||||
29.2799,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
78.2375,
|
||||
0,
|
||||
9.1733,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
89.0413,
|
||||
0,
|
||||
10.9587,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
60,
|
||||
100,
|
||||
200,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
79,
|
||||
46.3315,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
108,
|
||||
46.3315,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
51.087,
|
||||
79,
|
||||
46.3315,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
51.087,
|
||||
108,
|
||||
46.3315,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
168,
|
||||
46.3315,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
197,
|
||||
46.3315,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
51.087,
|
||||
168,
|
||||
46.3315,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
51.087,
|
||||
197,
|
||||
46.3315,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
276,
|
||||
100,
|
||||
177,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
295,
|
||||
94.837,
|
||||
17,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
323,
|
||||
94.837,
|
||||
104,
|
||||
8
|
||||
]
|
||||
]
|
||||
},
|
||||
"1280": {
|
||||
"name": "project-detail",
|
||||
"viewportWidth": 996,
|
||||
"width": 996,
|
||||
"height": 404,
|
||||
"bones": [
|
||||
[
|
||||
0.6024,
|
||||
7,
|
||||
2.008,
|
||||
20,
|
||||
"50%"
|
||||
],
|
||||
[
|
||||
4.0161,
|
||||
2,
|
||||
21.6365,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
84.7217,
|
||||
0,
|
||||
6.3771,
|
||||
34,
|
||||
8
|
||||
],
|
||||
[
|
||||
92.3036,
|
||||
0,
|
||||
7.6964,
|
||||
34,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
50,
|
||||
100,
|
||||
180,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
69,
|
||||
47.2892,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
96,
|
||||
47.2892,
|
||||
36,
|
||||
8
|
||||
],
|
||||
[
|
||||
50.8032,
|
||||
69,
|
||||
47.2892,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
50.8032,
|
||||
96,
|
||||
47.2892,
|
||||
36,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
148,
|
||||
47.2892,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
175,
|
||||
47.2892,
|
||||
36,
|
||||
8
|
||||
],
|
||||
[
|
||||
50.8032,
|
||||
148,
|
||||
47.2892,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
50.8032,
|
||||
175,
|
||||
47.2892,
|
||||
36,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
246,
|
||||
100,
|
||||
157,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
265,
|
||||
96.1847,
|
||||
17,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
294,
|
||||
96.1847,
|
||||
84,
|
||||
8
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"_hash": "ab5e1f108d42c55b0e6382fcaffff793"
|
||||
}
|
||||
@@ -1,746 +0,0 @@
|
||||
{
|
||||
"breakpoints": {
|
||||
"375": {
|
||||
"name": "projects",
|
||||
"viewportWidth": 351,
|
||||
"width": 351,
|
||||
"height": 497,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
22,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
26,
|
||||
100,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
61,
|
||||
100,
|
||||
436,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
74,
|
||||
92.5926,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
134,
|
||||
34.6065,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.3102,
|
||||
134,
|
||||
31.3568,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
69.667,
|
||||
134,
|
||||
26.6515,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
96.3186,
|
||||
134,
|
||||
27.7066,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
124.0251,
|
||||
134,
|
||||
22.1287,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
165,
|
||||
34.6065,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.3102,
|
||||
165,
|
||||
31.3568,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
69.667,
|
||||
165,
|
||||
26.6515,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
96.3186,
|
||||
165,
|
||||
27.7066,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
124.0251,
|
||||
165,
|
||||
22.1287,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
226,
|
||||
34.6065,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.3102,
|
||||
226,
|
||||
31.3568,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
69.667,
|
||||
226,
|
||||
26.6515,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
96.3186,
|
||||
226,
|
||||
27.7066,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
124.0251,
|
||||
226,
|
||||
22.1287,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
287,
|
||||
34.6065,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.3102,
|
||||
287,
|
||||
31.3568,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
69.667,
|
||||
287,
|
||||
26.6515,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
96.3186,
|
||||
287,
|
||||
27.7066,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
124.0251,
|
||||
287,
|
||||
22.1287,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
348,
|
||||
34.6065,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.3102,
|
||||
348,
|
||||
31.3568,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
69.667,
|
||||
348,
|
||||
26.6515,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
96.3186,
|
||||
348,
|
||||
27.7066,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
124.0251,
|
||||
348,
|
||||
22.1287,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
409,
|
||||
34.6065,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.3102,
|
||||
409,
|
||||
31.3568,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
69.667,
|
||||
409,
|
||||
26.6515,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
96.3186,
|
||||
409,
|
||||
27.7066,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
124.0251,
|
||||
409,
|
||||
22.1287,
|
||||
61,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"768": {
|
||||
"name": "projects",
|
||||
"viewportWidth": 736,
|
||||
"width": 736,
|
||||
"height": 502,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
10.9099,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
30,
|
||||
10.9099,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
67,
|
||||
100,
|
||||
435,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
86,
|
||||
94.837,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
146,
|
||||
23.429,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
26.0105,
|
||||
146,
|
||||
21.2806,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.2911,
|
||||
146,
|
||||
18.1704,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.4615,
|
||||
146,
|
||||
17.6694,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
83.1309,
|
||||
146,
|
||||
14.2875,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
179,
|
||||
23.429,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
26.0105,
|
||||
179,
|
||||
21.2806,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.2911,
|
||||
179,
|
||||
18.1704,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.4615,
|
||||
179,
|
||||
17.6694,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
83.1309,
|
||||
179,
|
||||
14.2875,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
240,
|
||||
23.429,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
26.0105,
|
||||
240,
|
||||
21.2806,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.2911,
|
||||
240,
|
||||
18.1704,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.4615,
|
||||
240,
|
||||
17.6694,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
83.1309,
|
||||
240,
|
||||
14.2875,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
301,
|
||||
23.429,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
26.0105,
|
||||
301,
|
||||
21.2806,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.2911,
|
||||
301,
|
||||
18.1704,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.4615,
|
||||
301,
|
||||
17.6694,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
83.1309,
|
||||
301,
|
||||
14.2875,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
362,
|
||||
23.429,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
26.0105,
|
||||
362,
|
||||
21.2806,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.2911,
|
||||
362,
|
||||
18.1704,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.4615,
|
||||
362,
|
||||
17.6694,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
83.1309,
|
||||
362,
|
||||
14.2875,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
423,
|
||||
23.429,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
26.0105,
|
||||
423,
|
||||
21.2806,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.2911,
|
||||
423,
|
||||
18.1704,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.4615,
|
||||
423,
|
||||
17.6694,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
83.1309,
|
||||
423,
|
||||
14.2875,
|
||||
61,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"1280": {
|
||||
"name": "projects",
|
||||
"viewportWidth": 996,
|
||||
"width": 996,
|
||||
"height": 470,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
8.0619,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
30,
|
||||
8.0619,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
67,
|
||||
100,
|
||||
403,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
86,
|
||||
96.1847,
|
||||
36,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
138,
|
||||
24.4588,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
26.3664,
|
||||
138,
|
||||
22.4068,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.7732,
|
||||
138,
|
||||
19.4308,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
68.2041,
|
||||
138,
|
||||
17.2612,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
85.4653,
|
||||
138,
|
||||
12.6271,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
176,
|
||||
24.4588,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
26.3664,
|
||||
176,
|
||||
22.4068,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.7732,
|
||||
176,
|
||||
19.4308,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
68.2041,
|
||||
176,
|
||||
17.2612,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
85.4653,
|
||||
176,
|
||||
12.6271,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
231,
|
||||
24.4588,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
26.3664,
|
||||
231,
|
||||
22.4068,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.7732,
|
||||
231,
|
||||
19.4308,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
68.2041,
|
||||
231,
|
||||
17.2612,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
85.4653,
|
||||
231,
|
||||
12.6271,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
286,
|
||||
24.4588,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
26.3664,
|
||||
286,
|
||||
22.4068,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.7732,
|
||||
286,
|
||||
19.4308,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
68.2041,
|
||||
286,
|
||||
17.2612,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
85.4653,
|
||||
286,
|
||||
12.6271,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
341,
|
||||
24.4588,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
26.3664,
|
||||
341,
|
||||
22.4068,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.7732,
|
||||
341,
|
||||
19.4308,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
68.2041,
|
||||
341,
|
||||
17.2612,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
85.4653,
|
||||
341,
|
||||
12.6271,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
396,
|
||||
24.4588,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
26.3664,
|
||||
396,
|
||||
22.4068,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
48.7732,
|
||||
396,
|
||||
19.4308,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
68.2041,
|
||||
396,
|
||||
17.2612,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
85.4653,
|
||||
396,
|
||||
12.6271,
|
||||
55,
|
||||
0
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"_hash": "17f8285c3ca514ddef6d48c1183ed642"
|
||||
}
|
||||
@@ -1,50 +0,0 @@
|
||||
"use client"
|
||||
// Auto-generated by `npx boneyard-js build` — do not edit
|
||||
import { registerBones } from 'boneyard-js'
|
||||
import { configureBoneyard } from 'boneyard-js/react'
|
||||
|
||||
import _dash_sessions from './dash-sessions.bones.json'
|
||||
import _attendance_history_fund from './attendance-history-fund.bones.json'
|
||||
import _attendance_history_table from './attendance-history-table.bones.json'
|
||||
import _leave_requests from './leave-requests.bones.json'
|
||||
import _leave_approval from './leave-approval.bones.json'
|
||||
import _attendance_balances from './attendance-balances.bones.json'
|
||||
import _trips_history from './trips-history.bones.json'
|
||||
import _trips_admin from './trips-admin.bones.json'
|
||||
import _vehicles from './vehicles.bones.json'
|
||||
import _offers from './offers.bones.json'
|
||||
import _orders from './orders.bones.json'
|
||||
import _projects from './projects.bones.json'
|
||||
import _offers_customers from './offers-customers.bones.json'
|
||||
import _users from './users.bones.json'
|
||||
import _audit_log_rows from './audit-log-rows.bones.json'
|
||||
import _offer_detail from './offer-detail.bones.json'
|
||||
import _invoice_detail from './invoice-detail.bones.json'
|
||||
import _project_detail from './project-detail.bones.json'
|
||||
import _attendance_create from './attendance-create.bones.json'
|
||||
import _offers_templates from './offers-templates.bones.json'
|
||||
|
||||
configureBoneyard({"color":"#e0e0e0","animate":"shimmer","shimmerColor":"#f0f0f0","speed":"1.2s","shimmerAngle":110})
|
||||
|
||||
registerBones({
|
||||
"dash-sessions": _dash_sessions,
|
||||
"attendance-history-fund": _attendance_history_fund,
|
||||
"attendance-history-table": _attendance_history_table,
|
||||
"leave-requests": _leave_requests,
|
||||
"leave-approval": _leave_approval,
|
||||
"attendance-balances": _attendance_balances,
|
||||
"trips-history": _trips_history,
|
||||
"trips-admin": _trips_admin,
|
||||
"vehicles": _vehicles,
|
||||
"offers": _offers,
|
||||
"orders": _orders,
|
||||
"projects": _projects,
|
||||
"offers-customers": _offers_customers,
|
||||
"users": _users,
|
||||
"audit-log-rows": _audit_log_rows,
|
||||
"offer-detail": _offer_detail,
|
||||
"invoice-detail": _invoice_detail,
|
||||
"project-detail": _project_detail,
|
||||
"attendance-create": _attendance_create,
|
||||
"offers-templates": _offers_templates,
|
||||
})
|
||||
@@ -1,725 +0,0 @@
|
||||
{
|
||||
"breakpoints": {
|
||||
"375": {
|
||||
"name": "trips-admin",
|
||||
"viewportWidth": 317,
|
||||
"width": 317,
|
||||
"height": 437,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
22,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
26,
|
||||
100,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
61,
|
||||
100,
|
||||
376,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
4.1009,
|
||||
74,
|
||||
37.8795,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
41.9805,
|
||||
74,
|
||||
43.4592,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
85.4397,
|
||||
74,
|
||||
31.6739,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
117.1136,
|
||||
74,
|
||||
16.6108,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
133.7244,
|
||||
74,
|
||||
28.1053,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
4.1009,
|
||||
105,
|
||||
37.8795,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
41.9805,
|
||||
105,
|
||||
43.4592,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
85.4397,
|
||||
105,
|
||||
31.6739,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
117.1136,
|
||||
105,
|
||||
16.6108,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
133.7244,
|
||||
105,
|
||||
28.1053,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
4.1009,
|
||||
166,
|
||||
37.8795,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
41.9805,
|
||||
166,
|
||||
43.4592,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
85.4397,
|
||||
166,
|
||||
31.6739,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
117.1136,
|
||||
166,
|
||||
16.6108,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
133.7244,
|
||||
166,
|
||||
28.1053,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
4.1009,
|
||||
227,
|
||||
37.8795,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
41.9805,
|
||||
227,
|
||||
43.4592,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
85.4397,
|
||||
227,
|
||||
31.6739,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
117.1136,
|
||||
227,
|
||||
16.6108,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
133.7244,
|
||||
227,
|
||||
28.1053,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
4.1009,
|
||||
288,
|
||||
37.8795,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
41.9805,
|
||||
288,
|
||||
43.4592,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
85.4397,
|
||||
288,
|
||||
31.6739,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
117.1136,
|
||||
288,
|
||||
16.6108,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
133.7244,
|
||||
288,
|
||||
28.1053,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
4.1009,
|
||||
349,
|
||||
37.8795,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
41.9805,
|
||||
349,
|
||||
43.4592,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
85.4397,
|
||||
349,
|
||||
31.6739,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
117.1136,
|
||||
349,
|
||||
16.6108,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
133.7244,
|
||||
349,
|
||||
28.1053,
|
||||
61,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"768": {
|
||||
"name": "trips-admin",
|
||||
"viewportWidth": 690,
|
||||
"width": 690,
|
||||
"height": 442,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
16.3202,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
30,
|
||||
16.3202,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
67,
|
||||
100,
|
||||
375,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
2.7536,
|
||||
86,
|
||||
22.8057,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.5593,
|
||||
86,
|
||||
26.0711,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
51.6304,
|
||||
86,
|
||||
19.1757,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.8062,
|
||||
86,
|
||||
10.3601,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
81.1662,
|
||||
86,
|
||||
16.0802,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.7536,
|
||||
119,
|
||||
22.8057,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.5593,
|
||||
119,
|
||||
26.0711,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
51.6304,
|
||||
119,
|
||||
19.1757,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.8062,
|
||||
119,
|
||||
10.3601,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
81.1662,
|
||||
119,
|
||||
16.0802,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.7536,
|
||||
180,
|
||||
22.8057,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.5593,
|
||||
180,
|
||||
26.0711,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
51.6304,
|
||||
180,
|
||||
19.1757,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.8062,
|
||||
180,
|
||||
10.3601,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
81.1662,
|
||||
180,
|
||||
16.0802,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.7536,
|
||||
241,
|
||||
22.8057,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.5593,
|
||||
241,
|
||||
26.0711,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
51.6304,
|
||||
241,
|
||||
19.1757,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.8062,
|
||||
241,
|
||||
10.3601,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
81.1662,
|
||||
241,
|
||||
16.0802,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.7536,
|
||||
302,
|
||||
22.8057,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.5593,
|
||||
302,
|
||||
26.0711,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
51.6304,
|
||||
302,
|
||||
19.1757,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.8062,
|
||||
302,
|
||||
10.3601,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
81.1662,
|
||||
302,
|
||||
16.0802,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.7536,
|
||||
363,
|
||||
22.8057,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.5593,
|
||||
363,
|
||||
26.0711,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
51.6304,
|
||||
363,
|
||||
19.1757,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.8062,
|
||||
363,
|
||||
10.3601,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
81.1662,
|
||||
363,
|
||||
16.0802,
|
||||
61,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"1280": {
|
||||
"name": "trips-admin",
|
||||
"viewportWidth": 950,
|
||||
"width": 950,
|
||||
"height": 418,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
11.8536,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
30,
|
||||
11.8536,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
67,
|
||||
100,
|
||||
351,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
2,
|
||||
86,
|
||||
23.523,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.523,
|
||||
86,
|
||||
26.574,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
52.097,
|
||||
86,
|
||||
20.1382,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.2352,
|
||||
86,
|
||||
11.9046,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
84.1398,
|
||||
86,
|
||||
13.8602,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
2,
|
||||
124,
|
||||
23.523,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.523,
|
||||
124,
|
||||
26.574,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
52.097,
|
||||
124,
|
||||
20.1382,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.2352,
|
||||
124,
|
||||
11.9046,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
84.1398,
|
||||
124,
|
||||
13.8602,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
2,
|
||||
179,
|
||||
23.523,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.523,
|
||||
179,
|
||||
26.574,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
52.097,
|
||||
179,
|
||||
20.1382,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.2352,
|
||||
179,
|
||||
11.9046,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
84.1398,
|
||||
179,
|
||||
13.8602,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
2,
|
||||
234,
|
||||
23.523,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.523,
|
||||
234,
|
||||
26.574,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
52.097,
|
||||
234,
|
||||
20.1382,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.2352,
|
||||
234,
|
||||
11.9046,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
84.1398,
|
||||
234,
|
||||
13.8602,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
2,
|
||||
289,
|
||||
23.523,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.523,
|
||||
289,
|
||||
26.574,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
52.097,
|
||||
289,
|
||||
20.1382,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.2352,
|
||||
289,
|
||||
11.9046,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
84.1398,
|
||||
289,
|
||||
13.8602,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
2,
|
||||
344,
|
||||
23.523,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
25.523,
|
||||
344,
|
||||
26.574,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
52.097,
|
||||
344,
|
||||
20.1382,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
72.2352,
|
||||
344,
|
||||
11.9046,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
84.1398,
|
||||
344,
|
||||
13.8602,
|
||||
55,
|
||||
0
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"_hash": "39a325f430c84bb51960a684759a8f0c"
|
||||
}
|
||||
@@ -1,725 +0,0 @@
|
||||
{
|
||||
"breakpoints": {
|
||||
"375": {
|
||||
"name": "trips-history",
|
||||
"viewportWidth": 317,
|
||||
"width": 317,
|
||||
"height": 300,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
22,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
26,
|
||||
100,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
61,
|
||||
100,
|
||||
239,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
4.1009,
|
||||
74,
|
||||
35.2326,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
39.3336,
|
||||
74,
|
||||
40.4278,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
79.7614,
|
||||
74,
|
||||
29.4657,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
109.2271,
|
||||
74,
|
||||
37.1402,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
146.3673,
|
||||
74,
|
||||
15.4623,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
4.1009,
|
||||
105,
|
||||
35.2326,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
39.3336,
|
||||
105,
|
||||
40.4278,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
79.7614,
|
||||
105,
|
||||
29.4657,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
109.2271,
|
||||
105,
|
||||
37.1402,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
146.3673,
|
||||
105,
|
||||
15.4623,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
4.1009,
|
||||
138,
|
||||
35.2326,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
39.3336,
|
||||
138,
|
||||
40.4278,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
79.7614,
|
||||
138,
|
||||
29.4657,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
109.2271,
|
||||
138,
|
||||
37.1402,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
146.3673,
|
||||
138,
|
||||
15.4623,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
4.1009,
|
||||
172,
|
||||
35.2326,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
39.3336,
|
||||
172,
|
||||
40.4278,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
79.7614,
|
||||
172,
|
||||
29.4657,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
109.2271,
|
||||
172,
|
||||
37.1402,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
146.3673,
|
||||
172,
|
||||
15.4623,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
4.1009,
|
||||
205,
|
||||
35.2326,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
39.3336,
|
||||
205,
|
||||
40.4278,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
79.7614,
|
||||
205,
|
||||
29.4657,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
109.2271,
|
||||
205,
|
||||
37.1402,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
146.3673,
|
||||
205,
|
||||
15.4623,
|
||||
34,
|
||||
0
|
||||
],
|
||||
[
|
||||
4.1009,
|
||||
239,
|
||||
35.2326,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
39.3336,
|
||||
239,
|
||||
40.4278,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
79.7614,
|
||||
239,
|
||||
29.4657,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
109.2271,
|
||||
239,
|
||||
37.1402,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
146.3673,
|
||||
239,
|
||||
15.4623,
|
||||
33,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"768": {
|
||||
"name": "trips-history",
|
||||
"viewportWidth": 690,
|
||||
"width": 690,
|
||||
"height": 312,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
16.6033,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
30,
|
||||
16.6033,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
67,
|
||||
100,
|
||||
245,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
2.7536,
|
||||
86,
|
||||
21.0417,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
23.7953,
|
||||
86,
|
||||
24.0534,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.8487,
|
||||
86,
|
||||
17.6925,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.5412,
|
||||
86,
|
||||
22.1445,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.6857,
|
||||
86,
|
||||
9.5607,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.7536,
|
||||
119,
|
||||
21.0417,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
23.7953,
|
||||
119,
|
||||
24.0534,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.8487,
|
||||
119,
|
||||
17.6925,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.5412,
|
||||
119,
|
||||
22.1445,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.6857,
|
||||
119,
|
||||
9.5607,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.7536,
|
||||
154,
|
||||
21.0417,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
23.7953,
|
||||
154,
|
||||
24.0534,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.8487,
|
||||
154,
|
||||
17.6925,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.5412,
|
||||
154,
|
||||
22.1445,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.6857,
|
||||
154,
|
||||
9.5607,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.7536,
|
||||
189,
|
||||
21.0417,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
23.7953,
|
||||
189,
|
||||
24.0534,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.8487,
|
||||
189,
|
||||
17.6925,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.5412,
|
||||
189,
|
||||
22.1445,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.6857,
|
||||
189,
|
||||
9.5607,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.7536,
|
||||
224,
|
||||
21.0417,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
23.7953,
|
||||
224,
|
||||
24.0534,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.8487,
|
||||
224,
|
||||
17.6925,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.5412,
|
||||
224,
|
||||
22.1445,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.6857,
|
||||
224,
|
||||
9.5607,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.7536,
|
||||
259,
|
||||
21.0417,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
23.7953,
|
||||
259,
|
||||
24.0534,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.8487,
|
||||
259,
|
||||
17.6925,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.5412,
|
||||
259,
|
||||
22.1445,
|
||||
35,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.6857,
|
||||
259,
|
||||
9.5607,
|
||||
35,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"1280": {
|
||||
"name": "trips-history",
|
||||
"viewportWidth": 958,
|
||||
"width": 958,
|
||||
"height": 355,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
11.9585,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
30,
|
||||
11.9585,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
67,
|
||||
100,
|
||||
288,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
1.9833,
|
||||
86,
|
||||
21.1541,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
23.1374,
|
||||
86,
|
||||
23.8974,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.0348,
|
||||
86,
|
||||
18.1106,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.1455,
|
||||
86,
|
||||
22.1604,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.3059,
|
||||
86,
|
||||
10.7108,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9833,
|
||||
124,
|
||||
21.1541,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
23.1374,
|
||||
124,
|
||||
23.8974,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.0348,
|
||||
124,
|
||||
18.1106,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.1455,
|
||||
124,
|
||||
22.1604,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.3059,
|
||||
124,
|
||||
10.7108,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9833,
|
||||
167,
|
||||
21.1541,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
23.1374,
|
||||
167,
|
||||
23.8974,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.0348,
|
||||
167,
|
||||
18.1106,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.1455,
|
||||
167,
|
||||
22.1604,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.3059,
|
||||
167,
|
||||
10.7108,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9833,
|
||||
209,
|
||||
21.1541,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
23.1374,
|
||||
209,
|
||||
23.8974,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.0348,
|
||||
209,
|
||||
18.1106,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.1455,
|
||||
209,
|
||||
22.1604,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.3059,
|
||||
209,
|
||||
10.7108,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9833,
|
||||
252,
|
||||
21.1541,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
23.1374,
|
||||
252,
|
||||
23.8974,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.0348,
|
||||
252,
|
||||
18.1106,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.1455,
|
||||
252,
|
||||
22.1604,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.3059,
|
||||
252,
|
||||
10.7108,
|
||||
43,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9833,
|
||||
294,
|
||||
21.1541,
|
||||
42,
|
||||
0
|
||||
],
|
||||
[
|
||||
23.1374,
|
||||
294,
|
||||
23.8974,
|
||||
42,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.0348,
|
||||
294,
|
||||
18.1106,
|
||||
42,
|
||||
0
|
||||
],
|
||||
[
|
||||
65.1455,
|
||||
294,
|
||||
22.1604,
|
||||
42,
|
||||
0
|
||||
],
|
||||
[
|
||||
87.3059,
|
||||
294,
|
||||
10.7108,
|
||||
42,
|
||||
0
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"_hash": "6b54a0afbb4863895e318916b1fdca67"
|
||||
}
|
||||
@@ -1,767 +0,0 @@
|
||||
{
|
||||
"breakpoints": {
|
||||
"375": {
|
||||
"name": "users",
|
||||
"viewportWidth": 351,
|
||||
"width": 351,
|
||||
"height": 549,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
22,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
26,
|
||||
100,
|
||||
19,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
53,
|
||||
100,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
113,
|
||||
100,
|
||||
436,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
126,
|
||||
92.5926,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
186,
|
||||
37.362,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
41.0657,
|
||||
186,
|
||||
26.429,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
67.4947,
|
||||
186,
|
||||
36.1779,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
103.6725,
|
||||
186,
|
||||
23.62,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
127.2926,
|
||||
186,
|
||||
18.8613,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
217,
|
||||
37.362,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
41.0657,
|
||||
217,
|
||||
26.429,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
67.4947,
|
||||
217,
|
||||
36.1779,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
103.6725,
|
||||
217,
|
||||
23.62,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
127.2926,
|
||||
217,
|
||||
18.8613,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
278,
|
||||
37.362,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
41.0657,
|
||||
278,
|
||||
26.429,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
67.4947,
|
||||
278,
|
||||
36.1779,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
103.6725,
|
||||
278,
|
||||
23.62,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
127.2926,
|
||||
278,
|
||||
18.8613,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
339,
|
||||
37.362,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
41.0657,
|
||||
339,
|
||||
26.429,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
67.4947,
|
||||
339,
|
||||
36.1779,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
103.6725,
|
||||
339,
|
||||
23.62,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
127.2926,
|
||||
339,
|
||||
18.8613,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
400,
|
||||
37.362,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
41.0657,
|
||||
400,
|
||||
26.429,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
67.4947,
|
||||
400,
|
||||
36.1779,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
103.6725,
|
||||
400,
|
||||
23.62,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
127.2926,
|
||||
400,
|
||||
18.8613,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
461,
|
||||
37.362,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
41.0657,
|
||||
461,
|
||||
26.429,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
67.4947,
|
||||
461,
|
||||
36.1779,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
103.6725,
|
||||
461,
|
||||
23.62,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
127.2926,
|
||||
461,
|
||||
18.8613,
|
||||
61,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"768": {
|
||||
"name": "users",
|
||||
"viewportWidth": 736,
|
||||
"width": 736,
|
||||
"height": 502,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
12.6741,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
30,
|
||||
12.6741,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
81.2479,
|
||||
4,
|
||||
18.7521,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
67,
|
||||
100,
|
||||
435,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
86,
|
||||
94.837,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
146,
|
||||
24.3079,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
26.8894,
|
||||
146,
|
||||
18.6481,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
45.5375,
|
||||
146,
|
||||
23.5628,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
69.1003,
|
||||
146,
|
||||
15.6568,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
84.7571,
|
||||
146,
|
||||
12.6613,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
179,
|
||||
24.3079,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
26.8894,
|
||||
179,
|
||||
18.6481,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
45.5375,
|
||||
179,
|
||||
23.5628,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
69.1003,
|
||||
179,
|
||||
15.6568,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
84.7571,
|
||||
179,
|
||||
12.6613,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
240,
|
||||
24.3079,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
26.8894,
|
||||
240,
|
||||
18.6481,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
45.5375,
|
||||
240,
|
||||
23.5628,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
69.1003,
|
||||
240,
|
||||
15.6568,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
84.7571,
|
||||
240,
|
||||
12.6613,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
301,
|
||||
24.3079,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
26.8894,
|
||||
301,
|
||||
18.6481,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
45.5375,
|
||||
301,
|
||||
23.5628,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
69.1003,
|
||||
301,
|
||||
15.6568,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
84.7571,
|
||||
301,
|
||||
12.6613,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
362,
|
||||
24.3079,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
26.8894,
|
||||
362,
|
||||
18.6481,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
45.5375,
|
||||
362,
|
||||
23.5628,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
69.1003,
|
||||
362,
|
||||
15.6568,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
84.7571,
|
||||
362,
|
||||
12.6613,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
423,
|
||||
24.3079,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
26.8894,
|
||||
423,
|
||||
18.6481,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
45.5375,
|
||||
423,
|
||||
23.5628,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
69.1003,
|
||||
423,
|
||||
15.6568,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
84.7571,
|
||||
423,
|
||||
12.6613,
|
||||
61,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"1280": {
|
||||
"name": "users",
|
||||
"viewportWidth": 996,
|
||||
"width": 996,
|
||||
"height": 505,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
9.3656,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
30,
|
||||
9.3656,
|
||||
21,
|
||||
8
|
||||
],
|
||||
[
|
||||
86.5446,
|
||||
10,
|
||||
13.4554,
|
||||
32,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
67,
|
||||
100,
|
||||
438,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
86,
|
||||
96.1847,
|
||||
36,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
138,
|
||||
25.3655,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.2732,
|
||||
138,
|
||||
20.4302,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.7033,
|
||||
138,
|
||||
22.8571,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.5604,
|
||||
138,
|
||||
15.9011,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
86.4615,
|
||||
138,
|
||||
11.6309,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
176,
|
||||
25.3655,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.2732,
|
||||
176,
|
||||
20.4302,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.7033,
|
||||
176,
|
||||
22.8571,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.5604,
|
||||
176,
|
||||
15.9011,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
86.4615,
|
||||
176,
|
||||
11.6309,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
238,
|
||||
25.3655,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.2732,
|
||||
238,
|
||||
20.4302,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.7033,
|
||||
238,
|
||||
22.8571,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.5604,
|
||||
238,
|
||||
15.9011,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
86.4615,
|
||||
238,
|
||||
11.6309,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
300,
|
||||
25.3655,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.2732,
|
||||
300,
|
||||
20.4302,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.7033,
|
||||
300,
|
||||
22.8571,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.5604,
|
||||
300,
|
||||
15.9011,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
86.4615,
|
||||
300,
|
||||
11.6309,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
362,
|
||||
25.3655,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.2732,
|
||||
362,
|
||||
20.4302,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.7033,
|
||||
362,
|
||||
22.8571,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.5604,
|
||||
362,
|
||||
15.9011,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
86.4615,
|
||||
362,
|
||||
11.6309,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
424,
|
||||
25.3655,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.2732,
|
||||
424,
|
||||
20.4302,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
47.7033,
|
||||
424,
|
||||
22.8571,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
70.5604,
|
||||
424,
|
||||
15.9011,
|
||||
62,
|
||||
0
|
||||
],
|
||||
[
|
||||
86.4615,
|
||||
424,
|
||||
11.6309,
|
||||
62,
|
||||
0
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"_hash": "53e8df6c8f8bf975b3b88bfca3bbd804"
|
||||
}
|
||||
@@ -1,746 +0,0 @@
|
||||
{
|
||||
"breakpoints": {
|
||||
"375": {
|
||||
"name": "vehicles",
|
||||
"viewportWidth": 351,
|
||||
"width": 351,
|
||||
"height": 530,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
0,
|
||||
100,
|
||||
22,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
34,
|
||||
100,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
94,
|
||||
100,
|
||||
436,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
107,
|
||||
92.5926,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
167,
|
||||
23.9583,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.662,
|
||||
167,
|
||||
24.4168,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
52.0789,
|
||||
167,
|
||||
29.042,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
81.1209,
|
||||
167,
|
||||
18.8435,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
99.9644,
|
||||
167,
|
||||
46.1895,
|
||||
31,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
197,
|
||||
23.9583,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.662,
|
||||
197,
|
||||
24.4168,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
52.0789,
|
||||
197,
|
||||
29.042,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
81.1209,
|
||||
197,
|
||||
18.8435,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
99.9644,
|
||||
197,
|
||||
46.1895,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
258,
|
||||
23.9583,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.662,
|
||||
258,
|
||||
24.4168,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
52.0789,
|
||||
258,
|
||||
29.042,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
81.1209,
|
||||
258,
|
||||
18.8435,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
99.9644,
|
||||
258,
|
||||
46.1895,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
319,
|
||||
23.9583,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.662,
|
||||
319,
|
||||
24.4168,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
52.0789,
|
||||
319,
|
||||
29.042,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
81.1209,
|
||||
319,
|
||||
18.8435,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
99.9644,
|
||||
319,
|
||||
46.1895,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
380,
|
||||
23.9583,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.662,
|
||||
380,
|
||||
24.4168,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
52.0789,
|
||||
380,
|
||||
29.042,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
81.1209,
|
||||
380,
|
||||
18.8435,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
99.9644,
|
||||
380,
|
||||
46.1895,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
3.7037,
|
||||
441,
|
||||
23.9583,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
27.662,
|
||||
441,
|
||||
24.4168,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
52.0789,
|
||||
441,
|
||||
29.042,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
81.1209,
|
||||
441,
|
||||
18.8435,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
99.9644,
|
||||
441,
|
||||
46.1895,
|
||||
61,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"768": {
|
||||
"name": "vehicles",
|
||||
"viewportWidth": 736,
|
||||
"width": 736,
|
||||
"height": 495,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
7,
|
||||
10.1478,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
82.6427,
|
||||
0,
|
||||
17.3573,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
60,
|
||||
100,
|
||||
435,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
79,
|
||||
94.837,
|
||||
44,
|
||||
8
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
139,
|
||||
16.4126,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
18.9941,
|
||||
139,
|
||||
16.5039,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.498,
|
||||
139,
|
||||
19.5058,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
55.0038,
|
||||
139,
|
||||
12.8843,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
67.8881,
|
||||
139,
|
||||
29.5304,
|
||||
33,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
172,
|
||||
16.4126,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
18.9941,
|
||||
172,
|
||||
16.5039,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.498,
|
||||
172,
|
||||
19.5058,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
55.0038,
|
||||
172,
|
||||
12.8843,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
67.8881,
|
||||
172,
|
||||
29.5304,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
233,
|
||||
16.4126,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
18.9941,
|
||||
233,
|
||||
16.5039,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.498,
|
||||
233,
|
||||
19.5058,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
55.0038,
|
||||
233,
|
||||
12.8843,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
67.8881,
|
||||
233,
|
||||
29.5304,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
294,
|
||||
16.4126,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
18.9941,
|
||||
294,
|
||||
16.5039,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.498,
|
||||
294,
|
||||
19.5058,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
55.0038,
|
||||
294,
|
||||
12.8843,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
67.8881,
|
||||
294,
|
||||
29.5304,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
355,
|
||||
16.4126,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
18.9941,
|
||||
355,
|
||||
16.5039,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.498,
|
||||
355,
|
||||
19.5058,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
55.0038,
|
||||
355,
|
||||
12.8843,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
67.8881,
|
||||
355,
|
||||
29.5304,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
2.5815,
|
||||
416,
|
||||
16.4126,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
18.9941,
|
||||
416,
|
||||
16.5039,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
35.498,
|
||||
416,
|
||||
19.5058,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
55.0038,
|
||||
416,
|
||||
12.8843,
|
||||
61,
|
||||
0
|
||||
],
|
||||
[
|
||||
67.8881,
|
||||
416,
|
||||
29.5304,
|
||||
61,
|
||||
0
|
||||
]
|
||||
]
|
||||
},
|
||||
"1280": {
|
||||
"name": "vehicles",
|
||||
"viewportWidth": 996,
|
||||
"width": 996,
|
||||
"height": 451,
|
||||
"bones": [
|
||||
[
|
||||
0,
|
||||
1,
|
||||
7.4987,
|
||||
26,
|
||||
8
|
||||
],
|
||||
[
|
||||
87.5753,
|
||||
0,
|
||||
12.4247,
|
||||
32,
|
||||
8
|
||||
],
|
||||
[
|
||||
0,
|
||||
48,
|
||||
100,
|
||||
403,
|
||||
10,
|
||||
true
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
67,
|
||||
96.1847,
|
||||
36,
|
||||
8
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
119,
|
||||
18.3531,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
20.2607,
|
||||
119,
|
||||
18.2762,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.537,
|
||||
119,
|
||||
21.1785,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
59.7154,
|
||||
119,
|
||||
14.7841,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
74.4996,
|
||||
119,
|
||||
23.5928,
|
||||
38,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
157,
|
||||
18.3531,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
20.2607,
|
||||
157,
|
||||
18.2762,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.537,
|
||||
157,
|
||||
21.1785,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
59.7154,
|
||||
157,
|
||||
14.7841,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
74.4996,
|
||||
157,
|
||||
23.5928,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
212,
|
||||
18.3531,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
20.2607,
|
||||
212,
|
||||
18.2762,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.537,
|
||||
212,
|
||||
21.1785,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
59.7154,
|
||||
212,
|
||||
14.7841,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
74.4996,
|
||||
212,
|
||||
23.5928,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
267,
|
||||
18.3531,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
20.2607,
|
||||
267,
|
||||
18.2762,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.537,
|
||||
267,
|
||||
21.1785,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
59.7154,
|
||||
267,
|
||||
14.7841,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
74.4996,
|
||||
267,
|
||||
23.5928,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
322,
|
||||
18.3531,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
20.2607,
|
||||
322,
|
||||
18.2762,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.537,
|
||||
322,
|
||||
21.1785,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
59.7154,
|
||||
322,
|
||||
14.7841,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
74.4996,
|
||||
322,
|
||||
23.5928,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
1.9076,
|
||||
377,
|
||||
18.3531,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
20.2607,
|
||||
377,
|
||||
18.2762,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
38.537,
|
||||
377,
|
||||
21.1785,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
59.7154,
|
||||
377,
|
||||
14.7841,
|
||||
55,
|
||||
0
|
||||
],
|
||||
[
|
||||
74.4996,
|
||||
377,
|
||||
23.5928,
|
||||
55,
|
||||
0
|
||||
]
|
||||
]
|
||||
}
|
||||
},
|
||||
"_hash": "567bad6080dc9ba9767c6e40a88559b9"
|
||||
}
|
||||
@@ -41,6 +41,11 @@
|
||||
}
|
||||
}
|
||||
|
||||
/* Danger card — highlighted border for alert/important cards */
|
||||
.admin-card-danger {
|
||||
border: 2px solid var(--danger);
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
Badges
|
||||
============================================================================ */
|
||||
@@ -123,6 +128,16 @@
|
||||
color: var(--danger);
|
||||
}
|
||||
|
||||
.admin-badge-incoming {
|
||||
background: var(--success-soft);
|
||||
color: var(--success);
|
||||
}
|
||||
|
||||
.admin-badge-outgoing {
|
||||
background: var(--info-soft);
|
||||
color: var(--info);
|
||||
}
|
||||
|
||||
/* Status Badges - Leave Requests */
|
||||
.badge-pending {
|
||||
background: color-mix(in srgb, var(--warning) 15%, transparent);
|
||||
@@ -716,6 +731,7 @@
|
||||
.admin-kpi-grid {
|
||||
display: grid;
|
||||
gap: 0.875rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.admin-kpi-4 {
|
||||
@@ -923,3 +939,163 @@
|
||||
max-height: 80px;
|
||||
object-fit: contain;
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
Search Bar & Filters
|
||||
============================================================================ */
|
||||
|
||||
.admin-search-bar {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
gap: 0.5rem;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.admin-search-bar .admin-form-input,
|
||||
.admin-search-bar .admin-form-select {
|
||||
flex: 1 1 140px;
|
||||
min-width: 140px;
|
||||
max-width: 280px;
|
||||
}
|
||||
|
||||
.admin-search-bar .react-datepicker-wrapper {
|
||||
flex: 1 1 140px;
|
||||
min-width: 140px;
|
||||
max-width: 280px;
|
||||
}
|
||||
|
||||
.admin-search-bar .admin-btn {
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.admin-search {
|
||||
position: relative;
|
||||
flex: 1 1 200px;
|
||||
min-width: 180px;
|
||||
max-width: 320px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.admin-search svg {
|
||||
position: absolute;
|
||||
left: 10px;
|
||||
color: var(--text-muted);
|
||||
pointer-events: none;
|
||||
}
|
||||
|
||||
.admin-search .admin-form-input {
|
||||
padding-left: 32px;
|
||||
}
|
||||
|
||||
@media (max-width: 768px) {
|
||||
.admin-search-bar {
|
||||
flex-direction: column;
|
||||
align-items: stretch;
|
||||
}
|
||||
|
||||
.admin-search-bar .admin-form-input,
|
||||
.admin-search-bar .admin-form-select {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.admin-search-bar .react-datepicker-wrapper {
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.admin-search {
|
||||
max-width: 100%;
|
||||
flex: 1 1 100%;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.admin-search-bar .admin-form-input,
|
||||
.admin-search-bar .admin-form-select {
|
||||
min-width: 100%;
|
||||
}
|
||||
|
||||
.admin-search-bar .react-datepicker-wrapper {
|
||||
min-width: 100%;
|
||||
}
|
||||
}
|
||||
|
||||
/* ============================================================================
|
||||
Item Picker (Warehouse)
|
||||
============================================================================ */
|
||||
|
||||
.admin-item-picker-list {
|
||||
position: absolute;
|
||||
top: 100%;
|
||||
left: 0;
|
||||
right: 0;
|
||||
z-index: 100;
|
||||
max-height: 240px;
|
||||
overflow-y: auto;
|
||||
overscroll-behavior: contain;
|
||||
background: var(--bg-primary);
|
||||
border: 1px solid var(--border-color);
|
||||
border-top: none;
|
||||
border-radius: 0 0 var(--border-radius-sm) var(--border-radius-sm);
|
||||
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
|
||||
padding: 4px 0;
|
||||
margin: 0;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.admin-item-picker-list::-webkit-scrollbar {
|
||||
width: 5px;
|
||||
}
|
||||
|
||||
.admin-item-picker-list::-webkit-scrollbar-track {
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.admin-item-picker-list::-webkit-scrollbar-thumb {
|
||||
background: var(--border-color);
|
||||
border-radius: 99px;
|
||||
}
|
||||
|
||||
.admin-item-picker-list::-webkit-scrollbar-thumb:hover {
|
||||
background: var(--text-muted);
|
||||
}
|
||||
|
||||
.admin-item-picker-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
gap: 0.5rem;
|
||||
padding: 8px 12px;
|
||||
cursor: pointer;
|
||||
transition: background var(--transition);
|
||||
border-radius: 4px;
|
||||
margin: 0 4px;
|
||||
}
|
||||
|
||||
.admin-item-picker-item:hover,
|
||||
.admin-item-picker-item.active {
|
||||
background: var(--bg-secondary);
|
||||
}
|
||||
|
||||
.admin-item-picker-name {
|
||||
font-size: 13px;
|
||||
font-weight: 500;
|
||||
color: var(--text-primary);
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
min-width: 0;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.admin-item-picker-number {
|
||||
font-size: 11.5px;
|
||||
color: var(--text-tertiary);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
.admin-item-picker-qty {
|
||||
font-size: 11.5px;
|
||||
color: var(--text-secondary);
|
||||
white-space: nowrap;
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { forwardRef, useMemo } from "react";
|
||||
import { forwardRef } from "react";
|
||||
import DatePicker, { registerLocale } from "react-datepicker";
|
||||
import { cs } from "date-fns/locale";
|
||||
import { parse, format } from "date-fns";
|
||||
@@ -124,7 +124,7 @@ export default function AdminDatePicker({
|
||||
disabled,
|
||||
placeholder,
|
||||
}: AdminDatePickerProps) {
|
||||
const useNative = useMemo(() => isTouchDevice(), []);
|
||||
const useNative = isTouchDevice();
|
||||
|
||||
if (useNative) {
|
||||
return (
|
||||
@@ -178,15 +178,12 @@ export default function AdminDatePicker({
|
||||
return undefined;
|
||||
};
|
||||
|
||||
const customInput = useMemo(
|
||||
() => (
|
||||
<CustomInput
|
||||
required={required}
|
||||
placeholder={placeholder}
|
||||
disabled={disabled}
|
||||
/>
|
||||
),
|
||||
[required, placeholder, disabled],
|
||||
const customInput = (
|
||||
<CustomInput
|
||||
required={required}
|
||||
placeholder={placeholder}
|
||||
disabled={disabled}
|
||||
/>
|
||||
);
|
||||
|
||||
const commonProps = {
|
||||
@@ -194,6 +191,7 @@ export default function AdminDatePicker({
|
||||
onChange: handleChange,
|
||||
locale: "cs",
|
||||
customInput,
|
||||
placeholderText: placeholder,
|
||||
minDate: parseMinMax(minDate),
|
||||
maxDate: parseMinMax(maxDate),
|
||||
popperPlacement: "bottom-start" as const,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Link } from "react-router-dom";
|
||||
import { Link } from "react-router-dom";
|
||||
import {
|
||||
formatDate,
|
||||
formatDatetime,
|
||||
@@ -8,34 +8,13 @@ import {
|
||||
getLeaveTypeName,
|
||||
getLeaveTypeBadgeClass,
|
||||
} from "../utils/attendanceHelpers";
|
||||
import type { AttendanceRecord as HookAttendanceRecord } from "../hooks/useAttendanceAdmin";
|
||||
|
||||
interface ProjectLog {
|
||||
id?: number;
|
||||
project_id?: number;
|
||||
project_name?: string;
|
||||
started_at?: string;
|
||||
ended_at?: string | null;
|
||||
hours?: string | number | null;
|
||||
minutes?: string | number | null;
|
||||
}
|
||||
|
||||
interface AttendanceRecord {
|
||||
id: number;
|
||||
shift_date: string;
|
||||
user_name: string;
|
||||
leave_type?: string;
|
||||
leave_hours?: number;
|
||||
arrival_time?: string | null;
|
||||
departure_time?: string | null;
|
||||
break_start?: string | null;
|
||||
break_end?: string | null;
|
||||
interface AttendanceRecord extends HookAttendanceRecord {
|
||||
arrival_lat?: number | string | null;
|
||||
arrival_lng?: number | string | null;
|
||||
departure_lat?: number | string | null;
|
||||
departure_lng?: number | string | null;
|
||||
project_name?: string;
|
||||
project_logs?: ProjectLog[];
|
||||
notes?: string | null;
|
||||
}
|
||||
|
||||
interface AttendanceShiftTableProps {
|
||||
@@ -51,7 +30,7 @@ function formatBreak(record: AttendanceRecord): string {
|
||||
if (record.break_start) {
|
||||
return `${formatTime(record.break_start)} - ?`;
|
||||
}
|
||||
return "\u2014";
|
||||
return "—";
|
||||
}
|
||||
|
||||
function renderProjectCell(record: AttendanceRecord): React.ReactNode {
|
||||
@@ -97,7 +76,7 @@ function renderProjectCell(record: AttendanceRecord): React.ReactNode {
|
||||
>
|
||||
{log.project_name || `#${log.project_id}`}{" "}
|
||||
{durationValid
|
||||
? `(${h}:${String(m).padStart(2, "0")}h${isActive ? " \u25B8" : ""})`
|
||||
? `(${h}:${String(m).padStart(2, "0")}h${isActive ? " ▸" : ""})`
|
||||
: "—"}
|
||||
</span>
|
||||
);
|
||||
@@ -115,7 +94,7 @@ function renderProjectCell(record: AttendanceRecord): React.ReactNode {
|
||||
</span>
|
||||
);
|
||||
}
|
||||
return "\u2014";
|
||||
return "—";
|
||||
}
|
||||
|
||||
export default function AttendanceShiftTable({
|
||||
@@ -156,7 +135,10 @@ export default function AttendanceShiftTable({
|
||||
const workMinutes = isLeave
|
||||
? (record.leave_hours != null ? Number(record.leave_hours) : 8) *
|
||||
60
|
||||
: calculateWorkMinutes(record);
|
||||
: calculateWorkMinutes({
|
||||
...record,
|
||||
notes: record.notes ?? undefined,
|
||||
});
|
||||
const hasLocation =
|
||||
(record.arrival_lat && record.arrival_lng) ||
|
||||
(record.departure_lat && record.departure_lng);
|
||||
@@ -173,18 +155,16 @@ export default function AttendanceShiftTable({
|
||||
</span>
|
||||
</td>
|
||||
<td className="admin-mono">
|
||||
{isLeave ? "\u2014" : formatDatetime(record.arrival_time)}
|
||||
{isLeave ? "—" : formatDatetime(record.arrival_time)}
|
||||
</td>
|
||||
<td className="admin-mono">
|
||||
{isLeave ? "\u2014" : formatBreak(record)}
|
||||
{isLeave ? "—" : formatBreak(record)}
|
||||
</td>
|
||||
<td className="admin-mono">
|
||||
{isLeave ? "\u2014" : formatDatetime(record.departure_time)}
|
||||
{isLeave ? "—" : formatDatetime(record.departure_time)}
|
||||
</td>
|
||||
<td className="admin-mono">
|
||||
{workMinutes > 0
|
||||
? `${formatMinutes(workMinutes)} h`
|
||||
: "\u2014"}
|
||||
{workMinutes > 0 ? `${formatMinutes(workMinutes)} h` : "—"}
|
||||
</td>
|
||||
<td>{renderProjectCell(record)}</td>
|
||||
<td>
|
||||
@@ -195,10 +175,10 @@ export default function AttendanceShiftTable({
|
||||
title="Zobrazit polohu"
|
||||
aria-label="Zobrazit polohu"
|
||||
>
|
||||
<span aria-hidden="true">{"\uD83D\uDCCD"}</span>
|
||||
<span aria-hidden="true">{"📍"}</span>
|
||||
</Link>
|
||||
) : (
|
||||
"\u2014"
|
||||
"—"
|
||||
)}
|
||||
</td>
|
||||
<td
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import type { ReactNode } from "react";
|
||||
import { useEffect, type ReactNode } from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
|
||||
interface ConfirmModalProps {
|
||||
@@ -91,6 +91,19 @@ export default function ConfirmModal({
|
||||
confirmVariant,
|
||||
loading,
|
||||
}: ConfirmModalProps) {
|
||||
useEffect(() => {
|
||||
if (!isOpen) return;
|
||||
|
||||
function handleKeyDown(e: KeyboardEvent) {
|
||||
if (e.key === "Escape" && !loading) {
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("keydown", handleKeyDown);
|
||||
return () => window.removeEventListener("keydown", handleKeyDown);
|
||||
}, [isOpen, loading, onClose]);
|
||||
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{isOpen && (
|
||||
|
||||
118
src/admin/components/FormModal.tsx
Normal file
118
src/admin/components/FormModal.tsx
Normal file
@@ -0,0 +1,118 @@
|
||||
import { useEffect, type ReactNode, type FormEvent } from "react";
|
||||
import { motion, AnimatePresence } from "framer-motion";
|
||||
import useModalLock from "../hooks/useModalLock";
|
||||
|
||||
export interface FormModalProps {
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
onSubmit?: () => void; // called when user clicks primary button (only if provided)
|
||||
title: string;
|
||||
children: ReactNode; // modal body (form fields)
|
||||
submitLabel?: string; // primary button text
|
||||
cancelLabel?: string; // cancel button text
|
||||
loading?: boolean;
|
||||
hideFooter?: boolean; // for "view-only" modals
|
||||
size?: "sm" | "md" | "lg"; // optional
|
||||
closeOnBackdrop?: boolean; // default true
|
||||
closeOnEsc?: boolean; // default true
|
||||
}
|
||||
|
||||
export default function FormModal({
|
||||
isOpen,
|
||||
onClose,
|
||||
onSubmit,
|
||||
title,
|
||||
children,
|
||||
submitLabel = "Uložit",
|
||||
cancelLabel = "Zrušit",
|
||||
loading = false,
|
||||
hideFooter = false,
|
||||
size = "md",
|
||||
closeOnBackdrop = true,
|
||||
closeOnEsc = true,
|
||||
}: FormModalProps) {
|
||||
useModalLock(isOpen);
|
||||
|
||||
useEffect(() => {
|
||||
if (!isOpen || !closeOnEsc) return;
|
||||
|
||||
function handleKeyDown(e: KeyboardEvent) {
|
||||
if (e.key === "Escape" && !loading) {
|
||||
onClose();
|
||||
}
|
||||
}
|
||||
|
||||
window.addEventListener("keydown", handleKeyDown);
|
||||
return () => window.removeEventListener("keydown", handleKeyDown);
|
||||
}, [isOpen, closeOnEsc, loading, onClose]);
|
||||
|
||||
const handleBackdropClick = () => {
|
||||
if (closeOnBackdrop && !loading) onClose();
|
||||
};
|
||||
|
||||
const handlePrimaryClick = (e: FormEvent) => {
|
||||
e.preventDefault();
|
||||
if (onSubmit) onSubmit();
|
||||
};
|
||||
|
||||
const titleId = "form-modal-title";
|
||||
const modalClassName =
|
||||
size === "lg" ? "admin-modal admin-modal-lg" : "admin-modal";
|
||||
|
||||
return (
|
||||
<AnimatePresence>
|
||||
{isOpen && (
|
||||
<motion.div
|
||||
className="admin-modal-overlay"
|
||||
initial={{ opacity: 0 }}
|
||||
animate={{ opacity: 1 }}
|
||||
exit={{ opacity: 0 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
>
|
||||
<div className="admin-modal-backdrop" onClick={handleBackdropClick} />
|
||||
<motion.div
|
||||
className={modalClassName}
|
||||
role="dialog"
|
||||
aria-modal="true"
|
||||
aria-labelledby={titleId}
|
||||
initial={{ opacity: 0, scale: 0.95, y: 20 }}
|
||||
animate={{ opacity: 1, scale: 1, y: 0 }}
|
||||
exit={{ opacity: 0, scale: 0.95, y: 20 }}
|
||||
transition={{ duration: 0.2 }}
|
||||
>
|
||||
<div className="admin-modal-header">
|
||||
<h2 id={titleId} className="admin-modal-title">
|
||||
{title}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div className="admin-modal-body">{children}</div>
|
||||
|
||||
{!hideFooter && (
|
||||
<div className="admin-modal-footer">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => !loading && onClose()}
|
||||
className="admin-btn admin-btn-secondary"
|
||||
disabled={loading}
|
||||
>
|
||||
{cancelLabel}
|
||||
</button>
|
||||
{onSubmit && (
|
||||
<button
|
||||
type="button"
|
||||
onClick={handlePrimaryClick}
|
||||
className="admin-btn admin-btn-primary"
|
||||
disabled={loading}
|
||||
>
|
||||
{loading ? "Zpracování..." : submitLabel}
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
</motion.div>
|
||||
</motion.div>
|
||||
)}
|
||||
</AnimatePresence>
|
||||
);
|
||||
}
|
||||
@@ -4,8 +4,6 @@ import { projectFilesOptions } from "../lib/queries/projects";
|
||||
import { useAlert } from "../context/AlertContext";
|
||||
import ConfirmModal from "./ConfirmModal";
|
||||
import apiFetch from "../utils/api";
|
||||
import { Skeleton } from "boneyard-js/react";
|
||||
import ProjectFileManagerFixture from "../fixtures/ProjectFileManagerFixture";
|
||||
|
||||
const API_BASE = "/api/admin";
|
||||
|
||||
@@ -472,13 +470,9 @@ export default function ProjectFileManager({
|
||||
|
||||
if (filesLoading && items.length === 0 && !errorMessage) {
|
||||
return (
|
||||
<Skeleton
|
||||
name="project-file-manager"
|
||||
loading={filesLoading && items.length === 0}
|
||||
fixture={<ProjectFileManagerFixture />}
|
||||
>
|
||||
<div />
|
||||
</Skeleton>
|
||||
<div className="admin-loading">
|
||||
<div className="admin-spinner" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -99,11 +99,8 @@ export default function RichEditor({
|
||||
useLayoutEffect(() => {
|
||||
if (!quillRef.current) return;
|
||||
const editor = quillRef.current.getEditor();
|
||||
editor.format("font", "tahoma");
|
||||
editor.format("size", "14px");
|
||||
// Quill auto-focuses on mount with existing content, which scrolls
|
||||
// the page to the editor. Blur to prevent unwanted scroll.
|
||||
editor.blur();
|
||||
editor.root.style.fontFamily = "Tahoma, sans-serif";
|
||||
editor.root.style.fontSize = "14px";
|
||||
}, []);
|
||||
|
||||
return (
|
||||
|
||||
@@ -85,7 +85,15 @@ export interface ShiftFormModalProps {
|
||||
|
||||
function ProjectTimeStatus({ form, projectLogs }: ProjectTimeStatusProps) {
|
||||
const totalWork = calcFormWorkMinutes(form);
|
||||
const totalProject = calcProjectMinutesTotal(projectLogs);
|
||||
const totalProject = calcProjectMinutesTotal(
|
||||
projectLogs.map((l) => ({
|
||||
...l,
|
||||
project_id:
|
||||
l.project_id !== "" && l.project_id != null
|
||||
? Number(l.project_id)
|
||||
: undefined,
|
||||
})),
|
||||
);
|
||||
const remaining = totalWork - totalProject;
|
||||
const hasLogs = projectLogs.some((l) => l.project_id);
|
||||
|
||||
@@ -329,7 +337,6 @@ export default function ShiftFormModal({
|
||||
<option value="work">Práce</option>
|
||||
<option value="vacation">Dovolená</option>
|
||||
<option value="sick">Nemoc</option>
|
||||
<option value="holiday">Svátek</option>
|
||||
<option value="unpaid">Neplacené volno</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
@@ -116,7 +116,7 @@ const menuSections: MenuSection[] = [
|
||||
{
|
||||
path: "/attendance/admin",
|
||||
label: "Správa",
|
||||
permission: "attendance.admin",
|
||||
permission: "attendance.manage",
|
||||
matchPrefix: "/attendance/admin",
|
||||
matchAlso: ["/attendance/create", "/attendance/location"],
|
||||
icon: (
|
||||
@@ -198,7 +198,7 @@ const menuSections: MenuSection[] = [
|
||||
{
|
||||
path: "/trips/admin",
|
||||
label: "Správa",
|
||||
permission: "trips.admin",
|
||||
permission: "trips.manage",
|
||||
icon: (
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
@@ -221,7 +221,7 @@ const menuSections: MenuSection[] = [
|
||||
{
|
||||
path: "/vehicles",
|
||||
label: "Vozidla",
|
||||
permission: "trips.vehicles",
|
||||
permission: "vehicles.manage",
|
||||
icon: (
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
@@ -315,7 +315,202 @@ const menuSections: MenuSection[] = [
|
||||
{
|
||||
path: "/offers/customers",
|
||||
label: "Zákazníci",
|
||||
permission: "offers.view",
|
||||
permission: "customers.view",
|
||||
icon: (
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2" />
|
||||
<circle cx="9" cy="7" r="4" />
|
||||
<path d="M23 21v-2a4 4 0 0 0-3-3.87" />
|
||||
<path d="M16 3.13a4 4 0 0 1 0 7.75" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
label: "Sklad",
|
||||
items: [
|
||||
{
|
||||
path: "/warehouse",
|
||||
label: "Přehled",
|
||||
permission: "warehouse.view",
|
||||
end: true,
|
||||
icon: (
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z" />
|
||||
<polyline points="3.27 6.96 12 12.01 20.73 6.96" />
|
||||
<line x1="12" y1="22.08" x2="12" y2="12" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "/warehouse/items",
|
||||
label: "Položky",
|
||||
permission: "warehouse.view",
|
||||
matchPrefix: "/warehouse/items",
|
||||
icon: (
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<path d="M21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16z" />
|
||||
<polyline points="3.27 6.96 12 12.01 20.73 6.96" />
|
||||
<line x1="12" y1="22.08" x2="12" y2="12" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "/warehouse/receipts",
|
||||
label: "Příjmy",
|
||||
permission: "warehouse.operate",
|
||||
matchPrefix: "/warehouse/receipts",
|
||||
icon: (
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<polyline points="17 11 12 6 7 11" />
|
||||
<line x1="12" y1="6" x2="12" y2="18" />
|
||||
<path d="M5 19h14" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "/warehouse/issues",
|
||||
label: "Výdeje",
|
||||
permission: "warehouse.operate",
|
||||
matchPrefix: "/warehouse/issues",
|
||||
icon: (
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<polyline points="7 13 12 18 17 13" />
|
||||
<line x1="12" y1="18" x2="12" y2="6" />
|
||||
<path d="M5 5h14" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "/warehouse/reservations",
|
||||
label: "Rezervace",
|
||||
permission: "warehouse.operate",
|
||||
matchPrefix: "/warehouse/reservations",
|
||||
icon: (
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<path d="M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" />
|
||||
<circle cx="9" cy="7" r="4" />
|
||||
<line x1="19" y1="8" x2="19" y2="14" />
|
||||
<line x1="22" y1="11" x2="16" y2="11" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "/warehouse/inventory",
|
||||
label: "Inventura",
|
||||
permission: "warehouse.inventory",
|
||||
matchPrefix: "/warehouse/inventory",
|
||||
icon: (
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<path d="M9 11l3 3L22 4" />
|
||||
<path d="M21 12v7a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h11" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "/warehouse/reports",
|
||||
label: "Reporty",
|
||||
permission: "warehouse.view",
|
||||
end: true,
|
||||
icon: (
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<line x1="18" y1="20" x2="18" y2="10" />
|
||||
<line x1="12" y1="20" x2="12" y2="4" />
|
||||
<line x1="6" y1="20" x2="6" y2="14" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "/warehouse/categories",
|
||||
label: "Kategorie",
|
||||
permission: "warehouse.manage",
|
||||
matchPrefix: "/warehouse/categories",
|
||||
icon: (
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<line x1="4" y1="21" x2="4" y2="14" />
|
||||
<line x1="4" y1="10" x2="4" y2="3" />
|
||||
<line x1="12" y1="21" x2="12" y2="12" />
|
||||
<line x1="12" y1="8" x2="12" y2="3" />
|
||||
<line x1="20" y1="21" x2="20" y2="16" />
|
||||
<line x1="20" y1="12" x2="20" y2="3" />
|
||||
<line x1="1" y1="14" x2="7" y2="14" />
|
||||
<line x1="9" y1="8" x2="15" y2="8" />
|
||||
<line x1="17" y1="16" x2="23" y2="16" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "/warehouse/locations",
|
||||
label: "Lokace",
|
||||
permission: "warehouse.manage",
|
||||
matchPrefix: "/warehouse/locations",
|
||||
icon: (
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<rect x="3" y="3" width="7" height="7" rx="1" />
|
||||
<rect x="14" y="3" width="7" height="7" rx="1" />
|
||||
<rect x="3" y="14" width="7" height="7" rx="1" />
|
||||
<rect x="14" y="14" width="7" height="7" rx="1" />
|
||||
</svg>
|
||||
),
|
||||
},
|
||||
{
|
||||
path: "/warehouse/suppliers",
|
||||
label: "Dodavatelé",
|
||||
permission: "warehouse.manage",
|
||||
matchPrefix: "/warehouse/suppliers",
|
||||
icon: (
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
@@ -356,7 +551,13 @@ const menuSections: MenuSection[] = [
|
||||
{
|
||||
path: "/settings",
|
||||
label: "Nastavení",
|
||||
permission: "settings.manage",
|
||||
permission: [
|
||||
"settings.company",
|
||||
"settings.banking",
|
||||
"settings.roles",
|
||||
"settings.system",
|
||||
"settings.templates",
|
||||
],
|
||||
icon: (
|
||||
<svg
|
||||
viewBox="0 0 24 24"
|
||||
|
||||
@@ -89,6 +89,21 @@ export default function DashProfile({
|
||||
const handleSubmit = async (e?: React.FormEvent) => {
|
||||
e?.preventDefault();
|
||||
const dataToSave = { ...formData };
|
||||
|
||||
if (dataToSave.new_password && !dataToSave.current_password) {
|
||||
alert.error("Pro změnu hesla zadejte aktuální heslo");
|
||||
return;
|
||||
}
|
||||
if (dataToSave.current_password && !dataToSave.new_password) {
|
||||
alert.error("Pro změnu hesla zadejte nové heslo");
|
||||
return;
|
||||
}
|
||||
|
||||
// Strip empty password fields so Zod doesn't reject ""
|
||||
if (!dataToSave.current_password)
|
||||
delete (dataToSave as any).current_password;
|
||||
if (!dataToSave.new_password) delete (dataToSave as any).new_password;
|
||||
|
||||
try {
|
||||
const response = await apiFetch(`${API_BASE}/profile`, {
|
||||
method: "PUT",
|
||||
@@ -329,9 +344,24 @@ export default function DashProfile({
|
||||
className="admin-form-input"
|
||||
/>
|
||||
</div>
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label">Aktuální heslo</label>
|
||||
<input
|
||||
type="password"
|
||||
value={formData.current_password}
|
||||
onChange={(e) =>
|
||||
setFormData({
|
||||
...formData,
|
||||
current_password: e.target.value,
|
||||
})
|
||||
}
|
||||
className="admin-form-input"
|
||||
placeholder="Pro změnu hesla, zadejte aktuální heslo"
|
||||
/>
|
||||
</div>
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label">
|
||||
Nové heslo (ponechte prázdné pro zachování stávajícího)
|
||||
Nové heslo
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
@@ -343,27 +373,9 @@ export default function DashProfile({
|
||||
})
|
||||
}
|
||||
className="admin-form-input"
|
||||
placeholder="Pro změnu hesla, zadejte nové heslo"
|
||||
/>
|
||||
</div>
|
||||
{formData.new_password && (
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label required">
|
||||
Aktuální heslo
|
||||
</label>
|
||||
<input
|
||||
type="password"
|
||||
value={formData.current_password}
|
||||
onChange={(e) =>
|
||||
setFormData({
|
||||
...formData,
|
||||
current_password: e.target.value,
|
||||
})
|
||||
}
|
||||
className="admin-form-input"
|
||||
placeholder="Zadejte aktuální heslo pro potvrzení"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-modal-footer">
|
||||
|
||||
@@ -7,8 +7,6 @@ import useModalLock from "../../hooks/useModalLock";
|
||||
import apiFetch from "../../utils/api";
|
||||
import { formatSessionDate } from "../../utils/dashboardHelpers";
|
||||
import { sessionsOptions, type Session } from "../../lib/queries/dashboard";
|
||||
import { Skeleton } from "boneyard-js/react";
|
||||
import DashSessionsFixture from "../../fixtures/DashSessionsFixture";
|
||||
|
||||
const API_BASE = "/api/admin";
|
||||
|
||||
@@ -154,11 +152,11 @@ export default function DashSessions() {
|
||||
)}
|
||||
</div>
|
||||
<div className="admin-card-body" style={{ padding: 0 }}>
|
||||
<Skeleton
|
||||
name="dash-sessions"
|
||||
loading={sessionsLoading}
|
||||
fixture={<DashSessionsFixture />}
|
||||
>
|
||||
{sessionsLoading ? (
|
||||
<div className="admin-loading">
|
||||
<div className="admin-spinner" />
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{sessions.length === 0 && (
|
||||
<div
|
||||
@@ -231,7 +229,7 @@ export default function DashSessions() {
|
||||
</div>
|
||||
)}
|
||||
</>
|
||||
</Skeleton>
|
||||
)}
|
||||
</div>
|
||||
</motion.div>
|
||||
|
||||
|
||||
74
src/admin/components/warehouse/BatchPicker.tsx
Normal file
74
src/admin/components/warehouse/BatchPicker.tsx
Normal file
@@ -0,0 +1,74 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { jsonQuery } from "../../lib/apiAdapter";
|
||||
|
||||
interface Batch {
|
||||
id: number;
|
||||
quantity: number;
|
||||
unit_price: number;
|
||||
received_at: string;
|
||||
is_consumed: boolean;
|
||||
}
|
||||
|
||||
interface BatchesResponse {
|
||||
batches: Batch[];
|
||||
total_stock: number;
|
||||
reserved_quantity: number;
|
||||
available_quantity: number;
|
||||
}
|
||||
|
||||
interface BatchPickerProps {
|
||||
itemId: number | null;
|
||||
value: number | null;
|
||||
onChange: (batchId: number, unitPrice: number) => void;
|
||||
}
|
||||
|
||||
export default function BatchPicker({
|
||||
itemId,
|
||||
value,
|
||||
onChange,
|
||||
}: BatchPickerProps) {
|
||||
const { data: response } = useQuery({
|
||||
queryKey: ["warehouse", "batches", itemId],
|
||||
queryFn: () =>
|
||||
jsonQuery<BatchesResponse>(
|
||||
`/api/admin/warehouse/items/${itemId}/batches`,
|
||||
),
|
||||
enabled: !!itemId,
|
||||
});
|
||||
|
||||
const batches = response?.batches ?? [];
|
||||
|
||||
return (
|
||||
<div>
|
||||
{response && response.reserved_quantity > 0 && (
|
||||
<div
|
||||
style={{
|
||||
fontSize: "0.75rem",
|
||||
color: "var(--text-tertiary)",
|
||||
marginBottom: "0.25rem",
|
||||
}}
|
||||
>
|
||||
Dostupné: {response.available_quantity} ks (z toho rezervováno:{" "}
|
||||
{response.reserved_quantity} ks)
|
||||
</div>
|
||||
)}
|
||||
<select
|
||||
className="admin-form-select"
|
||||
value={value ?? ""}
|
||||
onChange={(e) => {
|
||||
const batchId = Number(e.target.value);
|
||||
const batch = batches.find((b) => b.id === batchId);
|
||||
if (batch) onChange(batch.id, Number(batch.unit_price));
|
||||
}}
|
||||
>
|
||||
<option value="">-- auto FIFO --</option>
|
||||
{batches.map((b) => (
|
||||
<option key={b.id} value={b.id}>
|
||||
{new Date(b.received_at).toLocaleDateString("cs-CZ")} | {b.quantity}{" "}
|
||||
ks | {Number(b.unit_price).toFixed(2)} Kč
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
228
src/admin/components/warehouse/ItemPicker.tsx
Normal file
228
src/admin/components/warehouse/ItemPicker.tsx
Normal file
@@ -0,0 +1,228 @@
|
||||
import { useState, useRef, useEffect, useCallback, useId } from "react";
|
||||
import { createPortal } from "react-dom";
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { warehouseItemListOptions } from "../../lib/queries/warehouse";
|
||||
|
||||
interface ItemPickerProps {
|
||||
value: number | null;
|
||||
onChange: (itemId: number) => void;
|
||||
itemName?: string;
|
||||
}
|
||||
|
||||
export default function ItemPicker({
|
||||
value,
|
||||
onChange,
|
||||
itemName,
|
||||
}: ItemPickerProps) {
|
||||
const [search, setSearch] = useState(itemName ?? "");
|
||||
const [open, setOpen] = useState(false);
|
||||
const { data } = useQuery(warehouseItemListOptions({ search, perPage: 20 }));
|
||||
const items = data?.data ?? [];
|
||||
|
||||
const containerRef = useRef<HTMLDivElement>(null);
|
||||
const activeIndexRef = useRef<number>(-1);
|
||||
const listboxId = useId();
|
||||
const [activeIndex, setActiveIndex] = useState<number>(-1);
|
||||
|
||||
const [dropdownStyle, setDropdownStyle] = useState<{
|
||||
position: "fixed";
|
||||
top: number;
|
||||
left: number;
|
||||
width: number;
|
||||
zIndex: number;
|
||||
} | null>(null);
|
||||
|
||||
const updatePosition = useCallback(() => {
|
||||
if (!containerRef.current) return;
|
||||
const rect = containerRef.current.getBoundingClientRect();
|
||||
setDropdownStyle({
|
||||
position: "fixed",
|
||||
top: rect.bottom + 2,
|
||||
left: rect.left,
|
||||
width: rect.width,
|
||||
zIndex: 100,
|
||||
});
|
||||
}, []);
|
||||
|
||||
// Reset active index when items change
|
||||
useEffect(() => {
|
||||
if (activeIndex >= items.length) {
|
||||
activeIndexRef.current = -1;
|
||||
setActiveIndex(-1);
|
||||
}
|
||||
}, [items, activeIndex]);
|
||||
|
||||
useEffect(() => {
|
||||
if (open) {
|
||||
updatePosition();
|
||||
const onScroll = () => updatePosition();
|
||||
const onClose = () => setOpen(false);
|
||||
window.addEventListener("scroll", onScroll, true);
|
||||
window.addEventListener("resize", onClose);
|
||||
return () => {
|
||||
window.removeEventListener("scroll", onScroll, true);
|
||||
window.removeEventListener("resize", onClose);
|
||||
};
|
||||
} else {
|
||||
setDropdownStyle(null);
|
||||
activeIndexRef.current = -1;
|
||||
setActiveIndex(-1);
|
||||
}
|
||||
}, [open, updatePosition]);
|
||||
|
||||
// Close on click-outside via mousedown on document
|
||||
useEffect(() => {
|
||||
if (!open) return;
|
||||
const onDocMouseDown = (e: MouseEvent) => {
|
||||
const target = e.target;
|
||||
if (containerRef.current && target instanceof Node) {
|
||||
if (!containerRef.current.contains(target)) {
|
||||
// Don't close if click landed on an option in the portal
|
||||
const listEl = document.getElementById(listboxId);
|
||||
if (listEl && listEl.contains(target)) return;
|
||||
setOpen(false);
|
||||
}
|
||||
}
|
||||
};
|
||||
document.addEventListener("mousedown", onDocMouseDown);
|
||||
return () => document.removeEventListener("mousedown", onDocMouseDown);
|
||||
}, [open, listboxId]);
|
||||
|
||||
const handleSelect = (itemId: number, name: string) => {
|
||||
onChange(itemId);
|
||||
setOpen(false);
|
||||
setSearch(name);
|
||||
};
|
||||
|
||||
const setActive = (index: number) => {
|
||||
activeIndexRef.current = index;
|
||||
setActiveIndex(index);
|
||||
};
|
||||
|
||||
const handleKeyDown = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
if (e.key === "ArrowDown") {
|
||||
e.preventDefault();
|
||||
if (!open) {
|
||||
setOpen(true);
|
||||
if (items.length > 0) setActive(0);
|
||||
return;
|
||||
}
|
||||
const next =
|
||||
activeIndexRef.current < items.length - 1
|
||||
? activeIndexRef.current + 1
|
||||
: 0;
|
||||
setActive(next);
|
||||
} else if (e.key === "ArrowUp") {
|
||||
e.preventDefault();
|
||||
if (!open) {
|
||||
setOpen(true);
|
||||
if (items.length > 0) setActive(items.length - 1);
|
||||
return;
|
||||
}
|
||||
const prev =
|
||||
activeIndexRef.current > 0
|
||||
? activeIndexRef.current - 1
|
||||
: items.length - 1;
|
||||
setActive(prev);
|
||||
} else if (e.key === "Enter") {
|
||||
if (
|
||||
open &&
|
||||
activeIndexRef.current >= 0 &&
|
||||
activeIndexRef.current < items.length
|
||||
) {
|
||||
e.preventDefault();
|
||||
const item = items[activeIndexRef.current];
|
||||
handleSelect(item.id, item.name);
|
||||
}
|
||||
} else if (e.key === "Escape") {
|
||||
if (open) {
|
||||
e.preventDefault();
|
||||
setOpen(false);
|
||||
}
|
||||
} else if (e.key === "Home") {
|
||||
if (open && items.length > 0) {
|
||||
e.preventDefault();
|
||||
setActive(0);
|
||||
}
|
||||
} else if (e.key === "End") {
|
||||
if (open && items.length > 0) {
|
||||
e.preventDefault();
|
||||
setActive(items.length - 1);
|
||||
}
|
||||
} else if (e.key === "Tab") {
|
||||
setOpen(false);
|
||||
}
|
||||
};
|
||||
|
||||
const activeId =
|
||||
activeIndex >= 0 ? `${listboxId}-option-${activeIndex}` : undefined;
|
||||
|
||||
return (
|
||||
<div
|
||||
ref={containerRef}
|
||||
style={{ position: "relative" }}
|
||||
role="combobox"
|
||||
aria-haspopup="listbox"
|
||||
aria-expanded={open}
|
||||
aria-owns={listboxId}
|
||||
>
|
||||
<input
|
||||
type="text"
|
||||
className="admin-form-input"
|
||||
placeholder="Hledat položku..."
|
||||
value={search}
|
||||
role="searchbox"
|
||||
aria-autocomplete="list"
|
||||
aria-controls={listboxId}
|
||||
aria-activedescendant={activeId}
|
||||
onChange={(e) => {
|
||||
setSearch(e.target.value);
|
||||
setOpen(true);
|
||||
}}
|
||||
onFocus={() => {
|
||||
setOpen(true);
|
||||
updatePosition();
|
||||
}}
|
||||
onKeyDown={handleKeyDown}
|
||||
/>
|
||||
{open &&
|
||||
items.length > 0 &&
|
||||
dropdownStyle &&
|
||||
createPortal(
|
||||
<ul
|
||||
id={listboxId}
|
||||
role="listbox"
|
||||
className="admin-item-picker-list"
|
||||
style={dropdownStyle}
|
||||
>
|
||||
{items.map((item, index) => (
|
||||
<li
|
||||
key={item.id}
|
||||
id={`${listboxId}-option-${index}`}
|
||||
role="option"
|
||||
aria-selected={value === item.id}
|
||||
className={`admin-item-picker-item ${activeIndex === index ? "active" : ""}`}
|
||||
onMouseDown={(e) => {
|
||||
e.preventDefault();
|
||||
handleSelect(item.id, item.name);
|
||||
}}
|
||||
>
|
||||
<span className="admin-item-picker-name">{item.name}</span>
|
||||
{item.item_number && (
|
||||
<span className="admin-item-picker-number">
|
||||
{item.item_number}
|
||||
</span>
|
||||
)}
|
||||
{item.available_quantity !== undefined && (
|
||||
<span className="admin-item-picker-qty">
|
||||
{item.available_quantity} {item.unit}
|
||||
</span>
|
||||
)}
|
||||
</li>
|
||||
))}
|
||||
</ul>,
|
||||
document.body,
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
31
src/admin/components/warehouse/LocationSelect.tsx
Normal file
31
src/admin/components/warehouse/LocationSelect.tsx
Normal file
@@ -0,0 +1,31 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import {
|
||||
warehouseLocationListOptions,
|
||||
type WarehouseLocation,
|
||||
} from "../../lib/queries/warehouse";
|
||||
|
||||
interface LocationSelectProps {
|
||||
value: number | null;
|
||||
onChange: (locationId: number | null) => void;
|
||||
}
|
||||
|
||||
export default function LocationSelect({
|
||||
value,
|
||||
onChange,
|
||||
}: LocationSelectProps) {
|
||||
const { data: locations } = useQuery(warehouseLocationListOptions());
|
||||
return (
|
||||
<select
|
||||
className="admin-form-select"
|
||||
value={value ?? ""}
|
||||
onChange={(e) => onChange(e.target.value ? Number(e.target.value) : null)}
|
||||
>
|
||||
<option value="">-- bez lokace --</option>
|
||||
{locations?.map((loc: WarehouseLocation) => (
|
||||
<option key={loc.id} value={loc.id}>
|
||||
{loc.code} - {loc.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
);
|
||||
}
|
||||
54
src/admin/components/warehouse/ReservationPicker.tsx
Normal file
54
src/admin/components/warehouse/ReservationPicker.tsx
Normal file
@@ -0,0 +1,54 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import { warehouseReservationListOptions } from "../../lib/queries/warehouse";
|
||||
|
||||
interface ReservationPickerProps {
|
||||
itemId: number | null;
|
||||
projectId: number | null;
|
||||
value: number | null;
|
||||
onChange: (reservationId: number | null, remainingQty: number) => void;
|
||||
}
|
||||
|
||||
export default function ReservationPicker({
|
||||
itemId,
|
||||
projectId,
|
||||
value,
|
||||
onChange,
|
||||
}: ReservationPickerProps) {
|
||||
const { data: result } = useQuery(
|
||||
warehouseReservationListOptions({
|
||||
item_id: itemId ?? undefined,
|
||||
project_id: projectId ?? undefined,
|
||||
status: "ACTIVE",
|
||||
perPage: 100,
|
||||
}),
|
||||
);
|
||||
|
||||
const reservations = result?.data ?? [];
|
||||
|
||||
return (
|
||||
<select
|
||||
className="admin-form-select"
|
||||
value={value ?? ""}
|
||||
onChange={(e) => {
|
||||
const val = e.target.value;
|
||||
if (!val) {
|
||||
onChange(null, 0);
|
||||
return;
|
||||
}
|
||||
const reservationId = Number(val);
|
||||
const reservation = reservations.find((r) => r.id === reservationId);
|
||||
if (reservation) {
|
||||
onChange(reservationId, Number(reservation.remaining_qty));
|
||||
}
|
||||
}}
|
||||
>
|
||||
<option value="">— žádná rezervace —</option>
|
||||
{reservations.map((r) => (
|
||||
<option key={r.id} value={r.id}>
|
||||
R{r.id} — {r.project?.name ?? `Projekt #${r.project_id}`} — zbývá:{" "}
|
||||
{Number(r.remaining_qty)} {r.item?.unit ?? "ks"}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
);
|
||||
}
|
||||
33
src/admin/components/warehouse/SupplierSelect.tsx
Normal file
33
src/admin/components/warehouse/SupplierSelect.tsx
Normal file
@@ -0,0 +1,33 @@
|
||||
import { useQuery } from "@tanstack/react-query";
|
||||
import {
|
||||
warehouseSupplierListOptions,
|
||||
type WarehouseSupplier,
|
||||
} from "../../lib/queries/warehouse";
|
||||
|
||||
interface SupplierSelectProps {
|
||||
value: number | null;
|
||||
onChange: (supplierId: number | null) => void;
|
||||
}
|
||||
|
||||
export default function SupplierSelect({
|
||||
value,
|
||||
onChange,
|
||||
}: SupplierSelectProps) {
|
||||
const { data } = useQuery(warehouseSupplierListOptions({ perPage: 100 }));
|
||||
const suppliers = data?.data ?? [];
|
||||
return (
|
||||
<select
|
||||
className="admin-form-select"
|
||||
value={value ?? ""}
|
||||
onChange={(e) => onChange(e.target.value ? Number(e.target.value) : null)}
|
||||
>
|
||||
<option value="">-- bez dodavatele --</option>
|
||||
{suppliers.map((s: WarehouseSupplier) => (
|
||||
<option key={s.id} value={s.id}>
|
||||
{s.name}
|
||||
{s.ico ? ` (${s.ico})` : ""}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
);
|
||||
}
|
||||
249
src/admin/components/warehouse/WarehouseMovementTable.tsx
Normal file
249
src/admin/components/warehouse/WarehouseMovementTable.tsx
Normal file
@@ -0,0 +1,249 @@
|
||||
import { ReactNode, useId, useRef } from "react";
|
||||
import ItemPicker from "./ItemPicker";
|
||||
import LocationSelect from "./LocationSelect";
|
||||
import BatchPicker from "./BatchPicker";
|
||||
|
||||
export interface MovementItem {
|
||||
key: string;
|
||||
item_id: number | null;
|
||||
item_name?: string;
|
||||
quantity: number;
|
||||
unit_price: number;
|
||||
location_id: number | null;
|
||||
batch_id: number | null;
|
||||
reservation_id: number | null;
|
||||
notes: string | null;
|
||||
}
|
||||
|
||||
export type MovementRowRenderer<T> = (
|
||||
item: T,
|
||||
index: number,
|
||||
updateItem: (field: string, value: unknown) => void,
|
||||
removeItem: () => void,
|
||||
) => ReactNode;
|
||||
|
||||
interface WarehouseMovementTableProps<T extends { key: string }> {
|
||||
items: T[];
|
||||
onChange: (items: T[]) => void;
|
||||
mode: "receipt" | "issue" | "inventory";
|
||||
defaultItem?: () => Omit<T, "key">;
|
||||
renderRow?: MovementRowRenderer<T>;
|
||||
renderHeader?: () => ReactNode;
|
||||
}
|
||||
|
||||
function parseDecimal(raw: string): number {
|
||||
// Strip leading minus if you want negative support; here we want only positive
|
||||
const cleaned = raw.replace(/[eE+\-]/g, "");
|
||||
const n = Number(cleaned);
|
||||
return Number.isFinite(n) ? n : 0;
|
||||
}
|
||||
|
||||
const builtInDefaultMovementItem = (): Omit<MovementItem, "key"> => ({
|
||||
item_id: null,
|
||||
quantity: 0,
|
||||
unit_price: 0,
|
||||
location_id: null,
|
||||
batch_id: null,
|
||||
reservation_id: null,
|
||||
notes: null,
|
||||
});
|
||||
|
||||
export default function WarehouseMovementTable<T extends { key: string }>({
|
||||
items,
|
||||
onChange,
|
||||
mode,
|
||||
defaultItem,
|
||||
renderRow,
|
||||
renderHeader,
|
||||
}: WarehouseMovementTableProps<T>) {
|
||||
const baseId = useId();
|
||||
const counterRef = useRef(0);
|
||||
const nextKey = () => `${baseId}-item-${counterRef.current++}`;
|
||||
|
||||
const addItem = () => {
|
||||
const factory =
|
||||
defaultItem ??
|
||||
(builtInDefaultMovementItem as unknown as () => Omit<T, "key">);
|
||||
onChange([...items, { ...(factory() as object), key: nextKey() } as T]);
|
||||
};
|
||||
const removeItem = (index: number) => {
|
||||
onChange(items.filter((_, i) => i !== index));
|
||||
};
|
||||
const updateItem = (index: number, field: string, value: unknown) => {
|
||||
const updated = [...items];
|
||||
updated[index] = { ...updated[index], [field]: value };
|
||||
onChange(updated);
|
||||
};
|
||||
|
||||
// If a custom row renderer is supplied, the caller is fully in charge of
|
||||
// the row layout (and typically the column headers too — see inventory mode).
|
||||
if (renderRow) {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-warehouse-movement-table">
|
||||
<table className="admin-table">
|
||||
{renderHeader && (
|
||||
<thead>
|
||||
<tr>{renderHeader()}</tr>
|
||||
</thead>
|
||||
)}
|
||||
<tbody>
|
||||
{items.map((item, index) => (
|
||||
<tr key={item.key}>
|
||||
{renderRow(
|
||||
item,
|
||||
index,
|
||||
(field, value) => updateItem(index, field, value),
|
||||
() => removeItem(index),
|
||||
)}
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="admin-btn admin-btn-secondary"
|
||||
onClick={addItem}
|
||||
>
|
||||
+ Přidat řádek
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
// Default rendering: only valid for "receipt" | "issue" — narrow at runtime.
|
||||
const movementItems = items as unknown as MovementItem[];
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-warehouse-movement-table">
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th className="admin-warehouse-col-item">Položka</th>
|
||||
{mode === "issue" && (
|
||||
<th className="admin-warehouse-col-batch">Šarže</th>
|
||||
)}
|
||||
<th className="admin-warehouse-col-qty">Množství</th>
|
||||
<th className="admin-warehouse-col-price">Cena/ks</th>
|
||||
<th className="admin-warehouse-col-location">Lokace</th>
|
||||
<th className="admin-warehouse-col-notes">Poznámka</th>
|
||||
<th>Akce</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{movementItems.map((item, index) => (
|
||||
<tr key={item.key}>
|
||||
<td className="admin-warehouse-col-item">
|
||||
<ItemPicker
|
||||
value={item.item_id}
|
||||
itemName={item.item_name}
|
||||
onChange={(id) => updateItem(index, "item_id", id)}
|
||||
/>
|
||||
</td>
|
||||
{mode === "issue" && (
|
||||
<td className="admin-warehouse-col-batch">
|
||||
<BatchPicker
|
||||
itemId={item.item_id}
|
||||
value={item.batch_id}
|
||||
onChange={(batchId, unitPrice) => {
|
||||
updateItem(index, "batch_id", batchId);
|
||||
updateItem(index, "unit_price", unitPrice);
|
||||
}}
|
||||
/>
|
||||
</td>
|
||||
)}
|
||||
<td className="admin-warehouse-col-qty">
|
||||
<input
|
||||
type="number"
|
||||
className="admin-form-input"
|
||||
value={item.quantity || ""}
|
||||
onChange={(e) =>
|
||||
updateItem(
|
||||
index,
|
||||
"quantity",
|
||||
parseDecimal(e.target.value),
|
||||
)
|
||||
}
|
||||
min="0"
|
||||
step="0.001"
|
||||
inputMode="decimal"
|
||||
pattern="[0-9]+([\.,][0-9]+)?"
|
||||
aria-label={`Množství, řádek ${index + 1}`}
|
||||
/>
|
||||
</td>
|
||||
<td className="admin-warehouse-col-price">
|
||||
<input
|
||||
type="number"
|
||||
className="admin-form-input"
|
||||
value={item.unit_price || ""}
|
||||
onChange={(e) =>
|
||||
updateItem(
|
||||
index,
|
||||
"unit_price",
|
||||
parseDecimal(e.target.value),
|
||||
)
|
||||
}
|
||||
min="0"
|
||||
step="0.01"
|
||||
disabled={mode === "issue"}
|
||||
inputMode="decimal"
|
||||
pattern="[0-9]+([\.,][0-9]+)?"
|
||||
aria-label={`Cena za kus, řádek ${index + 1}`}
|
||||
/>
|
||||
</td>
|
||||
<td className="admin-warehouse-col-location">
|
||||
<LocationSelect
|
||||
value={item.location_id}
|
||||
onChange={(id) => updateItem(index, "location_id", id)}
|
||||
/>
|
||||
</td>
|
||||
<td className="admin-warehouse-col-notes">
|
||||
<input
|
||||
type="text"
|
||||
className="admin-form-input"
|
||||
value={item.notes ?? ""}
|
||||
onChange={(e) => updateItem(index, "notes", e.target.value)}
|
||||
/>
|
||||
</td>
|
||||
<td>
|
||||
<div className="admin-table-actions">
|
||||
<button
|
||||
type="button"
|
||||
className="admin-btn-icon danger"
|
||||
onClick={() => removeItem(index)}
|
||||
title="Odebrat řádek"
|
||||
aria-label="Odebrat řádek"
|
||||
>
|
||||
<svg
|
||||
width="16"
|
||||
height="16"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
>
|
||||
<line x1="18" y1="6" x2="6" y2="18" />
|
||||
<line x1="6" y1="6" x2="18" y2="18" />
|
||||
</svg>
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
className="admin-btn admin-btn-secondary"
|
||||
onClick={addItem}
|
||||
>
|
||||
+ Přidat řádek
|
||||
</button>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
export default function AttendanceAdminFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div>
|
||||
<h1 className="admin-page-title">Správa docházky</h1>
|
||||
</div>
|
||||
<div className="admin-page-actions">
|
||||
<button className="admin-btn admin-btn-secondary">
|
||||
Vyplnit měsíc
|
||||
</button>
|
||||
<button className="admin-btn admin-btn-primary">Přidat záznam</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card mb-6">
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-form-row">
|
||||
<label className="admin-form-label">Měsíc</label>
|
||||
<select className="admin-form-select" />
|
||||
<label className="admin-form-label">Zaměstnanec</label>
|
||||
<select className="admin-form-select" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-grid admin-grid-3">
|
||||
{Array.from({ length: 3 }, (_, i) => (
|
||||
<div key={i} className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<div className="flex-row gap-2 mb-2">
|
||||
<span style={{ fontWeight: 600 }}>Jan Novák</span>
|
||||
<span className="attendance-working-badge finished">
|
||||
✗
|
||||
</span>
|
||||
</div>
|
||||
<div className="admin-stat-value">8:00</div>
|
||||
<div className="admin-stat-label">odpracováno</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-table-responsive">
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Datum</th>
|
||||
<th>Příchod</th>
|
||||
<th>Odchod</th>
|
||||
<th>Hodiny</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 4 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td>1. 4. 2025</td>
|
||||
<td className="admin-mono">08:00</td>
|
||||
<td className="admin-mono">16:00</td>
|
||||
<td className="admin-mono">8:00</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,104 +0,0 @@
|
||||
export default function AttendanceBalancesFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div>
|
||||
<h1 className="admin-page-title">Správa bilancí</h1>
|
||||
</div>
|
||||
<div className="admin-page-actions">
|
||||
<select className="admin-form-select" style={{ minWidth: 100 }}>
|
||||
<option>2025</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-table-responsive">
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Zaměstnanec</th>
|
||||
<th>Nárok (h)</th>
|
||||
<th>Čerpáno (h)</th>
|
||||
<th>Zbývá (h)</th>
|
||||
<th>Nemoc (h)</th>
|
||||
<th>Akce</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 4 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td className="fw-500">Jan Novák</td>
|
||||
<td className="admin-mono">160</td>
|
||||
<td className="admin-mono">40.0</td>
|
||||
<td className="admin-mono">120.0</td>
|
||||
<td className="admin-mono">8.0</td>
|
||||
<td>
|
||||
<div className="admin-table-actions">
|
||||
<button className="admin-btn-icon" title="Upravit">
|
||||
✎
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-6">
|
||||
<h2 className="admin-page-title mb-4" style={{ fontSize: "1.25rem" }}>
|
||||
Měsíční přehled fondu 2025
|
||||
</h2>
|
||||
<div className="admin-grid admin-grid-3">
|
||||
{Array.from({ length: 3 }, (_, i) => (
|
||||
<div key={i} className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<h3 style={{ fontWeight: 600, fontSize: "1rem", margin: 0 }}>
|
||||
Duben
|
||||
</h3>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "0.375rem",
|
||||
marginTop: "0.5rem",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
fontSize: 12,
|
||||
}}
|
||||
>
|
||||
<span>Jan Novák</span>
|
||||
<span className="text-secondary">8h</span>
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
height: 3,
|
||||
background: "var(--bg-tertiary)",
|
||||
borderRadius: 2,
|
||||
overflow: "hidden",
|
||||
}}
|
||||
>
|
||||
<div
|
||||
style={{
|
||||
height: "100%",
|
||||
width: "75%",
|
||||
background: "var(--gradient)",
|
||||
borderRadius: 2,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
export default function AttendanceCreateFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<h1 className="admin-page-title">Zapsat docházku</h1>
|
||||
</div>
|
||||
<div className="admin-card" style={{ maxWidth: 600 }}>
|
||||
<div className="admin-card-body">
|
||||
<FormField label="Uživatel">
|
||||
<select className="admin-form-select">
|
||||
<option>Jan Novák</option>
|
||||
</select>
|
||||
</FormField>
|
||||
<FormField label="Datum">
|
||||
<input type="date" className="admin-form-input" />
|
||||
</FormField>
|
||||
<FormField label="Příchod">
|
||||
<input type="time" className="admin-form-input" />
|
||||
</FormField>
|
||||
<FormField label="Odchod">
|
||||
<input type="time" className="admin-form-input" />
|
||||
</FormField>
|
||||
<button className="admin-btn admin-btn-primary">Uložit</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function FormField({
|
||||
label,
|
||||
children,
|
||||
}: {
|
||||
label: string;
|
||||
children: React.ReactNode;
|
||||
}) {
|
||||
return (
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label">{label}</label>
|
||||
{children}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,79 +0,0 @@
|
||||
export default function AttendanceFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div>
|
||||
<h1 className="admin-page-title">Docházka</h1>
|
||||
<p className="admin-page-subtitle">pondělí 28. dubna 2025</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="attendance-layout">
|
||||
<div className="attendance-main">
|
||||
<div className="attendance-clock-card">
|
||||
<div className="attendance-clock-header">
|
||||
<div className="attendance-clock-status">
|
||||
<span className="attendance-status-dot" />
|
||||
<span>Nepracuji</span>
|
||||
</div>
|
||||
<div className="attendance-clock-time">08:30</div>
|
||||
</div>
|
||||
<div className="attendance-clock-actions">
|
||||
<button className="admin-btn admin-btn-primary w-full">
|
||||
Příchod
|
||||
</button>
|
||||
<button className="admin-btn admin-btn-secondary w-full">
|
||||
Žádost o nepřítomnost
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="attendance-sidebar">
|
||||
<div className="attendance-balance-card">
|
||||
<h3 className="attendance-balance-title">Dovolená 2025</h3>
|
||||
<div className="attendance-balance-value">
|
||||
<span className="attendance-balance-number">12</span>
|
||||
<span className="attendance-balance-unit">dnů</span>
|
||||
</div>
|
||||
<div className="attendance-balance-detail">
|
||||
<span>Celkem: 160h</span>
|
||||
<span>Čerpáno: 64h</span>
|
||||
</div>
|
||||
<div className="attendance-balance-bar">
|
||||
<div
|
||||
className="attendance-balance-progress"
|
||||
style={{ width: "60%" }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-stat-card">
|
||||
<div className="admin-stat-icon danger">
|
||||
<svg
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<path d="M22 12h-4l-3 9L9 3l-3 9H2" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="admin-stat-content">
|
||||
<span className="admin-stat-label">Nemoc 2025</span>
|
||||
<span className="admin-stat-value">16h čerpáno</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="attendance-quick-links">
|
||||
<h4 className="attendance-quick-title">Rychlé odkazy</h4>
|
||||
<a className="attendance-quick-link">
|
||||
<span>Moje žádosti</span>
|
||||
</a>
|
||||
<a className="attendance-quick-link">
|
||||
<span>Historie docházky</span>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
export default function AttendanceHistoryFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div>
|
||||
<h1 className="admin-page-title">Historie docházky</h1>
|
||||
<p className="admin-page-subtitle">duben 2025</p>
|
||||
</div>
|
||||
<div className="admin-page-actions">
|
||||
<button className="admin-btn admin-btn-secondary">Tisk</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card mb-6">
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-form-row">
|
||||
<label className="admin-form-label">Měsíc</label>
|
||||
<input className="admin-form-input" readOnly value="04/2025" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card mb-6">
|
||||
<div className="admin-card-body">
|
||||
<div style={{ display: "flex", alignItems: "center", gap: "1rem" }}>
|
||||
<div className="admin-stat-icon info">
|
||||
<svg
|
||||
width="24"
|
||||
height="24"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<rect x="3" y="4" width="18" height="18" rx="2" ry="2" />
|
||||
<line x1="16" y1="2" x2="16" y2="6" />
|
||||
<line x1="8" y1="2" x2="8" y2="6" />
|
||||
<line x1="3" y1="10" x2="21" y2="10" />
|
||||
</svg>
|
||||
</div>
|
||||
<div style={{ flex: 1, minWidth: 200 }}>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
justifyContent: "space-between",
|
||||
alignItems: "baseline",
|
||||
marginBottom: "0.375rem",
|
||||
}}
|
||||
>
|
||||
<span style={{ fontWeight: 600 }}>Fond: 120h / 160h</span>
|
||||
<span
|
||||
className="text-secondary"
|
||||
style={{ fontSize: "0.8125rem" }}
|
||||
>
|
||||
20 prac. dnů
|
||||
</span>
|
||||
</div>
|
||||
<div className="attendance-balance-bar">
|
||||
<div
|
||||
className="attendance-balance-progress"
|
||||
style={{ width: "75%" }}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-table-responsive">
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Datum</th>
|
||||
<th>Typ</th>
|
||||
<th>Příchod</th>
|
||||
<th>Pauza</th>
|
||||
<th>Odchod</th>
|
||||
<th>Hodiny</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 5 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td className="admin-mono">1. 4. 2025</td>
|
||||
<td>
|
||||
<span className="admin-badge admin-badge-info">
|
||||
Práce
|
||||
</span>
|
||||
</td>
|
||||
<td className="admin-mono">08:00</td>
|
||||
<td className="admin-mono">12:00 – 12:30</td>
|
||||
<td className="admin-mono">16:30</td>
|
||||
<td className="admin-mono">8:00</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
export default function AttendanceLocationFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div style={{ display: "flex", alignItems: "center", gap: "0.75rem" }}>
|
||||
<svg
|
||||
width="32"
|
||||
height="32"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z" />
|
||||
<circle cx="12" cy="10" r="3" />
|
||||
</svg>
|
||||
<h1 className="admin-page-title">Lokace</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card" style={{ height: 300, marginBottom: "1rem" }}>
|
||||
<div
|
||||
style={{
|
||||
background: "var(--bg-secondary)",
|
||||
height: "100%",
|
||||
borderRadius: 8,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "1rem" }}
|
||||
>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<h3 style={{ marginBottom: "0.5rem" }}>Poloha</h3>
|
||||
<p>50.0755° N, 14.4378° E</p>
|
||||
<p>Praha, Česká republika</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<h3 style={{ marginBottom: "0.5rem" }}>Čas záznamu</h3>
|
||||
<p>1. 1. 2024 08:00</p>
|
||||
<p>Přesnost: 10 m</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,52 +0,0 @@
|
||||
export default function AuditLogFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div>
|
||||
<h1 className="admin-page-title">Audit log</h1>
|
||||
<p className="admin-page-subtitle">Záznam změn v systému</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<div
|
||||
className="admin-search-bar mb-4"
|
||||
style={{ display: "flex", gap: "0.5rem" }}
|
||||
>
|
||||
<input className="admin-form-input" placeholder="" />
|
||||
<select className="admin-form-select" />
|
||||
<select className="admin-form-select" />
|
||||
</div>
|
||||
<div className="admin-table-responsive">
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Čas</th>
|
||||
<th>Uživatel</th>
|
||||
<th>Akce</th>
|
||||
<th>Entita</th>
|
||||
<th>Detail</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 5 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td className="admin-mono">1. 1. 2024 10:00</td>
|
||||
<td>admin</td>
|
||||
<td>
|
||||
<span className="admin-badge admin-badge-create">
|
||||
Vytvoření
|
||||
</span>
|
||||
</td>
|
||||
<td>Faktura</td>
|
||||
<td style={{ maxWidth: 300 }}>Nová faktura FV-2024-001</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,69 +0,0 @@
|
||||
export default function CompanySettingsFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div>
|
||||
<h1 className="admin-page-title">Nastavení firmy</h1>
|
||||
<p className="admin-page-subtitle">Firemní údaje a bankovní účty</p>
|
||||
</div>
|
||||
<button className="admin-btn admin-btn-primary">
|
||||
Uložit nastavení
|
||||
</button>
|
||||
</div>
|
||||
<div className="admin-settings-grid">
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-header">
|
||||
<h3 className="admin-card-title">Firemní údaje</h3>
|
||||
</div>
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-form">
|
||||
<label className="admin-form-label">Název firmy</label>
|
||||
<input
|
||||
className="admin-form-input"
|
||||
readOnly
|
||||
value="BOHA s.r.o."
|
||||
/>
|
||||
<div className="admin-form-row">
|
||||
<label className="admin-form-label">Ulice</label>
|
||||
<input
|
||||
className="admin-form-input"
|
||||
readOnly
|
||||
value="Hlavní 123"
|
||||
/>
|
||||
<label className="admin-form-label">Město</label>
|
||||
<input className="admin-form-input" readOnly value="Praha" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-header">
|
||||
<h3 className="admin-card-title">Bankovní účty</h3>
|
||||
</div>
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-table-responsive">
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Název</th>
|
||||
<th>Banka</th>
|
||||
<th>Číslo účtu</th>
|
||||
<th>Měna</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
<tr>
|
||||
<td>Hlavní účet</td>
|
||||
<td>ČSOB</td>
|
||||
<td className="admin-mono">123456/0300</td>
|
||||
<td>CZK</td>
|
||||
</tr>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
export default function DashSessionsFixture() {
|
||||
return (
|
||||
<div className="admin-card">
|
||||
<div
|
||||
className="admin-card-header"
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
gap: "0.75rem",
|
||||
}}
|
||||
>
|
||||
<h2 className="admin-card-title">Přihlášená zařízení</h2>
|
||||
<button className="admin-btn admin-btn-secondary admin-btn-sm">
|
||||
Odhlásit ostatní
|
||||
</button>
|
||||
</div>
|
||||
<div className="admin-card-body" style={{ padding: 0 }}>
|
||||
<div className="dash-sessions-list">
|
||||
{Array.from({ length: 3 }, (_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className={`dash-session-item${i === 0 ? " dash-session-item-current" : ""}`}
|
||||
>
|
||||
<div className="dash-session-icon">
|
||||
<svg
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<rect x="2" y="3" width="20" height="14" rx="2" ry="2" />
|
||||
<line x1="8" y1="21" x2="16" y2="21" />
|
||||
<line x1="12" y1="17" x2="12" y2="21" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="dash-session-info">
|
||||
<div className="dash-session-device">
|
||||
Chrome na Windows
|
||||
{i === 0 && (
|
||||
<span
|
||||
className="admin-badge admin-badge-success"
|
||||
style={{ marginLeft: "0.5rem" }}
|
||||
>
|
||||
Aktuální
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<div className="dash-session-meta">
|
||||
<span>192.168.1.100</span>
|
||||
<span className="dash-session-meta-separator">|</span>
|
||||
<span>před 2 hodinami</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,94 +0,0 @@
|
||||
export default function DashboardFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div>
|
||||
<h1 className="admin-page-title">Dashboard</h1>
|
||||
<p className="admin-page-subtitle">Přehled</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="dash-kpi-grid"
|
||||
style={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "repeat(4, 1fr)",
|
||||
gap: "1rem",
|
||||
marginBottom: "1rem",
|
||||
}}
|
||||
>
|
||||
{["Nabídky", "Objednávky", "Faktury", "Projekty"].map((label, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="dash-kpi-card"
|
||||
style={{
|
||||
padding: "1.25rem",
|
||||
borderRadius: 10,
|
||||
background: "var(--bg-secondary)",
|
||||
}}
|
||||
>
|
||||
<div style={{ fontSize: "0.875rem", marginBottom: "0.25rem" }}>
|
||||
{label}
|
||||
</div>
|
||||
<div style={{ fontSize: "1.5rem", fontWeight: 600 }}>12</div>
|
||||
<div style={{ fontSize: "0.75rem" }}>tento měsíc</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div
|
||||
className="dash-quick-actions"
|
||||
style={{ display: "flex", gap: "0.5rem", marginBottom: "1rem" }}
|
||||
>
|
||||
{["Nová nabídka", "Nová faktura", "Zapsat docházku"].map((label, i) => (
|
||||
<button
|
||||
key={i}
|
||||
className="admin-btn admin-btn-secondary"
|
||||
style={{ flex: 1 }}
|
||||
>
|
||||
{label}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
<div
|
||||
style={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "2fr 1fr",
|
||||
gap: "1rem",
|
||||
marginBottom: "1rem",
|
||||
}}
|
||||
>
|
||||
<div className="admin-card" style={{ minHeight: 320 }}>
|
||||
<div className="admin-card-body">
|
||||
<h3 className="admin-card-title">Docházka dnes</h3>
|
||||
<div style={{ height: 200 }} />
|
||||
</div>
|
||||
</div>
|
||||
<div style={{ display: "flex", flexDirection: "column", gap: "1rem" }}>
|
||||
<div className="admin-card" style={{ minHeight: 150 }}>
|
||||
<div className="admin-card-body">
|
||||
<h3 className="admin-card-title">Aktivita</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card" style={{ minHeight: 150 }}>
|
||||
<div className="admin-card-body">
|
||||
<h3 className="admin-card-title">Profil</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
style={{ display: "grid", gridTemplateColumns: "1fr 1fr", gap: "1rem" }}
|
||||
>
|
||||
<div className="admin-card" style={{ minHeight: 200 }}>
|
||||
<div className="admin-card-body">
|
||||
<h3 className="admin-card-title">Relace</h3>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card" style={{ minHeight: 200 }}>
|
||||
<div className="admin-card-body">
|
||||
<h3 className="admin-card-title">Poslední aktivity</h3>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,86 +0,0 @@
|
||||
export default function InvoiceDetailFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div style={{ display: "flex", alignItems: "center", gap: "0.5rem" }}>
|
||||
<a href="/invoices" className="admin-btn-icon">
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<path d="M19 12H5M12 19l-7-7 7-7" />
|
||||
</svg>
|
||||
</a>
|
||||
<div>
|
||||
<h1 className="admin-page-title">FV-2024-001</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-page-actions">
|
||||
<button className="admin-btn admin-btn-primary">Uložit</button>
|
||||
<button className="admin-btn admin-btn-secondary">Zaplaceno</button>
|
||||
<button className="admin-btn admin-btn-secondary">Smazat</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card" style={{ marginBottom: "1rem" }}>
|
||||
<div className="admin-card-body">
|
||||
<div
|
||||
className="admin-form-row"
|
||||
style={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr 1fr",
|
||||
gap: "1rem",
|
||||
}}
|
||||
>
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label">Zákazník</label>
|
||||
<div>Firma s.r.o.</div>
|
||||
</div>
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label">Stav</label>
|
||||
<span className="admin-badge admin-badge-invoice-issued">
|
||||
Vystavena
|
||||
</span>
|
||||
</div>
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label">Datum vystavení</label>
|
||||
<div>1. 1. 2024</div>
|
||||
</div>
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label">Datum splatnosti</label>
|
||||
<div>15. 1. 2024</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<h3 className="admin-card-title">Položky</h3>
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Položka</th>
|
||||
<th>Množství</th>
|
||||
<th>Cena</th>
|
||||
<th>Celkem</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 3 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td>Služba {i + 1}</td>
|
||||
<td>1</td>
|
||||
<td>10 000 Kč</td>
|
||||
<td>10 000 Kč</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
export default function InvoicesFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div>
|
||||
<h1 className="admin-page-title">Faktury</h1>
|
||||
<p className="admin-page-subtitle">15 faktur</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="dash-kpi-grid"
|
||||
style={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "repeat(4, 1fr)",
|
||||
gap: "1rem",
|
||||
marginBottom: "1rem",
|
||||
}}
|
||||
>
|
||||
{["Vystaveno", "Zaplaceno", "Po splatnosti", "Celkem"].map(
|
||||
(label, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="dash-kpi-card"
|
||||
style={{
|
||||
padding: "1.25rem",
|
||||
borderRadius: 10,
|
||||
background: "var(--bg-secondary)",
|
||||
}}
|
||||
>
|
||||
<div style={{ fontSize: "0.875rem", marginBottom: "0.25rem" }}>
|
||||
{label}
|
||||
</div>
|
||||
<div style={{ fontSize: "1.5rem", fontWeight: 600 }}>
|
||||
{i * 5 + 3}
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-search-bar mb-4">
|
||||
<input className="admin-form-input" placeholder="" />
|
||||
</div>
|
||||
<div className="admin-table-responsive">
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Číslo</th>
|
||||
<th>Zákazník</th>
|
||||
<th>Stav</th>
|
||||
<th>Datum</th>
|
||||
<th className="text-right">Částka</th>
|
||||
<th>Akce</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 5 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td className="admin-mono">FV-2024-00{i + 1}</td>
|
||||
<td>Firma s.r.o.</td>
|
||||
<td>
|
||||
<span className="admin-badge admin-badge-invoice-issued">
|
||||
Vystaveno
|
||||
</span>
|
||||
</td>
|
||||
<td className="admin-mono">1. 1. 2024</td>
|
||||
<td className="admin-mono text-right">50 000 Kč</td>
|
||||
<td>
|
||||
<div className="admin-table-actions">
|
||||
<button className="admin-btn-icon">👁</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
export default function LeaveApprovalFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div>
|
||||
<h1 className="admin-page-title">Schvalování dovolené</h1>
|
||||
<p className="admin-page-subtitle">2 čekající</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-table-responsive">
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Uživatel</th>
|
||||
<th>Typ</th>
|
||||
<th>Od</th>
|
||||
<th>Do</th>
|
||||
<th>Dní</th>
|
||||
<th>Akce</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 3 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td>Jan Novák</td>
|
||||
<td>Dovolená</td>
|
||||
<td className="admin-mono">1. 7. 2024</td>
|
||||
<td className="admin-mono">5. 7. 2024</td>
|
||||
<td>5</td>
|
||||
<td>
|
||||
<div className="admin-table-actions">
|
||||
<button className="admin-btn admin-btn-sm admin-btn-primary">
|
||||
Schválit
|
||||
</button>
|
||||
<button className="admin-btn admin-btn-sm admin-btn-secondary">
|
||||
Zamítnout
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
export default function LeaveRequestsFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div>
|
||||
<h1 className="admin-page-title">Žádosti o dovolenou</h1>
|
||||
<p className="admin-page-subtitle">3 žádosti</p>
|
||||
</div>
|
||||
<button className="admin-btn admin-btn-primary">+ Nová žádost</button>
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-table-responsive">
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Uživatel</th>
|
||||
<th>Typ</th>
|
||||
<th>Od</th>
|
||||
<th>Do</th>
|
||||
<th>Dní</th>
|
||||
<th>Stav</th>
|
||||
<th>Akce</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 3 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td>Jan Novák</td>
|
||||
<td>Dovolená</td>
|
||||
<td className="admin-mono">1. 7. 2024</td>
|
||||
<td className="admin-mono">5. 7. 2024</td>
|
||||
<td>5</td>
|
||||
<td>
|
||||
<span className="admin-badge admin-badge-pending">
|
||||
Čeká
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<div className="admin-table-actions">
|
||||
<button className="admin-btn-icon">Zrušit</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,60 +0,0 @@
|
||||
export default function OfferDetailFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<button className="admin-btn-icon">←</button>
|
||||
<h1 className="admin-page-title">NAB-2024-001</h1>
|
||||
<button className="admin-btn admin-btn-primary">Uložit</button>
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<div
|
||||
className="admin-form-row"
|
||||
style={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr 1fr",
|
||||
gap: "1rem",
|
||||
}}
|
||||
>
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label">Číslo nabídky</label>
|
||||
<div className="admin-form-input">NAB-2024-001</div>
|
||||
</div>
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label">Zákazník</label>
|
||||
<div className="admin-form-input">Firma s.r.o.</div>
|
||||
</div>
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label">Datum</label>
|
||||
<div className="admin-form-input">1. 1. 2024</div>
|
||||
</div>
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label">Platnost do</label>
|
||||
<div className="admin-form-input">31. 1. 2024</div>
|
||||
</div>
|
||||
</div>
|
||||
<table className="admin-table" style={{ marginTop: "1rem" }}>
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Položka</th>
|
||||
<th>Množství</th>
|
||||
<th>Cena</th>
|
||||
<th>Celkem</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 3 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td>Položka {i + 1}</td>
|
||||
<td>1</td>
|
||||
<td>10 000 Kč</td>
|
||||
<td>10 000 Kč</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
export default function OffersCustomersFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div>
|
||||
<h1 className="admin-page-title">Zákazníci</h1>
|
||||
<p className="admin-page-subtitle">8 zákazníků</p>
|
||||
</div>
|
||||
<button className="admin-btn admin-btn-primary">
|
||||
+ Přidat zákazníka
|
||||
</button>
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-search-bar mb-4">
|
||||
<input className="admin-form-input" placeholder="" />
|
||||
</div>
|
||||
<div className="admin-table-responsive">
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Název</th>
|
||||
<th>Město</th>
|
||||
<th>IČO</th>
|
||||
<th>Akce</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 5 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td>Firma s.r.o.</td>
|
||||
<td>Praha</td>
|
||||
<td className="admin-mono">12345678</td>
|
||||
<td>
|
||||
<div className="admin-table-actions">
|
||||
<button className="admin-btn-icon">✎</button>
|
||||
<button className="admin-btn-icon danger">🗑</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,54 +0,0 @@
|
||||
export default function OffersFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div>
|
||||
<h1 className="admin-page-title">Nabídky</h1>
|
||||
<p className="admin-page-subtitle">12 nabídek</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-search-bar mb-4">
|
||||
<input className="admin-form-input" placeholder="" />
|
||||
</div>
|
||||
<div className="admin-table-responsive">
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Číslo</th>
|
||||
<th>Zákazník</th>
|
||||
<th>Stav</th>
|
||||
<th>Datum</th>
|
||||
<th className="text-right">Celkem</th>
|
||||
<th>Akce</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 5 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td className="admin-mono">NAB-2024-00{i + 1}</td>
|
||||
<td>Firma s.r.o.</td>
|
||||
<td>
|
||||
<span className="admin-badge admin-badge-offer-active">
|
||||
Aktivní
|
||||
</span>
|
||||
</td>
|
||||
<td className="admin-mono">1. 1. 2024</td>
|
||||
<td className="admin-mono text-right fw-500">100 000 Kč</td>
|
||||
<td>
|
||||
<div className="admin-table-actions">
|
||||
<button className="admin-btn-icon">👁</button>
|
||||
<button className="admin-btn-icon">✎</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,36 +0,0 @@
|
||||
export default function OffersTemplatesFixture() {
|
||||
return (
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-search-bar mb-4">
|
||||
<input className="admin-form-input" placeholder="" />
|
||||
</div>
|
||||
<div className="admin-table-responsive">
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Název</th>
|
||||
<th>Cena</th>
|
||||
<th>Akce</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 5 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td>Šablona {i + 1}</td>
|
||||
<td className="admin-mono text-right">1 000 Kč</td>
|
||||
<td>
|
||||
<div className="admin-table-actions">
|
||||
<button className="admin-btn-icon">✎</button>
|
||||
<button className="admin-btn-icon danger">🗑</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
export default function OrderDetailFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div className="admin-page-header-left">
|
||||
<Link
|
||||
to="/orders"
|
||||
className="admin-btn-icon"
|
||||
style={{ marginRight: "0.5rem" }}
|
||||
>
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<path d="M19 12H5M12 19l-7-7 7-7" />
|
||||
</svg>
|
||||
</Link>
|
||||
<div>
|
||||
<h1 className="admin-page-title">OBJ-2024-001</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-page-actions">
|
||||
<button className="admin-btn admin-btn-primary">Uložit</button>
|
||||
<button className="admin-btn admin-btn-secondary">Stornovat</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card" style={{ marginBottom: "1rem" }}>
|
||||
<div className="admin-card-body">
|
||||
<div
|
||||
className="admin-form-row"
|
||||
style={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr 1fr",
|
||||
gap: "1rem",
|
||||
}}
|
||||
>
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label">Zákazník</label>
|
||||
<div>Firma s.r.o.</div>
|
||||
</div>
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label">Stav</label>
|
||||
<span className="admin-badge admin-badge-order-realizace">
|
||||
V realizaci
|
||||
</span>
|
||||
</div>
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label">Datum vytvoření</label>
|
||||
<div>1. 1. 2024</div>
|
||||
</div>
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label">Celkem</label>
|
||||
<div className="fw-500">50 000 Kč</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<h3 className="admin-card-title">Položky</h3>
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Položka</th>
|
||||
<th>Množství</th>
|
||||
<th>Cena</th>
|
||||
<th>Celkem</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 3 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td>Položka {i + 1}</td>
|
||||
<td>1</td>
|
||||
<td>10 000 Kč</td>
|
||||
<td>10 000 Kč</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,55 +0,0 @@
|
||||
export default function OrdersFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div>
|
||||
<h1 className="admin-page-title">Objednávky</h1>
|
||||
<p className="admin-page-subtitle">8 objednávek</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-search-bar mb-4">
|
||||
<input className="admin-form-input" placeholder="" />
|
||||
</div>
|
||||
<div className="admin-table-responsive">
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Číslo</th>
|
||||
<th>Nabídka</th>
|
||||
<th>Zákazník</th>
|
||||
<th>Stav</th>
|
||||
<th>Datum</th>
|
||||
<th className="text-right">Celkem</th>
|
||||
<th>Akce</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 5 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td className="admin-mono">OBJ-2024-00{i + 1}</td>
|
||||
<td>NAB-2024-00{i + 1}</td>
|
||||
<td>Firma s.r.o.</td>
|
||||
<td>
|
||||
<span className="admin-badge admin-badge-order-realizace">
|
||||
V realizaci
|
||||
</span>
|
||||
</td>
|
||||
<td className="admin-mono">1. 1. 2024</td>
|
||||
<td className="admin-mono text-right fw-500">50 000 Kč</td>
|
||||
<td>
|
||||
<div className="admin-table-actions">
|
||||
<button className="admin-btn-icon">👁</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
export default function ProjectDetailFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div style={{ display: "flex", alignItems: "center", gap: "0.5rem" }}>
|
||||
<a href="/projects" className="admin-btn-icon">
|
||||
<svg
|
||||
width="20"
|
||||
height="20"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<path d="M19 12H5M12 19l-7-7 7-7" />
|
||||
</svg>
|
||||
</a>
|
||||
<div>
|
||||
<h1 className="admin-page-title">PRJ-001 Projekt Alpha</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-page-actions">
|
||||
<button className="admin-btn admin-btn-primary">Uložit</button>
|
||||
<button className="admin-btn admin-btn-secondary">Smazat</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card" style={{ marginBottom: "1rem" }}>
|
||||
<div className="admin-card-body">
|
||||
<div
|
||||
className="admin-form-row"
|
||||
style={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "1fr 1fr",
|
||||
gap: "1rem",
|
||||
}}
|
||||
>
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label">Název projektu</label>
|
||||
<input
|
||||
className="admin-form-input"
|
||||
value="Projekt Alpha"
|
||||
readOnly
|
||||
/>
|
||||
</div>
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label">Stav</label>
|
||||
<select className="admin-form-select">
|
||||
<option>Aktivní</option>
|
||||
</select>
|
||||
</div>
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label">Začátek</label>
|
||||
<input type="date" className="admin-form-input" readOnly />
|
||||
</div>
|
||||
<div className="admin-form-group">
|
||||
<label className="admin-form-label">Konec</label>
|
||||
<input type="date" className="admin-form-input" readOnly />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card" style={{ marginBottom: "1rem" }}>
|
||||
<div className="admin-card-body">
|
||||
<h3 className="admin-card-title">Poznámky</h3>
|
||||
<textarea className="admin-form-input" rows={4} readOnly />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
export default function ProjectFileManagerFixture() {
|
||||
return (
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<h3 className="admin-card-title">Soubory</h3>
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "0.5rem",
|
||||
marginBottom: "0.75rem",
|
||||
fontSize: "0.875rem",
|
||||
color: "var(--text-secondary)",
|
||||
}}
|
||||
>
|
||||
<span>Projekt</span>
|
||||
<span>/</span>
|
||||
<span>Dokumentace</span>
|
||||
</div>
|
||||
{Array.from({ length: 4 }, (_, i) => (
|
||||
<div
|
||||
key={i}
|
||||
style={{
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
gap: "0.5rem",
|
||||
padding: "0.5rem 0",
|
||||
borderBottom: i < 3 ? "1px solid var(--border-color)" : "none",
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
width="18"
|
||||
height="18"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="1.5"
|
||||
>
|
||||
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" />
|
||||
<polyline points="14 2 14 8 20 8" />
|
||||
</svg>
|
||||
<span style={{ flex: 1 }}>dokument_{i + 1}.pdf</span>
|
||||
<span
|
||||
style={{ color: "var(--text-secondary)", fontSize: "0.8rem" }}
|
||||
>
|
||||
2.{i + 1} MB
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,51 +0,0 @@
|
||||
export default function ProjectsFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div>
|
||||
<h1 className="admin-page-title">Projekty</h1>
|
||||
<p className="admin-page-subtitle">6 projektů</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-search-bar mb-4">
|
||||
<input className="admin-form-input" placeholder="" />
|
||||
</div>
|
||||
<div className="admin-table-responsive">
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Číslo</th>
|
||||
<th>Název</th>
|
||||
<th>Zákazník</th>
|
||||
<th>Stav</th>
|
||||
<th>Akce</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 5 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td className="admin-mono">PRJ-2024-00{i + 1}</td>
|
||||
<td>Projekt Alpha</td>
|
||||
<td>Firma s.r.o.</td>
|
||||
<td>
|
||||
<span className="admin-badge admin-badge-project-active">
|
||||
Aktivní
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<div className="admin-table-actions">
|
||||
<button className="admin-btn-icon">👁</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,80 +0,0 @@
|
||||
export default function ReceivedInvoicesFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div>
|
||||
<h1 className="admin-page-title">Přijaté faktury</h1>
|
||||
<p className="admin-page-subtitle">8 faktur</p>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="dash-kpi-grid"
|
||||
style={{
|
||||
display: "grid",
|
||||
gridTemplateColumns: "repeat(4, 1fr)",
|
||||
gap: "1rem",
|
||||
marginBottom: "1rem",
|
||||
}}
|
||||
>
|
||||
{["K úhradě", "Zaplaceno", "Po splatnosti", "Celkem"].map(
|
||||
(label, i) => (
|
||||
<div
|
||||
key={i}
|
||||
className="dash-kpi-card"
|
||||
style={{
|
||||
padding: "1.25rem",
|
||||
borderRadius: 10,
|
||||
background: "var(--bg-secondary)",
|
||||
}}
|
||||
>
|
||||
<div style={{ fontSize: "0.875rem", marginBottom: "0.25rem" }}>
|
||||
{label}
|
||||
</div>
|
||||
<div style={{ fontSize: "1.5rem", fontWeight: 600 }}>
|
||||
{i * 3 + 2}
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
)}
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-table-responsive">
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Číslo</th>
|
||||
<th>Dodavatel</th>
|
||||
<th>Částka</th>
|
||||
<th>Datum</th>
|
||||
<th>Stav</th>
|
||||
<th>Akce</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 5 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td className="admin-mono">PF-2024-00{i + 1}</td>
|
||||
<td>Dodavatel s.r.o.</td>
|
||||
<td className="admin-mono text-right">10 000 Kč</td>
|
||||
<td className="admin-mono">1. 1. 2024</td>
|
||||
<td>
|
||||
<span className="admin-badge admin-badge-invoice-issued">
|
||||
K úhradě
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<div className="admin-table-actions">
|
||||
<button className="admin-btn-icon">✎</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,70 +0,0 @@
|
||||
export default function SettingsFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div>
|
||||
<h1 className="admin-page-title">Nastavení</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-tab-bar">
|
||||
<button className="admin-tab active">Role</button>
|
||||
<button className="admin-tab">Systém</button>
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-table-responsive">
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Název role</th>
|
||||
<th>Popis</th>
|
||||
<th>Oprávnění</th>
|
||||
<th>Akce</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 3 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td className="fw-500">admin</td>
|
||||
<td>Správa celého systému</td>
|
||||
<td>
|
||||
<span className="admin-badge admin-badge-info">
|
||||
všechna
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<div className="admin-table-actions">
|
||||
<button className="admin-btn-icon" title="Upravit">
|
||||
✎
|
||||
</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-header">
|
||||
<h2 className="admin-card-title">Docházka</h2>
|
||||
</div>
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-form">
|
||||
<div className="admin-form-row">
|
||||
<label className="admin-form-label">
|
||||
Limit pro přestávku (hodiny)
|
||||
</label>
|
||||
<input className="admin-form-input" readOnly value="6" />
|
||||
<label className="admin-form-label">
|
||||
Délka krátké přestávky (min)
|
||||
</label>
|
||||
<input className="admin-form-input" readOnly value="15" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,44 +0,0 @@
|
||||
export default function TripsAdminFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div>
|
||||
<h1 className="admin-page-title">Správa jízd</h1>
|
||||
<p className="admin-page-subtitle">10 jízd</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-table-responsive">
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Datum</th>
|
||||
<th>Vozidlo</th>
|
||||
<th>Uživatel</th>
|
||||
<th>Km</th>
|
||||
<th>Akce</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 5 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td className="admin-mono">1. 1. 2024</td>
|
||||
<td>Škoda Octavia</td>
|
||||
<td>Jan Novák</td>
|
||||
<td className="admin-mono">200</td>
|
||||
<td>
|
||||
<div className="admin-table-actions">
|
||||
<button className="admin-btn-icon">✎</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,132 +0,0 @@
|
||||
export default function TripsFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div>
|
||||
<h1 className="admin-page-title">Kniha jízd</h1>
|
||||
<p className="admin-page-subtitle">duben 2025</p>
|
||||
</div>
|
||||
<div className="admin-page-actions">
|
||||
<button className="admin-btn admin-btn-primary">Přidat jízdu</button>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-grid admin-grid-4">
|
||||
<div className="admin-stat-card info">
|
||||
<div className="admin-stat-icon info">
|
||||
<svg
|
||||
width="22"
|
||||
height="22"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<line x1="12" y1="20" x2="12" y2="10" />
|
||||
<line x1="18" y1="20" x2="18" y2="4" />
|
||||
<line x1="6" y1="20" x2="6" y2="16" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="admin-stat-content">
|
||||
<span className="admin-stat-value">12</span>
|
||||
<span className="admin-stat-label">Počet jízd</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-stat-card">
|
||||
<div className="admin-stat-icon">
|
||||
<svg
|
||||
width="22"
|
||||
height="22"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<path d="M22 12h-4l-3 9L9 3l-3 9H2" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="admin-stat-content">
|
||||
<span className="admin-stat-value">1 240 km</span>
|
||||
<span className="admin-stat-label">Celkem naježděno</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-stat-card success">
|
||||
<div className="admin-stat-icon success">
|
||||
<svg
|
||||
width="22"
|
||||
height="22"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<rect x="1" y="3" width="15" height="13" rx="2" ry="2" />
|
||||
<path d="M16 8h2a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-1" />
|
||||
<circle cx="5.5" cy="18" r="2" />
|
||||
<circle cx="18.5" cy="18" r="2" />
|
||||
<path d="M8 18h8" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="admin-stat-content">
|
||||
<span className="admin-stat-value">980 km</span>
|
||||
<span className="admin-stat-label">Služební</span>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-stat-card warning">
|
||||
<div className="admin-stat-icon warning">
|
||||
<svg
|
||||
width="22"
|
||||
height="22"
|
||||
viewBox="0 0 24 24"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
strokeWidth="2"
|
||||
>
|
||||
<path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z" />
|
||||
<polyline points="9 22 9 12 15 12 15 22" />
|
||||
</svg>
|
||||
</div>
|
||||
<div className="admin-stat-content">
|
||||
<span className="admin-stat-value">260 km</span>
|
||||
<span className="admin-stat-label">Soukromé</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card mt-6">
|
||||
<div className="admin-card-header flex-between">
|
||||
<h2 className="admin-card-title">Poslední jízdy</h2>
|
||||
<a className="admin-btn admin-btn-secondary admin-btn-sm">
|
||||
Zobrazit historii
|
||||
</a>
|
||||
</div>
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-table-responsive">
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Datum</th>
|
||||
<th>Vozidlo</th>
|
||||
<th>Trasa</th>
|
||||
<th>Vzdálenost</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 4 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td className="admin-mono">1. 4. 2025</td>
|
||||
<td>
|
||||
<span className="admin-badge">1A2 3456</span>
|
||||
</td>
|
||||
<td>Praha → Brno</td>
|
||||
<td className="admin-mono">
|
||||
<strong>200 km</strong>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,40 +0,0 @@
|
||||
export default function TripsHistoryFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div>
|
||||
<h1 className="admin-page-title">Historie jízd</h1>
|
||||
<p className="admin-page-subtitle">10 jízd</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-table-responsive">
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Datum</th>
|
||||
<th>Vozidlo</th>
|
||||
<th>Uživatel</th>
|
||||
<th>Trasa</th>
|
||||
<th>Km</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 5 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td className="admin-mono">1. 1. 2024</td>
|
||||
<td>Škoda Octavia</td>
|
||||
<td>Jan Novák</td>
|
||||
<td>Praha → Brno</td>
|
||||
<td className="admin-mono">200</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,66 +0,0 @@
|
||||
export default function UsersFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<div>
|
||||
<h1 className="admin-page-title">Uživatelé</h1>
|
||||
<p className="admin-page-subtitle">5 uživatelů</p>
|
||||
</div>
|
||||
<button className="admin-btn admin-btn-primary">
|
||||
+ Přidat uživatele
|
||||
</button>
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-search-bar mb-4">
|
||||
<input className="admin-form-input" placeholder="" />
|
||||
</div>
|
||||
<div className="admin-table-responsive">
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Uživatel</th>
|
||||
<th>E-mail</th>
|
||||
<th>Role</th>
|
||||
<th>Stav</th>
|
||||
<th>Akce</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 5 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td>
|
||||
<div className="admin-table-user">
|
||||
<div className="admin-table-avatar">A</div>
|
||||
<div>
|
||||
<div className="admin-table-name">Jan Novák</div>
|
||||
<div className="admin-table-username">@jan</div>
|
||||
</div>
|
||||
</div>
|
||||
</td>
|
||||
<td>jan@email.cz</td>
|
||||
<td>
|
||||
<span className="admin-badge admin-badge-admin">
|
||||
Administrátor
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<span className="admin-badge admin-badge-active">
|
||||
Aktivní
|
||||
</span>
|
||||
</td>
|
||||
<td>
|
||||
<div className="admin-table-actions">
|
||||
<button className="admin-btn-icon">✎</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,48 +0,0 @@
|
||||
export default function VehiclesFixture() {
|
||||
return (
|
||||
<div>
|
||||
<div className="admin-page-header">
|
||||
<h1 className="admin-page-title">Vozidla</h1>
|
||||
<button className="admin-btn admin-btn-primary">
|
||||
+ Přidat vozidlo
|
||||
</button>
|
||||
</div>
|
||||
<div className="admin-card">
|
||||
<div className="admin-card-body">
|
||||
<div className="admin-search-bar mb-4">
|
||||
<input className="admin-form-input" placeholder="" />
|
||||
</div>
|
||||
<div className="admin-table-responsive">
|
||||
<table className="admin-table">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Značka</th>
|
||||
<th>Model</th>
|
||||
<th>SPZ</th>
|
||||
<th>Rok</th>
|
||||
<th>Akce</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{Array.from({ length: 5 }, (_, i) => (
|
||||
<tr key={i}>
|
||||
<td>Škoda</td>
|
||||
<td>Octavia</td>
|
||||
<td className="admin-mono">1A2 3456</td>
|
||||
<td>2024</td>
|
||||
<td>
|
||||
<div className="admin-table-actions">
|
||||
<button className="admin-btn-icon">✎</button>
|
||||
<button className="admin-btn-icon danger">🗑</button>
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
))}
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
import { useCallback, useRef } from "react";
|
||||
import { useAlert } from "../context/AlertContext";
|
||||
import apiFetch from "../utils/api";
|
||||
|
||||
interface ApiCallResult<T> {
|
||||
data: T | null;
|
||||
ok: boolean;
|
||||
response: Response | null;
|
||||
}
|
||||
|
||||
export default function useApiCall() {
|
||||
const alert = useAlert();
|
||||
const abortRef = useRef<AbortController | null>(null);
|
||||
|
||||
const call = useCallback(
|
||||
async <T = unknown>(
|
||||
url: string,
|
||||
options: RequestInit = {},
|
||||
errorMsg = "Chyba při načítání dat",
|
||||
): Promise<ApiCallResult<T>> => {
|
||||
if (abortRef.current) abortRef.current.abort();
|
||||
const controller = new AbortController();
|
||||
abortRef.current = controller;
|
||||
|
||||
try {
|
||||
const { signal: _, ...restOptions } = options;
|
||||
const response = await apiFetch(url, {
|
||||
...restOptions,
|
||||
signal: controller.signal,
|
||||
});
|
||||
const data = await response.json();
|
||||
if (!response.ok || !data.success) {
|
||||
alert.error(data.error || errorMsg);
|
||||
return { data: null, ok: false, response };
|
||||
}
|
||||
return { data: data.data as T, ok: true, response };
|
||||
} catch (err: unknown) {
|
||||
if (err instanceof Error && err.name === "AbortError") {
|
||||
return { data: null, ok: false, response: null };
|
||||
}
|
||||
alert.error(errorMsg);
|
||||
return { data: null, ok: false, response: null };
|
||||
}
|
||||
},
|
||||
[alert],
|
||||
);
|
||||
|
||||
return { call };
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
import { useState, useEffect, useCallback, useRef } from "react";
|
||||
import { useQueryClient } from "@tanstack/react-query";
|
||||
import apiFetch from "../utils/api";
|
||||
import { isHoliday } from "../../utils/czech-holidays";
|
||||
import {
|
||||
calcProjectMinutesTotal,
|
||||
calcFormWorkMinutes,
|
||||
@@ -9,9 +11,17 @@ import {
|
||||
formatDate,
|
||||
formatMinutes,
|
||||
getLeaveTypeName,
|
||||
getLeaveTypeBadgeClass,
|
||||
formatTimeOrDatetimePrint,
|
||||
calculateWorkMinutesPrint,
|
||||
isWeekendDate,
|
||||
getDaysInMonth,
|
||||
shiftDateForMonth,
|
||||
formatHoursDecimal,
|
||||
calculateNightMinutes,
|
||||
normalizeDateStr,
|
||||
holidaysInMonth,
|
||||
calculateFreeHolidayHours,
|
||||
getCzechWeekday,
|
||||
} from "../utils/attendanceHelpers";
|
||||
import type {
|
||||
ShiftFormData,
|
||||
@@ -28,7 +38,7 @@ interface AlertContext {
|
||||
alert: { success: (msg: string) => void; error: (msg: string) => void };
|
||||
}
|
||||
|
||||
interface AttendanceRecord {
|
||||
export interface AttendanceRecord {
|
||||
id: number;
|
||||
user_id: number;
|
||||
shift_date: string;
|
||||
@@ -38,7 +48,7 @@ interface AttendanceRecord {
|
||||
departure_time?: string | null;
|
||||
break_start?: string | null;
|
||||
break_end?: string | null;
|
||||
notes?: string;
|
||||
notes?: string | null;
|
||||
project_id?: number | null;
|
||||
project_name?: string;
|
||||
project_logs?: Array<{
|
||||
@@ -72,7 +82,6 @@ interface UserTotal {
|
||||
working: boolean;
|
||||
vacation_hours: number;
|
||||
sick_hours: number;
|
||||
holiday_hours: number;
|
||||
unpaid_hours: number;
|
||||
overtime: number;
|
||||
missing: number;
|
||||
@@ -80,6 +89,16 @@ interface UserTotal {
|
||||
business_days: number;
|
||||
worked_hours: number;
|
||||
covered: number;
|
||||
// mzda-style summary fields (set by computeUserTotals)
|
||||
worked_hours_raw?: number;
|
||||
odpracovano?: number;
|
||||
vcetne_svatku?: number;
|
||||
prescas?: number;
|
||||
svatek?: number;
|
||||
weekend_hours?: number;
|
||||
night_minutes?: number;
|
||||
worked_holiday_hours?: number; // sum of hours worked ON a holiday
|
||||
records?: AttendanceRecord[];
|
||||
}
|
||||
|
||||
interface LeaveBalance {
|
||||
@@ -120,6 +139,11 @@ const combineDatetime = (date: string, time: string): string | null =>
|
||||
/**
|
||||
* Compute per-user totals from raw attendance records.
|
||||
* This replaces the server-side `user_totals` that the PHP backend returned.
|
||||
*
|
||||
* Adds mzda-style summary fields (odpracovano, vcetne_svatku, prescas, svatek,
|
||||
* weekend_hours, night_minutes) and a fund computed as
|
||||
* (rawBizDays + holidayCount) × 8 — holidays count as work days for fund
|
||||
* purposes, per the mzda.pdf model.
|
||||
*/
|
||||
function computeUserTotals(
|
||||
records: AttendanceRecord[],
|
||||
@@ -127,6 +151,7 @@ function computeUserTotals(
|
||||
month: string,
|
||||
): Record<string, UserTotal> {
|
||||
const totals: Record<string, UserTotal> = {};
|
||||
const recordsByUser = new Map<number, AttendanceRecord[]>();
|
||||
|
||||
for (const rec of records) {
|
||||
const uid = String(rec.user_id);
|
||||
@@ -143,7 +168,6 @@ function computeUserTotals(
|
||||
working: false,
|
||||
vacation_hours: 0,
|
||||
sick_hours: 0,
|
||||
holiday_hours: 0,
|
||||
unpaid_hours: 0,
|
||||
overtime: 0,
|
||||
missing: 0,
|
||||
@@ -151,15 +175,23 @@ function computeUserTotals(
|
||||
business_days: 0,
|
||||
worked_hours: 0,
|
||||
covered: 0,
|
||||
records: [],
|
||||
};
|
||||
}
|
||||
|
||||
const t = totals[uid];
|
||||
t.records!.push(rec);
|
||||
if (!recordsByUser.has(rec.user_id)) recordsByUser.set(rec.user_id, []);
|
||||
recordsByUser.get(rec.user_id)!.push(rec);
|
||||
|
||||
const leaveType = rec.leave_type || "work";
|
||||
|
||||
if (leaveType === "work") {
|
||||
// Only work records contribute to "minutes" (matching PHP calculateUserTotals)
|
||||
t.minutes += calculateWorkMinutes(rec);
|
||||
t.minutes += calculateWorkMinutes({
|
||||
...rec,
|
||||
notes: rec.notes ?? undefined,
|
||||
});
|
||||
} else {
|
||||
const leaveHours = Number(rec.leave_hours) || 8;
|
||||
switch (leaveType) {
|
||||
@@ -169,12 +201,14 @@ function computeUserTotals(
|
||||
case "sick":
|
||||
t.sick_hours += leaveHours;
|
||||
break;
|
||||
case "holiday":
|
||||
t.holiday_hours += leaveHours;
|
||||
break;
|
||||
case "unpaid":
|
||||
t.unpaid_hours += leaveHours;
|
||||
break;
|
||||
// "holiday" leave_type is no longer selectable in the UI — it is
|
||||
// auto-computed from Czech public holidays (see freeHolidayHours
|
||||
// below). Old records may still exist in the DB; treat them as a
|
||||
// paid non-work entry and skip so they don't double-count with
|
||||
// the auto-detected svátek.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -189,7 +223,10 @@ function computeUserTotals(
|
||||
const yr = parseInt(yearStr, 10);
|
||||
const mo = parseInt(monthStr, 10) - 1;
|
||||
|
||||
// Count business days in month (Mon-Fri)
|
||||
// Count Mon-Fri business days in month (INCLUDING holidays).
|
||||
// The fund is rawBizDays × 8 — holidays stay in the count so the
|
||||
// user is paid for them via the fund. Svátek (free holiday hours) is
|
||||
// computed separately as "8h per holiday the user did not work".
|
||||
let rawBizDays = 0;
|
||||
const cur = new Date(yr, mo, 1);
|
||||
while (cur.getMonth() === mo) {
|
||||
@@ -198,23 +235,100 @@ function computeUserTotals(
|
||||
cur.setDate(cur.getDate() + 1);
|
||||
}
|
||||
|
||||
const holidayDates = holidaysInMonth(yr, mo + 1);
|
||||
const holidayCount = holidayDates.length;
|
||||
|
||||
for (const uid of Object.keys(totals)) {
|
||||
const t = totals[uid];
|
||||
// Subtract holiday days from business days for this user
|
||||
const holidayDays = Math.round(t.holiday_hours / 8);
|
||||
const bizDays = Math.max(0, rawBizDays - holidayDays);
|
||||
const fund = bizDays * 8;
|
||||
const workedHours = Math.round((t.minutes / 60) * 10) / 10;
|
||||
// Covered = worked + vacation + sick (NOT holiday/unpaid — matching PHP)
|
||||
const leaveHours = t.vacation_hours + t.sick_hours;
|
||||
const covered = Math.round((workedHours + leaveHours) * 10) / 10;
|
||||
const userRecords = recordsByUser.get(Number(uid)) || [];
|
||||
|
||||
// Odpracováno: floor(worked / 8) × 8 — round to whole days, drop remainder.
|
||||
const workedHoursRaw = t.minutes / 60;
|
||||
const odpracovano = Math.floor(workedHoursRaw / 8) * 8;
|
||||
|
||||
// So/Ne: sum of worked hours on Sat/Sun (raw, not rounded).
|
||||
const weekendHours = userRecords
|
||||
.filter(
|
||||
(r) =>
|
||||
(r.leave_type || "work") === "work" && isWeekendDate(r.shift_date),
|
||||
)
|
||||
.reduce((sum, r) => sum + calculateWorkMinutesPrint(r) / 60, 0);
|
||||
|
||||
// Práce v noci: minutes in 22:00-06:00 across all work records.
|
||||
const nightMinutes = userRecords
|
||||
.filter((r) => (r.leave_type || "work") === "work")
|
||||
.reduce((sum, r) => sum + calculateNightMinutes(r), 0);
|
||||
|
||||
// Svátek (free): 8h per holiday the user did not work.
|
||||
const freeHolidayHours = calculateFreeHolidayHours(
|
||||
userRecords,
|
||||
holidayDates,
|
||||
);
|
||||
|
||||
// Worked holidays: holidays the user DID work (counted toward
|
||||
// Odpracováno, but their 8h must not flow into Přesčas).
|
||||
const workedDatesSet = new Set(
|
||||
userRecords
|
||||
.filter((r) => (r.leave_type || "work") === "work")
|
||||
.map((r) => normalizeDateStr(r.shift_date))
|
||||
.filter(Boolean),
|
||||
);
|
||||
let workedHolidayCount = 0;
|
||||
let workedHolidayHours = 0;
|
||||
for (const hd of holidayDates) {
|
||||
if (workedDatesSet.has(hd)) workedHolidayCount++;
|
||||
}
|
||||
// Sum the actual hours worked on holiday dates (for the KPI card's
|
||||
// "fond used" total = real_work + vacation + worked_holiday + free_holiday).
|
||||
for (const r of userRecords) {
|
||||
if ((r.leave_type || "work") !== "work") continue;
|
||||
const d = normalizeDateStr(r.shift_date);
|
||||
if (d && holidayDates.includes(d)) {
|
||||
workedHolidayHours += calculateWorkMinutesPrint(r) / 60;
|
||||
}
|
||||
}
|
||||
|
||||
// Fund = Mon-Fri × 8h. Holidays count as work days (already in rawBizDays).
|
||||
const fund = rawBizDays * 8;
|
||||
|
||||
// Včetně svátků a přesčasů (mzda formula):
|
||||
// odpracovano + vacation + remainder − min(freeHols, workedHols × 8)
|
||||
//
|
||||
// Two-way logic matching the print:
|
||||
// • If the user worked at least one holiday, that worked holiday's
|
||||
// 8h is in Odpracováno and shouldn't also count as Přesčas. We
|
||||
// subtract one 8h per worked holiday (capped at the total free
|
||||
// holiday hours — can't go negative).
|
||||
// • If the user did NOT work any holiday, no adjustment is needed:
|
||||
// all unworked holidays are already paid via the Svátek line and
|
||||
// don't flow into Přesčas, so vcetne_svatku just equals the
|
||||
// work + vacation + remainder.
|
||||
const remainder = workedHoursRaw - odpracovano;
|
||||
const holidayAdj = Math.min(freeHolidayHours, workedHolidayCount * 8);
|
||||
const vcetneSv = odpracovano - holidayAdj + t.vacation_hours + remainder;
|
||||
|
||||
// Přesčas = vcetneSv − odpracovano (derived).
|
||||
const prescas = vcetneSv - odpracovano;
|
||||
|
||||
// Legacy fields (kept so existing UI doesn't break).
|
||||
const workedHours = Math.round(workedHoursRaw * 10) / 10;
|
||||
const covered = Math.round((workedHours + t.vacation_hours) * 10) / 10;
|
||||
|
||||
t.fund = fund;
|
||||
t.business_days = bizDays;
|
||||
t.business_days = rawBizDays;
|
||||
t.worked_hours = workedHours;
|
||||
t.covered = covered;
|
||||
t.missing = Math.max(0, Math.round((fund - covered) * 10) / 10);
|
||||
t.overtime = Math.max(0, Math.round((covered - fund) * 10) / 10);
|
||||
|
||||
t.worked_hours_raw = workedHoursRaw;
|
||||
t.odpracovano = odpracovano;
|
||||
t.vcetne_svatku = vcetneSv;
|
||||
t.prescas = prescas;
|
||||
t.svatek = freeHolidayHours;
|
||||
t.weekend_hours = weekendHours;
|
||||
t.night_minutes = nightMinutes;
|
||||
t.worked_holiday_hours = workedHolidayHours;
|
||||
}
|
||||
|
||||
return totals;
|
||||
@@ -233,14 +347,6 @@ function escapeHtml(str: string): string {
|
||||
.replace(/'/g, "'");
|
||||
}
|
||||
|
||||
function renderFundStatus(userData: Record<string, any>): string {
|
||||
if (userData.overtime > 0)
|
||||
return `<span class="leave-badge badge-overtime">+${escapeHtml(String(userData.overtime))}h přesčas</span>`;
|
||||
if (userData.missing > 0)
|
||||
return `<span style="color:#dc2626">−${escapeHtml(String(userData.missing))}h</span>`;
|
||||
return '<span style="color:#16a34a">splněno</span>';
|
||||
}
|
||||
|
||||
function buildProjectLogsHtml(record: Record<string, any>): string {
|
||||
if (record.project_logs && record.project_logs.length > 0) {
|
||||
return record.project_logs
|
||||
@@ -271,94 +377,220 @@ function buildProjectLogsHtml(record: Record<string, any>): string {
|
||||
return escapeHtml(record.project_name || "—");
|
||||
}
|
||||
|
||||
function buildLeaveSummaryHtml(
|
||||
userId: string,
|
||||
userData: Record<string, any>,
|
||||
printData: Record<string, any>,
|
||||
): string {
|
||||
const bal = printData.leave_balances[userId];
|
||||
let parts = `<strong>Dovolená ${escapeHtml(String(printData.year))}:</strong> Zbývá ${bal.vacation_remaining.toFixed(1)}h z ${bal.vacation_total}h`;
|
||||
if (userData.vacation_hours > 0)
|
||||
parts += ` | <span class="leave-badge badge-vacation">Tento měsíc: ${escapeHtml(String(userData.vacation_hours))}h</span>`;
|
||||
if (userData.sick_hours > 0)
|
||||
parts += ` | <span class="leave-badge badge-sick">Nemoc: ${escapeHtml(String(userData.sick_hours))}h</span>`;
|
||||
if (userData.holiday_hours > 0)
|
||||
parts += ` | <span class="leave-badge badge-holiday">Svátek: ${escapeHtml(String(userData.holiday_hours))}h</span>`;
|
||||
if (userData.overtime > 0)
|
||||
parts += ` | <span class="leave-badge badge-overtime">Přesčas: +${escapeHtml(String(userData.overtime))}h</span>`;
|
||||
return `<div class="leave-summary">${parts}</div>`;
|
||||
}
|
||||
|
||||
function buildUserSectionHtml(
|
||||
userId: string,
|
||||
userData: Record<string, any>,
|
||||
printData: Record<string, any>,
|
||||
): string {
|
||||
const leaveHtml = printData.leave_balances[userId]
|
||||
? buildLeaveSummaryHtml(userId, userData, printData)
|
||||
: "";
|
||||
// Build a date-keyed lookup of the user's records.
|
||||
const recordsByDate = new Map<string, Record<string, any>>();
|
||||
for (const r of userData.records || []) {
|
||||
recordsByDate.set(normalizeDateStr(r.shift_date), r);
|
||||
}
|
||||
|
||||
const recordRows = (userData.records || [])
|
||||
.map((record: any) => {
|
||||
const leaveType = record.leave_type || "work";
|
||||
const isLeave = leaveType !== "work";
|
||||
const workMinutes = calculateWorkMinutesPrint(record);
|
||||
const hours = Math.floor(workMinutes / 60);
|
||||
const mins = workMinutes % 60;
|
||||
const breakCell =
|
||||
isLeave || !record.break_start || !record.break_end
|
||||
? "—"
|
||||
: `${escapeHtml(formatTimeOrDatetimePrint(record.break_start, record.shift_date))} - ${escapeHtml(formatTimeOrDatetimePrint(record.break_end, record.shift_date))}`;
|
||||
// Iterate one row per day of the month.
|
||||
const [yearStr, monthStr] = printData.month.split("-");
|
||||
const yr = parseInt(yearStr, 10);
|
||||
const mo = parseInt(monthStr, 10);
|
||||
const daysInMonth = getDaysInMonth(yr, mo);
|
||||
|
||||
return `<tr>
|
||||
<td>${escapeHtml(formatDate(record.shift_date))}</td>
|
||||
<td><span class="leave-badge ${escapeHtml(getLeaveTypeBadgeClass(leaveType))}">${escapeHtml(getLeaveTypeName(leaveType))}</span></td>
|
||||
const userRecords = (userData.records || []) as Record<string, any>[];
|
||||
|
||||
const rows: string[] = [];
|
||||
for (let d = 1; d <= daysInMonth; d++) {
|
||||
const dateStr = shiftDateForMonth(yr, mo, d);
|
||||
const record = recordsByDate.get(dateStr);
|
||||
const weekend = isWeekendDate(dateStr);
|
||||
const holiday = isHoliday(dateStr);
|
||||
const leaveType = (record?.leave_type as string) || "work";
|
||||
const rowClasses = [
|
||||
weekend && "weekend",
|
||||
holiday && "holiday",
|
||||
leaveType === "vacation" && "vacation",
|
||||
]
|
||||
.filter(Boolean)
|
||||
.join(" ");
|
||||
|
||||
if (!record) {
|
||||
rows.push(`<tr class="${rowClasses}">
|
||||
<td>${escapeHtml(formatDate(dateStr))}</td>
|
||||
<td>${escapeHtml(getCzechWeekday(dateStr))}</td>
|
||||
<td>—</td>
|
||||
<td class="text-center">—</td>
|
||||
<td class="text-center">—</td>
|
||||
<td class="text-center">—</td>
|
||||
<td class="text-center">—</td>
|
||||
<td></td>
|
||||
<td></td>
|
||||
</tr>`);
|
||||
continue;
|
||||
}
|
||||
|
||||
const isLeave = leaveType !== "work";
|
||||
const workMinutes = calculateWorkMinutesPrint(record);
|
||||
const hours = Math.floor(workMinutes / 60);
|
||||
const mins = workMinutes % 60;
|
||||
const breakCell =
|
||||
isLeave || !record.break_start || !record.break_end
|
||||
? "—"
|
||||
: `${escapeHtml(formatTimeOrDatetimePrint(record.break_start, record.shift_date))} - ${escapeHtml(formatTimeOrDatetimePrint(record.break_end, record.shift_date))}`;
|
||||
|
||||
let hoursCell: string;
|
||||
if (workMinutes > 0 && !isLeave) {
|
||||
hoursCell = `${hours}:${String(mins).padStart(2, "0")} (${formatHoursDecimal(workMinutes)})`;
|
||||
} else if (isLeave) {
|
||||
hoursCell = formatHoursDecimal((Number(record.leave_hours) || 8) * 60);
|
||||
} else {
|
||||
hoursCell = "—";
|
||||
}
|
||||
|
||||
rows.push(`<tr class="${rowClasses}">
|
||||
<td>${escapeHtml(formatDate(dateStr))}</td>
|
||||
<td>${escapeHtml(getCzechWeekday(dateStr))}</td>
|
||||
<td>${escapeHtml(getLeaveTypeName(leaveType))}</td>
|
||||
<td class="text-center">${isLeave ? "—" : escapeHtml(formatTimeOrDatetimePrint(record.arrival_time, record.shift_date))}</td>
|
||||
<td class="text-center">${breakCell}</td>
|
||||
<td class="text-center">${isLeave ? "—" : escapeHtml(formatTimeOrDatetimePrint(record.departure_time, record.shift_date))}</td>
|
||||
<td class="text-center">${workMinutes > 0 ? `${hours}:${String(mins).padStart(2, "0")}` : "—"}</td>
|
||||
<td class="text-center">${hoursCell}</td>
|
||||
<td style="font-size:8px">${buildProjectLogsHtml(record)}</td>
|
||||
<td>${escapeHtml(record.notes || "")}</td>
|
||||
</tr>`;
|
||||
})
|
||||
.join("");
|
||||
</tr>`);
|
||||
}
|
||||
|
||||
const fundRow =
|
||||
userData.fund !== null
|
||||
? `<tr>
|
||||
<td colspan="6" class="text-right">Fond měsíce:</td>
|
||||
<td class="text-center">${escapeHtml(String(userData.covered))}h / ${escapeHtml(String(userData.fund))}h</td>
|
||||
<td colspan="2">${renderFundStatus(userData)}</td>
|
||||
</tr>`
|
||||
: "";
|
||||
// ----- mzda-style summary numbers (computed here, not from userData,
|
||||
// because the backend's getPrintData only returns the legacy fields). -----
|
||||
|
||||
// Worked minutes: sum of calculateWorkMinutesPrint across work records.
|
||||
let workedMinutes = 0;
|
||||
let weekendHoursRaw = 0;
|
||||
let nightMinutes = 0;
|
||||
for (const r of userRecords) {
|
||||
const leaveType = r.leave_type || "work";
|
||||
if (leaveType !== "work") continue;
|
||||
const m = calculateWorkMinutesPrint(r);
|
||||
workedMinutes += m;
|
||||
if (isWeekendDate(r.shift_date)) {
|
||||
weekendHoursRaw += m / 60;
|
||||
}
|
||||
nightMinutes += calculateNightMinutes(r);
|
||||
}
|
||||
|
||||
// Sum of vacation/sick/unpaid hours (in hours, not minutes). The
|
||||
// "holiday" leave_type is auto-computed from Czech holidays further down
|
||||
// and no longer selectable in the UI, so it's deliberately omitted here.
|
||||
let vacationHours = 0,
|
||||
sickHours = 0;
|
||||
for (const r of userRecords) {
|
||||
const lt = r.leave_type || "work";
|
||||
if (lt === "work") continue;
|
||||
const h = Number(r.leave_hours) || 8;
|
||||
if (lt === "vacation") vacationHours += h;
|
||||
else if (lt === "sick") sickHours += h;
|
||||
}
|
||||
|
||||
// Odpracováno: floor(worked / 8) × 8.
|
||||
const workedHoursRaw = workedMinutes / 60;
|
||||
const odpracovano = Math.floor(workedHoursRaw / 8) * 8;
|
||||
|
||||
// Free Svátek: 8h per holiday date the user did not work.
|
||||
const holidayDates = holidaysInMonth(yr, mo);
|
||||
const holidayCount = holidayDates.length;
|
||||
const workedDates = new Set(
|
||||
userRecords
|
||||
.filter((r) => (r.leave_type || "work") === "work")
|
||||
.map((r) => normalizeDateStr(r.shift_date))
|
||||
.filter(Boolean),
|
||||
);
|
||||
let freeHolidayHours = 0;
|
||||
let workedHolidayCount = 0;
|
||||
for (const hd of holidayDates) {
|
||||
if (workedDates.has(hd)) workedHolidayCount++;
|
||||
else freeHolidayHours += 8;
|
||||
}
|
||||
|
||||
// Fund: count Mon-Fri (incl. holidays) × 8h.
|
||||
let rawBizDays = 0;
|
||||
const cur = new Date(yr, mo - 1, 1);
|
||||
while (cur.getMonth() === mo - 1) {
|
||||
const dow = cur.getDay();
|
||||
if (dow !== 0 && dow !== 6) rawBizDays++;
|
||||
cur.setDate(cur.getDate() + 1);
|
||||
}
|
||||
const businessDays = rawBizDays;
|
||||
const fund = businessDays * 8;
|
||||
|
||||
// Včetně svátků a přesčasů: floor(worked/8)*8 − worked_holiday*8 + vacation + remainder.
|
||||
// (A worked holiday counts toward Odpracováno, but its 8h should not flow
|
||||
// into Přesčas — so we subtract it here. Unworked holidays are paid via
|
||||
// the fund and don't affect this line.)
|
||||
const remainder = workedHoursRaw - odpracovano;
|
||||
const vcetneSv =
|
||||
odpracovano - workedHolidayCount * 8 + vacationHours + remainder;
|
||||
|
||||
// Přesčas = #2 - #1.
|
||||
const prescas = vcetneSv - odpracovano;
|
||||
|
||||
const summaryHtml = `<div class="user-summary">
|
||||
<div class="summary-row">
|
||||
<span class="summary-label">Odpracováno:</span>
|
||||
<span class="summary-value">${formatHoursDecimal(odpracovano * 60)}h</span>
|
||||
</div>
|
||||
<div class="summary-row">
|
||||
<span class="summary-label">Odpracováno včetně svátků a přesčasů:</span>
|
||||
<span class="summary-value">${formatHoursDecimal(vcetneSv * 60)}h</span>
|
||||
</div>
|
||||
<div class="summary-row">
|
||||
<span class="summary-label">Dovolená:</span>
|
||||
<span class="summary-value">${formatHoursDecimal(vacationHours * 60)}h</span>
|
||||
</div>
|
||||
<div class="summary-row">
|
||||
<span class="summary-label">Přesčas:</span>
|
||||
<span class="summary-value">${formatHoursDecimal(prescas * 60)}h</span>
|
||||
</div>
|
||||
<div class="summary-row">
|
||||
<span class="summary-label">Svátek:</span>
|
||||
<span class="summary-value">${formatHoursDecimal(freeHolidayHours * 60)}h</span>
|
||||
</div>
|
||||
<div class="summary-row">
|
||||
<span class="summary-label">So/Ne:</span>
|
||||
<span class="summary-value">${formatHoursDecimal(weekendHoursRaw * 60)}h</span>
|
||||
</div>
|
||||
<div class="summary-row">
|
||||
<span class="summary-label">Práce v noci:</span>
|
||||
<span class="summary-value">${formatHoursDecimal(nightMinutes)}h</span>
|
||||
</div>
|
||||
<div class="summary-row summary-fund">
|
||||
<span class="summary-label">Fond měsíce:</span>
|
||||
<span class="summary-value">${formatHoursDecimal(fund * 60)}h (${businessDays} dnů)</span>
|
||||
</div>
|
||||
<div class="legend">
|
||||
<span class="legend-item"><span class="legend-swatch weekend"></span>Víkend (So/Ne)</span>
|
||||
<span class="legend-item"><span class="legend-swatch holiday"></span>Svátek</span>
|
||||
<span class="legend-item"><span class="legend-swatch weekend-holiday"></span>Víkend + svátek</span>
|
||||
<span class="legend-item"><span class="legend-swatch vacation"></span>Dovolená</span>
|
||||
</div>
|
||||
</div>`;
|
||||
|
||||
return `<div class="user-section">
|
||||
<div class="user-header">
|
||||
<h3>${escapeHtml(userData.name)}</h3>
|
||||
<span class="total">Odpracováno: ${escapeHtml(formatMinutes(userData.minutes))} h</span>
|
||||
</div>
|
||||
${leaveHtml}
|
||||
<table>
|
||||
<thead><tr>
|
||||
<th style="width:70px">Datum</th>
|
||||
<th style="width:70px">Typ</th>
|
||||
<th class="text-center" style="width:70px">Příchod</th>
|
||||
<th class="text-center" style="width:90px">Pauza</th>
|
||||
<th class="text-center" style="width:70px">Odchod</th>
|
||||
<th class="text-center" style="width:80px">Hodiny</th>
|
||||
<th style="width:55px">Datum</th>
|
||||
<th style="width:55px">Den</th>
|
||||
<th style="width:60px">Typ</th>
|
||||
<th class="text-center" style="width:55px">Příchod</th>
|
||||
<th class="text-center" style="width:80px">Pauza</th>
|
||||
<th class="text-center" style="width:55px">Odchod</th>
|
||||
<th class="text-center" style="width:85px">Hodiny</th>
|
||||
<th>Projekty</th>
|
||||
<th>Poznámka</th>
|
||||
</tr></thead>
|
||||
<tbody>${recordRows}</tbody>
|
||||
<tfoot>
|
||||
<tr>
|
||||
<td colspan="6" class="text-right">Odpracováno:</td>
|
||||
<td class="text-center">${escapeHtml(formatMinutes(userData.minutes))} h</td>
|
||||
<td colspan="2"></td>
|
||||
</tr>
|
||||
${fundRow}
|
||||
</tfoot>
|
||||
<tbody>${rows.join("")}</tbody>
|
||||
</table>
|
||||
${summaryHtml}
|
||||
</div>`;
|
||||
}
|
||||
|
||||
@@ -376,7 +608,13 @@ function buildPrintHtml(
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Docházka - ${escapeHtml(pData.month_name)}</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
* {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
box-sizing: border-box;
|
||||
-webkit-print-color-adjust: exact;
|
||||
print-color-adjust: exact;
|
||||
}
|
||||
body {
|
||||
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
|
||||
font-size: 11px; line-height: 1.4; color: #000; background: #fff; padding: 15mm;
|
||||
@@ -406,19 +644,47 @@ function buildPrintHtml(
|
||||
.user-section th { background: #333; color: #fff; font-weight: 600; font-size: 10px; text-transform: uppercase; }
|
||||
.user-section td { font-size: 10px; }
|
||||
.user-section tr:nth-child(even) { background: #f9f9f9; }
|
||||
/* Weekend and holiday row highlighting — must come after the
|
||||
:nth-child(even) rule and use higher specificity (tr.X td) to win. */
|
||||
.user-section tr.weekend td { background: #fde68a; }
|
||||
.user-section tr.holiday td { background: #bbf7d0; }
|
||||
.user-section tr.weekend.holiday td { background: #fcd34d; }
|
||||
.user-section tr.vacation td { background: #bfdbfe; }
|
||||
.text-center { text-align: center; }
|
||||
.text-right { text-align: right; }
|
||||
.user-section tfoot td { background: #eee; font-weight: 600; }
|
||||
.leave-badge { display: inline-block; padding: 2px 6px; border-radius: 3px; font-size: 9px; font-weight: 500; }
|
||||
.badge-vacation { background: #dbeafe; color: #1d4ed8; }
|
||||
.badge-sick { background: #fee2e2; color: #dc2626; }
|
||||
.badge-holiday { background: #dcfce7; color: #16a34a; }
|
||||
.badge-unpaid { background: #f3f4f6; color: #6b7280; }
|
||||
.badge-overtime { background: #fef3c7; color: #d97706; }
|
||||
.leave-summary {
|
||||
margin-top: 10px; padding: 8px 15px; background: #f9f9f9;
|
||||
border: 1px solid #ddd; font-size: 10px;
|
||||
.user-summary {
|
||||
margin-top: 10px; padding: 10px 15px;
|
||||
background: #f9f9f9; border: 1px solid #ddd; font-size: 10px;
|
||||
}
|
||||
.user-summary .summary-row {
|
||||
display: flex; justify-content: space-between; padding: 2px 0;
|
||||
}
|
||||
.user-summary .summary-label { color: #555; }
|
||||
.user-summary .summary-value { font-weight: 600; }
|
||||
.user-summary .summary-fund {
|
||||
border-top: 1px solid #ddd; margin-top: 4px; padding-top: 6px;
|
||||
}
|
||||
.legend {
|
||||
display: flex; flex-wrap: wrap; gap: 14px;
|
||||
margin-top: 8px; padding-top: 6px;
|
||||
border-top: 1px dashed #ddd;
|
||||
font-size: 9px; color: #555;
|
||||
}
|
||||
.legend-item { display: inline-flex; align-items: center; gap: 5px; }
|
||||
.legend-swatch {
|
||||
display: inline-block; width: 12px; height: 12px;
|
||||
border: 1px solid #333; vertical-align: middle;
|
||||
}
|
||||
.legend-swatch.weekend { background: #fde68a; }
|
||||
.legend-swatch.holiday { background: #bbf7d0; }
|
||||
.legend-swatch.weekend-holiday { background: #fcd34d; }
|
||||
.legend-swatch.vacation { background: #bfdbfe; }
|
||||
.print-wrapper-table { width: 100%; border-collapse: collapse; border: none; }
|
||||
.print-wrapper-table > thead > tr > td,
|
||||
.print-wrapper-table > tbody > tr > td { padding: 0; border: none; background: none; }
|
||||
@@ -461,6 +727,7 @@ function buildPrintHtml(
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
export default function useAttendanceAdmin({ alert }: AlertContext) {
|
||||
const queryClient = useQueryClient();
|
||||
// ---- Core state ----
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [month, setMonth] = useState(() => {
|
||||
@@ -662,7 +929,15 @@ export default function useAttendanceAdmin({ alert }: AlertContext) {
|
||||
formData: ShiftFormData,
|
||||
): boolean => {
|
||||
const totalWork = calcFormWorkMinutes(formData);
|
||||
const totalProject = calcProjectMinutesTotal(logs);
|
||||
const totalProject = calcProjectMinutesTotal(
|
||||
logs.map((l) => ({
|
||||
...l,
|
||||
project_id:
|
||||
l.project_id !== "" && l.project_id != null
|
||||
? Number(l.project_id)
|
||||
: undefined,
|
||||
})),
|
||||
);
|
||||
if (totalWork > 0 && totalProject !== totalWork) {
|
||||
const wH = Math.floor(totalWork / 60);
|
||||
const wM = totalWork % 60;
|
||||
@@ -771,6 +1046,7 @@ export default function useAttendanceAdmin({ alert }: AlertContext) {
|
||||
|
||||
if (result.success) {
|
||||
setShowCreateModal(false);
|
||||
queryClient.invalidateQueries({ queryKey: ["attendance"] });
|
||||
await fetchData(false);
|
||||
await new Promise((resolve) => setTimeout(resolve, 300));
|
||||
alert.success(
|
||||
@@ -842,6 +1118,7 @@ export default function useAttendanceAdmin({ alert }: AlertContext) {
|
||||
|
||||
if (result.success) {
|
||||
setShowBulkModal(false);
|
||||
queryClient.invalidateQueries({ queryKey: ["attendance"] });
|
||||
await fetchData(false);
|
||||
await new Promise((resolve) => setTimeout(resolve, 300));
|
||||
alert.success(
|
||||
@@ -865,7 +1142,7 @@ export default function useAttendanceAdmin({ alert }: AlertContext) {
|
||||
const userName = record.users
|
||||
? `${record.users.first_name} ${record.users.last_name}`.trim() ||
|
||||
record.users.username
|
||||
: ((record as Record<string, unknown>).user_name as string) ||
|
||||
: ((record as unknown as Record<string, unknown>).user_name as string) ||
|
||||
`User #${record.user_id}`;
|
||||
const enriched = { ...record, user_name: userName };
|
||||
setEditingRecord(enriched);
|
||||
@@ -976,6 +1253,7 @@ export default function useAttendanceAdmin({ alert }: AlertContext) {
|
||||
|
||||
if (result.success) {
|
||||
setShowEditModal(false);
|
||||
queryClient.invalidateQueries({ queryKey: ["attendance"] });
|
||||
await fetchData(false);
|
||||
await new Promise((resolve) => setTimeout(resolve, 300));
|
||||
alert.success(
|
||||
@@ -1005,6 +1283,7 @@ export default function useAttendanceAdmin({ alert }: AlertContext) {
|
||||
|
||||
if (result.success) {
|
||||
setDeleteConfirm({ show: false, record: null });
|
||||
queryClient.invalidateQueries({ queryKey: ["attendance"] });
|
||||
await fetchData(false);
|
||||
alert.success(
|
||||
result.message || result.data?.message || "Záznam smazán",
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user