diff --git a/src/components/admin/ErrorLogPanel.jsx b/src/components/admin/ErrorLogPanel.jsx
index c91f933..0503e12 100644
--- a/src/components/admin/ErrorLogPanel.jsx
+++ b/src/components/admin/ErrorLogPanel.jsx
@@ -2,6 +2,7 @@ import React, { useState, useEffect, useCallback, useRef } from 'react';
import { Panel } from '../UI/Panel';
import { Badge } from '../UI/Badge';
import { Select } from '../UI/Select';
+import { Skeleton } from '../UI/Loading';
import { supabase } from '../../supabaseClient';
@@ -274,7 +275,11 @@ export default function ErrorLogPanel() {
)}
{loading ? (
-
{errors.length === 0 && (
diff --git a/src/components/admin/StopWordsPanel.jsx b/src/components/admin/StopWordsPanel.jsx
index 9ffd338..96838f8 100644
--- a/src/components/admin/StopWordsPanel.jsx
+++ b/src/components/admin/StopWordsPanel.jsx
@@ -1,6 +1,7 @@
import React from "react";
import { Panel } from "../UI/Panel";
import { Button } from "../UI/Button";
+import { Skeleton } from "../UI/Loading";
import { supabase } from "../../supabaseClient";
export const StopWordsPanel = () => {
@@ -162,7 +163,11 @@ export const StopWordsPanel = () => {
)}
{isLoading ? (
-
Загрузка...
+
+ {Array.from({ length: 6 }).map((_, i) => (
+
+ ))}
+
) : !words.length ? (
Стоп-слов пока нет. Добавьте первое.
) : (
diff --git a/src/components/admin/UserManagementPanel.jsx b/src/components/admin/UserManagementPanel.jsx
index 62dbc43..6199aaf 100644
--- a/src/components/admin/UserManagementPanel.jsx
+++ b/src/components/admin/UserManagementPanel.jsx
@@ -2,6 +2,7 @@ import React, { useState, useEffect, useCallback, useRef } from 'react';
import { Panel } from '../UI/Panel';
import { Badge } from '../UI/Badge';
import { Input } from '../UI/Input';
+import { Skeleton } from '../UI/Loading';
import { supabase, supabaseUrl } from '../../supabaseClient';
@@ -274,7 +275,18 @@ export default function UserManagementPanel() {
const fmtDate = (iso) => iso ? new Date(iso).toLocaleString('ru-RU') : '—';
if (loading) {
- return
Загрузка…
;
+ return (
+
+
+
+
+ {Array.from({ length: 4 }).map((_, i) => (
+
+ ))}
+
+
+
+ );
}
return (
diff --git a/src/components/chat/ChatTimeline.jsx b/src/components/chat/ChatTimeline.jsx
index 0c24f43..d297fc3 100644
--- a/src/components/chat/ChatTimeline.jsx
+++ b/src/components/chat/ChatTimeline.jsx
@@ -1,8 +1,22 @@
import React from "react";
import { formatDateTime } from "../../utils/formatters";
import { Badge } from "../UI/Badge";
+import { Skeleton } from "../UI/Loading";
+
+export const ChatTimeline = ({ messages, isLoading = false }) => {
+ if (isLoading) {
+ return (
+
+ {Array.from({ length: 3 }).map((_, i) => (
+
+
+
+
+ ))}
+
+ );
+ }
-export const ChatTimeline = ({ messages }) => {
if (!messages.length) {
return (
diff --git a/src/components/client/DeliverySlotsPicker.jsx b/src/components/client/DeliverySlotsPicker.jsx
index 4d4af7d..ecf39a0 100644
--- a/src/components/client/DeliverySlotsPicker.jsx
+++ b/src/components/client/DeliverySlotsPicker.jsx
@@ -1,6 +1,7 @@
import React from "react";
import { Button } from "../UI/Button";
import { Panel } from "../UI/Panel";
+import { Skeleton } from "../UI/Loading";
import { formatDeliveryDate, getDeliveryRelativeDayLabel } from "./deliveryDateFormatting";
const groupSlotsByDate = (slots) => {
@@ -55,7 +56,20 @@ export const DeliverySlotsPicker = ({
onSelectSlot,
selectedSlotId,
referenceDate = new Date(),
+ isLoading = false,
}) => {
+ if (isLoading) {
+ return (
+
+
+
+
+
+
+
+ );
+ }
+
if (!slots || !slots.length) {
return (
diff --git a/src/components/driver/DriverDeliveryPlanner.jsx b/src/components/driver/DriverDeliveryPlanner.jsx
index 0e12fc7..31f15af 100644
--- a/src/components/driver/DriverDeliveryPlanner.jsx
+++ b/src/components/driver/DriverDeliveryPlanner.jsx
@@ -13,6 +13,7 @@ import { Badge } from "../UI/Badge";
import { Input } from "../UI/Input";
import { Select } from "../UI/Select";
import { Panel } from "../UI/Panel";
+import { SkeletonPage } from "../UI/Loading";
const CHEVRON_DOWN = (