diff --git a/app/resources/js/components/projects/ProjectDetailsDrawer.vue b/app/resources/js/components/projects/ProjectDetailsDrawer.vue
index ee62da50..1c653433 100644
--- a/app/resources/js/components/projects/ProjectDetailsDrawer.vue
+++ b/app/resources/js/components/projects/ProjectDetailsDrawer.vue
@@ -1,14 +1,104 @@
@@ -26,4 +116,20 @@ defineEmits<{ close: []; saved: [] }>();
z-index: 5;
}
.project-details-drawer.open { transform: translateX(0); }
+.pdd-content { display: flex; flex-direction: column; height: 100%; }
+.pdd-head { display: flex; justify-content: space-between; align-items: center; padding: 16px 20px; border-bottom: 1px solid var(--liderra-line, #e6e2d6); }
+.pdd-title { font-weight: 600; font-size: 16px; }
+.pdd-close { background: none; border: 0; cursor: pointer; font-size: 18px; padding: 4px; }
+.pdd-body { padding: 16px 20px; display: flex; flex-direction: column; gap: 14px; flex: 1; overflow-y: auto; }
+.pdd-field { display: flex; flex-direction: column; gap: 4px; }
+.pdd-label { font-size: 12px; color: #6b6f72; }
+.pdd-input { padding: 8px 10px; border: 1px solid var(--liderra-line, #e6e2d6); border-radius: 6px; font: inherit; }
+.pdd-days { display: flex; gap: 4px; }
+.pdd-day { padding: 6px 10px; border: 1px solid var(--liderra-line, #e6e2d6); background: #ffffff; border-radius: 4px; cursor: pointer; font: inherit; }
+.pdd-day.active { background: #0f6e56; color: #ffffff; border-color: #0f6e56; }
+.pdd-foot { display: flex; justify-content: space-between; padding: 12px 20px; border-top: 1px solid var(--liderra-line, #e6e2d6); }
+.pdd-foot-left, .pdd-foot-right { display: flex; gap: 8px; }
+.pdd-btn { padding: 6px 14px; border: 0; border-radius: 6px; cursor: pointer; font: inherit; }
+.pdd-btn-text { background: transparent; color: #081319; }
+.pdd-btn-primary { background: #0f6e56; color: #ffffff; }
diff --git a/app/tests/Frontend/ProjectDetailsDrawer.spec.ts b/app/tests/Frontend/ProjectDetailsDrawer.spec.ts
index 41076471..067dcff5 100644
--- a/app/tests/Frontend/ProjectDetailsDrawer.spec.ts
+++ b/app/tests/Frontend/ProjectDetailsDrawer.spec.ts
@@ -2,6 +2,22 @@ import { describe, it, expect, beforeEach } from 'vitest';
import { mount } from '@vue/test-utils';
import { createPinia, setActivePinia } from 'pinia';
import ProjectDetailsDrawer from '../../resources/js/components/projects/ProjectDetailsDrawer.vue';
+import type { Project } from '../../resources/js/stores/projectsStore';
+
+const sampleProject: Project = {
+ id: 42,
+ name: 'Натяжные потолки',
+ signal_type: 'call',
+ signal_identifier: '79161112233',
+ daily_limit_target: 30,
+ delivered_today: 0,
+ is_active: true,
+ archived_at: null,
+ region_mask: 0,
+ region_mode: 'include',
+ delivery_days_mask: 31, // Mon-Fri
+ sync_status: 'pending',
+};
describe('ProjectDetailsDrawer', () => {
beforeEach(() => setActivePinia(createPinia()));
@@ -12,4 +28,20 @@ describe('ProjectDetailsDrawer', () => {
expect(aside.exists()).toBe(true);
expect(aside.classes()).not.toContain('open');
});
+
+ it('renders project name + daily_limit_target + delivery_days', () => {
+ const wrapper = mount(ProjectDetailsDrawer, { props: { project: sampleProject } });
+ const aside = wrapper.find('aside.project-details-drawer');
+ expect(aside.classes()).toContain('open');
+ expect(wrapper.text()).toContain('Натяжные потолки');
+ const nameInput = wrapper.get('input[data-testid="pdd-name"]');
+ expect((nameInput.element as HTMLInputElement).value).toBe('Натяжные потолки');
+ const limitInput = wrapper.get('input[data-testid="pdd-limit"]');
+ expect((limitInput.element as HTMLInputElement).value).toBe('30');
+ // Days mask 31 = bits 0..4 = Mon..Fri (5 days active)
+ const dayBtns = wrapper.findAll('button[data-testid^="pdd-day-"]');
+ expect(dayBtns.length).toBe(7);
+ const activeBtns = dayBtns.filter(b => b.classes().includes('active'));
+ expect(activeBtns.length).toBe(5);
+ });
});