Creating & Edit profile

This commit is contained in:
2026-09-15 14:10:52 +03:30
parent 8dcf4ed5e9
commit 9ae176bec0
13 changed files with 767 additions and 77 deletions
+106 -39
View File
@@ -280,8 +280,21 @@ async function toggle(row: MessageAutomationRuleDto) {
}
}
async function remove(row: MessageAutomationRuleDto) {
if (!confirm(`قانون «${row.name}» حذف شود؟`)) return;
const pendingDelete = ref<MessageAutomationRuleDto | null>(null);
function askRemove(row: MessageAutomationRuleDto) {
menuId.value = null;
pendingDelete.value = row;
}
function cancelRemove() {
pendingDelete.value = null;
}
async function confirmRemove() {
const row = pendingDelete.value;
if (!row) return;
pendingDelete.value = null;
try {
await api.delete(`/message-automations/${row.id}`);
if (editingId.value === row.id) resetForm();
@@ -410,7 +423,7 @@ onUnmounted(() => {
</button>
<div v-if="menuId === row.id" class="pop">
<button type="button" @click="openMobileEdit(row)">ویرایش</button>
<button type="button" class="danger" @click="remove(row)">حذف</button>
<button type="button" class="danger" @click="askRemove(row)">حذف</button>
</div>
</div>
<div class="m-copy">
@@ -1071,23 +1084,25 @@ onUnmounted(() => {
<td>{{ MESSAGE_AUTOMATION_TARGET_LABELS[row.notifyTarget] }}</td>
<td>{{ MESSAGE_AUTOMATION_CHANNEL_LABELS[row.channel] }}</td>
<td class="ops">
<button
class="icon-btn status"
type="button"
:class="{ on: row.isActive }"
:aria-pressed="row.isActive"
:aria-label="row.isActive ? 'فعال' : 'غیرفعال'"
:title="row.isActive ? 'فعال' : 'غیرفعال'"
@click="toggle(row)"
>
<UiIcon :name="row.isActive ? 'check-plain' : 'x'" :size="16" />
</button>
<button class="icon-btn" type="button" title="ویرایش" aria-label="ویرایش" @click="startEdit(row)">
<UiIcon name="pencil" :size="16" />
</button>
<button class="icon-btn danger" type="button" title="حذف" aria-label="حذف" @click="remove(row)">
<UiIcon name="trash" :size="16" />
</button>
<div class="ops-row">
<button
class="icon-btn status"
type="button"
:class="{ on: row.isActive }"
:aria-pressed="row.isActive"
:aria-label="row.isActive ? 'فعال' : 'غیرفعال'"
:title="row.isActive ? 'فعال' : 'غیرفعال'"
@click="toggle(row)"
>
<UiIcon :name="row.isActive ? 'check' : 'x-circle'" :size="24" />
</button>
<button class="icon-btn edit" type="button" title="ویرایش" aria-label="ویرایش" @click="startEdit(row)">
<UiIcon name="edit" :size="24" />
</button>
<button class="icon-btn danger" type="button" title="حذف" aria-label="حذف" @click="askRemove(row)">
<UiIcon name="trash" :size="24" />
</button>
</div>
</td>
</tr>
</tbody>
@@ -1123,12 +1138,24 @@ onUnmounted(() => {
<p class="preview">{{ row.description || row.body }}</p>
<div class="card-actions">
<button class="btn ghost" type="button" @click="startEdit(row)">ویرایش</button>
<button class="btn danger" type="button" @click="remove(row)">حذف</button>
<button class="btn danger" type="button" @click="askRemove(row)">حذف</button>
</div>
</article>
</div>
<p v-if="!loading && !items.length" class="empty">هنوز قانون پیامی نیست.</p>
</div>
<div v-if="pendingDelete" class="sheet-layer">
<button class="dim" type="button" aria-label="انصراف" @click="cancelRemove" />
<section class="confirm-box" role="dialog" aria-modal="true" aria-labelledby="delete-confirm-title">
<h3 id="delete-confirm-title">حذف قانون</h3>
<p>آیا از حذف مطمئن هستید؟</p>
<div class="confirm-actions">
<button class="btn danger" type="button" @click="confirmRemove">حذف</button>
<button class="btn ghost" type="button" @click="cancelRemove">انصراف</button>
</div>
</section>
</div>
</section>
</template>
@@ -1678,6 +1705,37 @@ textarea {
background: rgba(15, 23, 42, 0.32);
}
.confirm-box {
position: relative;
z-index: 1;
width: min(22rem, 100%);
display: grid;
gap: 0.85rem;
padding: 1.15rem 1.2rem 1.1rem;
border-radius: 18px;
background: #fff;
box-shadow: 0 18px 40px rgba(15, 23, 42, 0.16);
}
.confirm-box h3 {
margin: 0;
font-size: 1.05rem;
font-weight: 800;
color: #0f172a;
}
.confirm-box p {
margin: 0;
color: #475569;
font-size: 0.95rem;
}
.confirm-actions {
display: flex;
justify-content: flex-end;
gap: 0.5rem;
}
.sheet {
position: relative;
z-index: 1;
@@ -1802,50 +1860,59 @@ textarea {
}
.desk-table .ops {
display: flex;
align-items: center;
gap: 0.3rem;
flex-wrap: nowrap;
display: table-cell;
width: 1%;
white-space: nowrap;
vertical-align: middle;
}
.ops-row {
display: inline-flex;
align-items: center;
gap: 0.35rem;
}
.icon-btn {
display: grid;
display: inline-grid;
place-items: center;
width: 36px;
height: 36px;
flex: 0 0 2.75rem;
width: 2.75rem;
height: 2.75rem;
padding: 0;
border: 1px solid #e2e8f0;
border-radius: var(--radius);
background: #fff;
border: 0;
border-radius: 8px;
background: transparent;
color: #64748b;
cursor: pointer;
}
.icon-btn:hover {
background: #f8fafc;
background: transparent;
color: #0f172a;
}
.icon-btn.edit {
color: #2563eb;
}
.icon-btn.edit:hover {
color: #1d4ed8;
}
.icon-btn.danger {
color: #b91c1c;
border-color: #fecaca;
color: #dc2626;
}
.icon-btn.danger:hover {
background: #fef2f2;
color: #b91c1c;
background: transparent;
}
.icon-btn.status {
border-color: #fecaca;
background: #fef2f2;
color: #dc2626;
}
.icon-btn.status.on {
border-color: #bbf7d0;
background: #f0fdf4;
color: #16a34a;
}