@mohasinac/appkit 3.2.19 → 3.2.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -67,7 +67,6 @@ export function UserOffersPanel({ fetchEndpoint = "/api/user/offers", onAcceptCo
67
67
  const [fetchError, setFetchError] = useState("");
68
68
  const [showLoginModal, setShowLoginModal] = useState(false);
69
69
  const loadOffers = useCallback(async () => {
70
- // toast-intentionally-silent: background data loader — error displayed in inline fetchError state
71
70
  setLoading(true);
72
71
  setFetchError("");
73
72
  try {
@@ -26,7 +26,7 @@ function makeCard(zone = 1) {
26
26
  id: `card-${Date.now()}-${Math.random().toString(36).slice(2, 6)}`,
27
27
  zone,
28
28
  background: { type: "color", color: "var(--appkit-color-primary)" },
29
- content: { title: "", subtitle: "", textColor: "#ffffff", textAlign: "left" }, // audit-hex-tokens-ok: Firestore document default value (text CSS color field), not a styling literal
29
+ content: { title: "", subtitle: "", textColor: "#ffffff", textAlign: "left" },
30
30
  buttons: [],
31
31
  hover: { effect: "scale" },
32
32
  };
@@ -78,8 +78,7 @@ function ZonePicker({ selected, onChange, disabled, }) {
78
78
  // ── Background Editor ────────────────────────────────────────────────────────
79
79
  function BackgroundEditor({ value, onChange, prefix, }) {
80
80
  const set = (patch) => onChange({ ...value, ...patch });
81
- return (_jsxs(Stack, { gap: "3", children: [_jsx(Select, { label: "Background type", value: value.type, onChange: (e) => onChange({ type: e.target.value }), options: BG_TYPE_OPTIONS }), (value.type === "image" || value.type === "video") && (_jsxs(_Fragment, { children: [_jsx(Input, { label: `${value.type === "image" ? "Image" : "Video"} URL`, value: value.url ?? "", onChange: (e) => set({ url: e.target.value }), placeholder: "https://..." }), _jsx(Input, { label: "Mobile URL (optional)", value: value.mobileUrl ?? "", onChange: (e) => set({ mobileUrl: e.target.value || undefined }), placeholder: "https://... (portrait crop)" }), value.type === "video" && (_jsx(Input, { label: "Poster / thumbnail URL", value: value.thumbnail ?? "", onChange: (e) => set({ thumbnail: e.target.value || undefined }), placeholder: "https://..." })), _jsxs(Stack, { className: `${__P.p3}`, gap: "sm", rounded: "lg", border: "default", children: [_jsx(Toggle, { label: "Dim overlay", checked: value.dimOverlay?.enabled ?? false, onChange: (v) => set({ dimOverlay: { enabled: v, opacity: value.dimOverlay?.opacity ?? 40 } }) }), value.dimOverlay?.enabled && (_jsxs(Div, { children: [_jsxs(Text, { className: "mb-1", size: "sm", weight: "medium", children: ["Opacity (", value.dimOverlay.opacity, "%)"] }), _jsx("input", { type: "range", min: 0, max: 90, step: 5, value: value.dimOverlay.opacity, onChange: (e) => set({ dimOverlay: { enabled: true, opacity: Number(e.target.value) } }), className: "w-full" })] }))] })] })), value.type === "color" && (_jsx(Input, { label: "Colour (CSS token or hex)", value: value.color ?? "", onChange: (e) => set({ color: e.target.value }), placeholder: "var(--appkit-color-primary) or #1a1a2e" // audit-hex-tokens-ok: descriptive placeholder string showing users valid input formats
82
- })), value.type === "gradient" && (_jsxs(_Fragment, { children: [_jsx(Input, { label: "From colour", value: value.gradientFrom ?? "", onChange: (e) => set({ gradientFrom: e.target.value }), placeholder: "var(--appkit-color-primary)" }), _jsx(Input, { label: "To colour", value: value.gradientTo ?? "", onChange: (e) => set({ gradientTo: e.target.value }), placeholder: "var(--appkit-color-secondary)" }), _jsx(Input, { label: "Angle (degrees)", type: "number", value: String(value.gradientAngle ?? 135), onChange: (e) => set({ gradientAngle: Number(e.target.value) }), min: 0, max: 360 })] }))] }));
81
+ return (_jsxs(Stack, { gap: "3", children: [_jsx(Select, { label: "Background type", value: value.type, onChange: (e) => onChange({ type: e.target.value }), options: BG_TYPE_OPTIONS }), (value.type === "image" || value.type === "video") && (_jsxs(_Fragment, { children: [_jsx(Input, { label: `${value.type === "image" ? "Image" : "Video"} URL`, value: value.url ?? "", onChange: (e) => set({ url: e.target.value }), placeholder: "https://..." }), _jsx(Input, { label: "Mobile URL (optional)", value: value.mobileUrl ?? "", onChange: (e) => set({ mobileUrl: e.target.value || undefined }), placeholder: "https://... (portrait crop)" }), value.type === "video" && (_jsx(Input, { label: "Poster / thumbnail URL", value: value.thumbnail ?? "", onChange: (e) => set({ thumbnail: e.target.value || undefined }), placeholder: "https://..." })), _jsxs(Stack, { className: `${__P.p3}`, gap: "sm", rounded: "lg", border: "default", children: [_jsx(Toggle, { label: "Dim overlay", checked: value.dimOverlay?.enabled ?? false, onChange: (v) => set({ dimOverlay: { enabled: v, opacity: value.dimOverlay?.opacity ?? 40 } }) }), value.dimOverlay?.enabled && (_jsxs(Div, { children: [_jsxs(Text, { className: "mb-1", size: "sm", weight: "medium", children: ["Opacity (", value.dimOverlay.opacity, "%)"] }), _jsx("input", { type: "range", min: 0, max: 90, step: 5, value: value.dimOverlay.opacity, onChange: (e) => set({ dimOverlay: { enabled: true, opacity: Number(e.target.value) } }), className: "w-full" })] }))] })] })), value.type === "color" && (_jsx(Input, { label: "Colour (CSS token or hex)", value: value.color ?? "", onChange: (e) => set({ color: e.target.value }), placeholder: "var(--appkit-color-primary) or #1a1a2e" })), value.type === "gradient" && (_jsxs(_Fragment, { children: [_jsx(Input, { label: "From colour", value: value.gradientFrom ?? "", onChange: (e) => set({ gradientFrom: e.target.value }), placeholder: "var(--appkit-color-primary)" }), _jsx(Input, { label: "To colour", value: value.gradientTo ?? "", onChange: (e) => set({ gradientTo: e.target.value }), placeholder: "var(--appkit-color-secondary)" }), _jsx(Input, { label: "Angle (degrees)", type: "number", value: String(value.gradientAngle ?? 135), onChange: (e) => set({ gradientAngle: Number(e.target.value) }), min: 0, max: 360 })] }))] }));
83
82
  }
84
83
  // ── Card Editor ──────────────────────────────────────────────────────────────
85
84
  function CardEditor({ card, index, otherZones, onChange, onRemove, }) {
@@ -34,7 +34,6 @@ export function AdminFulfillmentView({ initialStoreId, initialStoreName, }) {
34
34
  const [actionLoadingId, setActionLoadingId] = useState(null);
35
35
  const { showToast } = useToast();
36
36
  const fetchOrders = useCallback(async (sid) => {
37
- // toast-intentionally-silent: background data loader — normalizeError logs, no user-facing toast needed
38
37
  setIsLoading(true);
39
38
  try {
40
39
  const res = await apiClient.get(ADMIN_ENDPOINTS.ADMIN_FULFILLMENT(sid));
@@ -16,7 +16,6 @@ export function useChat(chatId, options) {
16
16
  const tokenExpiresAtRef = useRef(0);
17
17
  const unsubscribeRef = useRef(null);
18
18
  const connectAndSubscribe = useCallback(async () => {
19
- // toast-intentionally-silent: RTDB connection management — error set in state, not surfaced via toast
20
19
  if (!chatId)
21
20
  return;
22
21
  setIsLoading(true);
@@ -121,7 +121,6 @@ export function useGoogleLogin(options) {
121
121
  return () => window.removeEventListener("message", handleMessage);
122
122
  }, []); // mount once — uses refs, no stale closure risk
123
123
  const mutate = useCallback(async () => {
124
- // toast-intentionally-silent: OAuth popup flow — errors forwarded to onErrorRef callback, not toast
125
124
  calledRef.current = false; // reset for each new auth flow
126
125
  const popup = window.open(`${window.location.origin}/auth.html`, "oauth_google", "width=500,height=660,left=400,top=100");
127
126
  if (!popup) {
@@ -74,7 +74,6 @@ export function useHistory(userId) {
74
74
  const [items, setItems] = useState([]);
75
75
  const trackTimers = useRef(new Map());
76
76
  const loadItems = useCallback(async () => {
77
- // toast-intentionally-silent: background history load — normalizeError logs, silent fail is acceptable
78
77
  try {
79
78
  if (isAuth) {
80
79
  setItems(await fetchAuthHistory());
@@ -43,7 +43,6 @@ export function useConversation(conversationId) {
43
43
  const [error, setError] = useState(null);
44
44
  const [isConnected, setIsConnected] = useState(false);
45
45
  const refetch = useCallback(async () => {
46
- // toast-intentionally-silent: background conversation refetch — error stored in state, UI shows inline error
47
46
  if (!conversationId) {
48
47
  setConversation(null);
49
48
  return;
@@ -19,7 +19,6 @@ export function useConversations(userId) {
19
19
  const [isLoading, setIsLoading] = useState(false);
20
20
  const [error, setError] = useState(null);
21
21
  const refetch = useCallback(async () => {
22
- // toast-intentionally-silent: background conversations list refetch — error stored in state
23
22
  if (!userId) {
24
23
  setConversations([]);
25
24
  return;
@@ -31,7 +31,6 @@ export function FulfillmentView({ currentUserId, }) {
31
31
  const [actionLoadingId, setActionLoadingId] = useState(null);
32
32
  const { showToast } = useToast();
33
33
  const fetchOrders = useCallback(async () => {
34
- // toast-intentionally-silent: background data loader — normalizeError logs, no user-facing toast needed
35
34
  setIsLoadingOrders(true);
36
35
  try {
37
36
  const res = await apiClient.get(SELLER_ENDPOINTS.ORDERS_FULFILLMENT);
@@ -68,7 +68,6 @@ export function SellerAddressesView({ apiBase = SELLER_ENDPOINTS.STORE_ADDRESSES
68
68
  const [saveError, setSaveError] = useState(null);
69
69
  const [deleteTargetAddr, setDeleteTargetAddr] = useState(null);
70
70
  const load = useCallback(async () => {
71
- // toast-intentionally-silent: background address loader — error displayed in inline errorMessage state
72
71
  setIsLoading(true);
73
72
  setErrorMessage(null);
74
73
  try {
@@ -117,7 +117,6 @@ export function SellerOffersPanel({ fetchEndpoint = "/api/store/offers", onRespo
117
117
  const [showLoginModal, setShowLoginModal] = useState(false);
118
118
  const [statusFilter, setStatusFilter] = useState("all");
119
119
  const loadOffers = useCallback(async () => {
120
- // toast-intentionally-silent: background data loader — error displayed in inline fetchError state
121
120
  setLoading(true);
122
121
  setFetchError("");
123
122
  try {
@@ -94,7 +94,6 @@ export function SellerReviewsView({ reviewsApiBase = "/api/store/reviews", reply
94
94
  }, [feedbackTarget, feedbackText]);
95
95
  const fetchReviewsRef = useMemo(() => ({ current: null }), []);
96
96
  const fetchReviews = useCallback(async () => {
97
- // toast-intentionally-silent: background data loader — error displayed in inline error state
98
97
  setLoading(true);
99
98
  setError(null);
100
99
  try {
@@ -137,7 +137,7 @@ function attachCopyButtons(container) {
137
137
  btn.style.cssText =
138
138
  "position:absolute;top:8px;right:8px;padding:2px 10px;font-size:11px;font-family:inherit;" +
139
139
  "border-radius:6px;border:1px solid rgba(148,163,184,.4);background:rgba(30,41,59,.75);" +
140
- "color:#e2e8f0;cursor:pointer;line-height:1.6;user-select:none;transition:background .15s;"; // audit-hex-tokens-ok: DOM-injected cssText string; CSS vars require getPropertyValue() and can't be used in style.cssText assignment
140
+ "color:#e2e8f0;cursor:pointer;line-height:1.6;user-select:none;transition:background .15s;";
141
141
  btn.addEventListener("click", () => {
142
142
  const code = pre.querySelector("code")?.textContent ?? pre.textContent ?? "";
143
143
  if (!navigator.clipboard)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@mohasinac/appkit",
3
- "version": "3.2.19",
3
+ "version": "3.2.20",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"