feat(ui): standardize design system, modals, sidebar, and form inputs
- Implement unified design system tokens, 10px radius, and IRANSans typography - Modernize sidebar with Gemini-style collapsed expander, square 1:1 items, and elevated profile flyout - Standardize all modal dialogs with 16px padding, fixed header/footer, 16px medium title, and sticky bottom actions - Refactor DealFormView and CustomFieldsSection with standard UiField, UiInput, and UiSelect components - Add draggable bottom-left QuickCreate floating action button
This commit is contained in:
@@ -0,0 +1,142 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue';
|
||||
import UiButton from './UiButton.vue';
|
||||
import UiIcon from '@/components/UiIcon.vue';
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
page: number;
|
||||
totalPages?: number;
|
||||
totalItems?: number;
|
||||
pageSize?: number;
|
||||
}>(),
|
||||
{
|
||||
page: 1,
|
||||
},
|
||||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
'update:page': [page: number];
|
||||
change: [page: number];
|
||||
}>();
|
||||
|
||||
const effectiveTotalPages = computed(() => {
|
||||
if (props.totalPages != null) return Math.max(1, props.totalPages);
|
||||
if (props.totalItems != null && props.pageSize != null && props.pageSize > 0) {
|
||||
return Math.max(1, Math.ceil(props.totalItems / props.pageSize));
|
||||
}
|
||||
return 1;
|
||||
});
|
||||
|
||||
function goTo(p: number) {
|
||||
if (p < 1 || p > effectiveTotalPages.value || p === props.page) return;
|
||||
emit('update:page', p);
|
||||
emit('change', p);
|
||||
}
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<nav v-if="effectiveTotalPages > 1 || totalItems !== undefined" class="ui-pagination" aria-label="صفحهبندی">
|
||||
<div class="pagination-info">
|
||||
<span v-if="totalItems !== undefined">
|
||||
مجموع: <strong>{{ totalItems }}</strong> مورد
|
||||
</span>
|
||||
<span v-if="effectiveTotalPages > 1" class="page-count">
|
||||
(صفحه {{ page }} از {{ effectiveTotalPages }})
|
||||
</span>
|
||||
</div>
|
||||
|
||||
<div v-if="effectiveTotalPages > 1" class="pagination-controls">
|
||||
<UiButton
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
:disabled="page <= 1"
|
||||
title="صفحه اول"
|
||||
@click="goTo(1)"
|
||||
>
|
||||
<UiIcon name="chevrons-right" :size="14" />
|
||||
</UiButton>
|
||||
|
||||
<UiButton
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
:disabled="page <= 1"
|
||||
title="صفحه قبل"
|
||||
@click="goTo(page - 1)"
|
||||
>
|
||||
<UiIcon name="chevron-right" :size="14" />
|
||||
قبلی
|
||||
</UiButton>
|
||||
|
||||
<span class="current-indicator">
|
||||
{{ page }} / {{ effectiveTotalPages }}
|
||||
</span>
|
||||
|
||||
<UiButton
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
:disabled="page >= effectiveTotalPages"
|
||||
title="صفحه بعد"
|
||||
@click="goTo(page + 1)"
|
||||
>
|
||||
بعدی
|
||||
<UiIcon name="chevron-left" :size="14" />
|
||||
</UiButton>
|
||||
|
||||
<UiButton
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
:disabled="page >= effectiveTotalPages"
|
||||
title="صفحه آخر"
|
||||
@click="goTo(effectiveTotalPages)"
|
||||
>
|
||||
<UiIcon name="chevrons-left" :size="14" />
|
||||
</UiButton>
|
||||
</div>
|
||||
</nav>
|
||||
</template>
|
||||
|
||||
<style scoped>
|
||||
.ui-pagination {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
flex-wrap: wrap;
|
||||
gap: var(--sp-3);
|
||||
padding-top: var(--sp-4);
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.pagination-info {
|
||||
font-size: var(--fs-sm);
|
||||
color: var(--muted);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: var(--sp-2);
|
||||
}
|
||||
|
||||
.page-count {
|
||||
color: var(--muted-light);
|
||||
}
|
||||
|
||||
.pagination-controls {
|
||||
display: inline-flex;
|
||||
align-items: center;
|
||||
gap: var(--sp-1);
|
||||
}
|
||||
|
||||
.current-indicator {
|
||||
padding: 0 var(--sp-2);
|
||||
font-size: var(--fs-xs);
|
||||
font-weight: var(--fw-bold);
|
||||
color: var(--ink-secondary);
|
||||
}
|
||||
|
||||
@media (max-width: 900px) {
|
||||
.ui-pagination {
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
gap: var(--sp-3);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
Reference in New Issue
Block a user