Implement comprehensive Telegram customers storage and management functionality: Backend: - Add database migration for telecart_customers table with indexes - Create TelegramCustomer model with CRUD operations - Implement TelegramCustomerService for business logic - Add TelegramCustomerHandler for API endpoint (saveOrUpdate) - Add TelegramCustomersHandler for admin API (getCustomers with pagination, filtering, sorting) - Add SendMessageHandler for sending messages to customers via Telegram - Create custom exceptions: TelegramCustomerNotFoundException, TelegramCustomerWriteNotAllowedException - Refactor TelegramInitDataDecoder to separate decoding logic - Add TelegramHeader enum for header constants - Update SignatureValidator to use TelegramInitDataDecoder - Register new routes in bastion/routes.php and src/routes.php Frontend (Admin): - Add CustomersView.vue component with PrimeVue DataTable - Implement advanced filtering (text, date, boolean filters) - Add column visibility toggle functionality - Add global search with debounce - Implement message sending dialog with validation - Add Russian locale for PrimeVue components - Add navigation link in App.vue - Register route in router Frontend (SPA): - Add saveTelegramCustomer utility function - Integrate automatic customer data saving on app initialization - Extract user data from Telegram.WebApp.initDataUnsafe The system automatically saves/updates customer data when users access the Telegram Mini App, and provides admin interface for viewing, filtering, and messaging customers. BREAKING CHANGE: None
77 lines
1.6 KiB
CSS
77 lines
1.6 KiB
CSS
@layer theme, base, components, utilities;
|
|
@import "tailwindcss/theme.css" layer(theme) prefix(tw);
|
|
@import "tailwindcss/utilities.css" layer(utilities) prefix(tw);
|
|
|
|
@layer components {
|
|
.tw\:d-toggle {
|
|
width: calc((var(--d-size) * 2) - (var(--border) + var(--d-toggle-p)) * 2) !important;
|
|
height: var(--d-size) !important;
|
|
border: var(--border) solid currentColor !important;
|
|
color: var(--d-input-color) !important;
|
|
border-radius: calc(var(--radius-selector) + min(var(--d-toggle-p), var(--radius-selector-max)) + min(var(--border), var(--radius-selector-max))) !important;
|
|
padding: var(--d-toggle-p) !important;
|
|
}
|
|
|
|
.tw\:d-toggle:after {
|
|
all: unset !important;
|
|
}
|
|
}
|
|
|
|
html {
|
|
font-size: 14px;
|
|
}
|
|
|
|
.p-toast .p-toast-message-success {
|
|
color: #3c763d;
|
|
background-color: #dff0d8;
|
|
border-color: #d6e9c6;
|
|
}
|
|
|
|
.p-toggleswitch > input[type="checkbox"] {
|
|
position: absolute;
|
|
width: 100%;
|
|
height: 100%;
|
|
border: none;
|
|
border-radius: unset;
|
|
margin: 0;
|
|
}
|
|
|
|
legend.p-fieldset-legend {
|
|
font-size: 14px;
|
|
line-height: inherit;
|
|
width: auto;
|
|
margin-bottom: 0;
|
|
}
|
|
|
|
.telecart-admin-app {
|
|
color: var(--color-slate-700);
|
|
}
|
|
|
|
.blueprint-bg {
|
|
background-color: #efefef;
|
|
opacity: 0.7;
|
|
background-image: radial-gradient(#989898 0.65px, #efefef 0.65px);
|
|
background-size: 13px 13px;
|
|
}
|
|
|
|
ul.formkit-options {
|
|
padding: 0;
|
|
margin-bottom: 0;
|
|
list-style: none;
|
|
}
|
|
|
|
ul.formkit-options label {
|
|
display: inline-flex;
|
|
}
|
|
ul.formkit-options input[type="radio"] {
|
|
position: absolute;
|
|
}
|
|
|
|
input.p-checkbox-input {
|
|
position: absolute;
|
|
}
|
|
|
|
label {
|
|
margin-bottom: 0;
|
|
}
|