@djangocfg/ext-support 1.0.22 → 1.0.23

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.
package/dist/config.cjs CHANGED
@@ -27,7 +27,7 @@ var import_ext_base = require("@djangocfg/ext-base");
27
27
  // package.json
28
28
  var package_default = {
29
29
  name: "@djangocfg/ext-support",
30
- version: "1.0.22",
30
+ version: "1.0.23",
31
31
  description: "Support ticket system extension for DjangoCFG",
32
32
  keywords: [
33
33
  "django",
@@ -95,14 +95,15 @@ var package_default = {
95
95
  "@djangocfg/ext-base": "workspace:*",
96
96
  "@djangocfg/i18n": "workspace:*",
97
97
  "@djangocfg/ui-core": "workspace:*",
98
+ "@hookform/resolvers": "^5.2.2",
98
99
  consola: "^3.4.2",
99
100
  "lucide-react": "^0.545.0",
100
101
  moment: "^2.30.1",
101
102
  next: "^16",
103
+ "next-intl": "^4",
102
104
  "p-retry": "^7.0.0",
103
105
  react: "^19",
104
106
  "react-hook-form": "^7.69.0",
105
- "@hookform/resolvers": "^5.2.2",
106
107
  swr: "^2.3.7",
107
108
  zod: "^4.3.4"
108
109
  },
@@ -116,6 +117,7 @@ var package_default = {
116
117
  "@types/react": "^19.0.0",
117
118
  consola: "^3.4.2",
118
119
  moment: "^2.30.1",
120
+ "next-intl": "^4.1.0",
119
121
  "p-retry": "^7.0.0",
120
122
  swr: "^2.3.7",
121
123
  tsup: "^8.5.0",
package/dist/config.js CHANGED
@@ -4,7 +4,7 @@ import { createExtensionConfig } from "@djangocfg/ext-base";
4
4
  // package.json
5
5
  var package_default = {
6
6
  name: "@djangocfg/ext-support",
7
- version: "1.0.22",
7
+ version: "1.0.23",
8
8
  description: "Support ticket system extension for DjangoCFG",
9
9
  keywords: [
10
10
  "django",
@@ -72,14 +72,15 @@ var package_default = {
72
72
  "@djangocfg/ext-base": "workspace:*",
73
73
  "@djangocfg/i18n": "workspace:*",
74
74
  "@djangocfg/ui-core": "workspace:*",
75
+ "@hookform/resolvers": "^5.2.2",
75
76
  consola: "^3.4.2",
76
77
  "lucide-react": "^0.545.0",
77
78
  moment: "^2.30.1",
78
79
  next: "^16",
80
+ "next-intl": "^4",
79
81
  "p-retry": "^7.0.0",
80
82
  react: "^19",
81
83
  "react-hook-form": "^7.69.0",
82
- "@hookform/resolvers": "^5.2.2",
83
84
  swr: "^2.3.7",
84
85
  zod: "^4.3.4"
85
86
  },
@@ -93,6 +94,7 @@ var package_default = {
93
94
  "@types/react": "^19.0.0",
94
95
  consola: "^3.4.2",
95
96
  moment: "^2.30.1",
97
+ "next-intl": "^4.1.0",
96
98
  "p-retry": "^7.0.0",
97
99
  swr: "^2.3.7",
98
100
  tsup: "^8.5.0",
package/dist/hooks.cjs CHANGED
@@ -6,8 +6,7 @@ var zod = require('zod');
6
6
  var api = require('@djangocfg/ext-base/api');
7
7
  var lucideReact = require('lucide-react');
8
8
  var React8 = require('react');
9
- var i18n = require('@djangocfg/ext-base/i18n');
10
- var i18n$1 = require('@djangocfg/i18n');
9
+ var nextIntl = require('next-intl');
11
10
  var uiCore = require('@djangocfg/ui-core');
12
11
  var useSWR = require('swr');
13
12
  var jsxRuntime = require('react/jsx-runtime');
@@ -1832,14 +1831,28 @@ var ko = {
1832
1831
  }
1833
1832
  };
1834
1833
 
1835
- // src/i18n/index.ts
1836
- var SUPPORT_NAMESPACE = "support";
1837
- var supportI18n = i18n.createExtensionI18n({
1838
- namespace: SUPPORT_NAMESPACE,
1839
- defaultLocale: "en",
1840
- locales: { en, ru, ko }
1841
- });
1842
- supportI18n.getAllTranslations();
1834
+ // src/i18n/useSupportT.ts
1835
+ var translations = { en, ru, ko };
1836
+ function getNestedValue(obj, path) {
1837
+ const keys = path.split(".");
1838
+ let result = obj;
1839
+ for (const key of keys) {
1840
+ if (result && typeof result === "object" && key in result) {
1841
+ result = result[key];
1842
+ } else {
1843
+ return path;
1844
+ }
1845
+ }
1846
+ return typeof result === "string" ? result : path;
1847
+ }
1848
+ function useSupportT() {
1849
+ const locale = nextIntl.useLocale();
1850
+ const t = React8.useMemo(() => translations[locale] || translations.en, [locale]);
1851
+ return React8.useCallback(
1852
+ (key) => getNestedValue(t, key),
1853
+ [t]
1854
+ );
1855
+ }
1843
1856
  function useSupportTicketsList(params, client) {
1844
1857
  return useSWR__default.default(
1845
1858
  params ? ["cfg-support-tickets", params] : "cfg-support-tickets",
@@ -2055,8 +2068,7 @@ var getStatusBadgeVariant = (status) => {
2055
2068
  }
2056
2069
  };
2057
2070
  var TicketCard = ({ ticket, isSelected, onClick }) => {
2058
- const baseT = i18n$1.useT();
2059
- const st = i18n.createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2071
+ const st = useSupportT();
2060
2072
  const labels = React8.useMemo(() => ({
2061
2073
  status: {
2062
2074
  open: st("status.open"),
@@ -2382,8 +2394,7 @@ function useSupportLayoutContext() {
2382
2394
  return context;
2383
2395
  }
2384
2396
  var TicketList = () => {
2385
- const baseT = i18n$1.useT();
2386
- const st = i18n.createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2397
+ const st = useSupportT();
2387
2398
  const { selectedTicket, selectTicket } = useSupportLayoutContext();
2388
2399
  const {
2389
2400
  tickets,
@@ -2529,8 +2540,7 @@ var MessageBubble = ({ message, isFromUser, currentUser, labels }) => {
2529
2540
  );
2530
2541
  };
2531
2542
  var MessageList = () => {
2532
- const baseT = i18n$1.useT();
2533
- const st = i18n.createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2543
+ const st = useSupportT();
2534
2544
  const { selectedTicket } = useSupportLayoutContext();
2535
2545
  const { user } = auth.useAuth();
2536
2546
  const labels = React8.useMemo(() => ({
@@ -2681,8 +2691,7 @@ var logger = consola.createConsola({
2681
2691
  }).withTag("ext-support");
2682
2692
  var supportLogger = logger;
2683
2693
  var MessageInput = () => {
2684
- const baseT = i18n$1.useT();
2685
- const st = i18n.createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2694
+ const st = useSupportT();
2686
2695
  const { selectedTicket, sendMessage } = useSupportLayoutContext();
2687
2696
  const { toast } = hooks.useToast();
2688
2697
  const [message, setMessage] = React8.useState("");
@@ -2747,8 +2756,7 @@ var MessageInput = () => {
2747
2756
  ] });
2748
2757
  };
2749
2758
  var CreateTicketDialog = () => {
2750
- const baseT = i18n$1.useT();
2751
- const st = i18n.createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2759
+ const st = useSupportT();
2752
2760
  const { uiState, createTicket, closeCreateDialog } = useSupportLayoutContext();
2753
2761
  const { toast } = uiCore.useToast();
2754
2762
  const [isSubmitting, setIsSubmitting] = React8__default.default.useState(false);
@@ -2862,8 +2870,7 @@ var CreateTicketDialog = () => {
2862
2870
  ] }) });
2863
2871
  };
2864
2872
  var SupportLayoutContent = () => {
2865
- const baseT = i18n$1.useT();
2866
- const st = i18n.createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2873
+ const st = useSupportT();
2867
2874
  const { selectedTicket, selectTicket, openCreateDialog, getUnreadCount } = useSupportLayoutContext();
2868
2875
  const [isMobile, setIsMobile] = React8__default.default.useState(false);
2869
2876
  const labels = React8.useMemo(() => ({
@@ -2947,7 +2954,7 @@ var SupportLayout = () => {
2947
2954
  // package.json
2948
2955
  var package_default = {
2949
2956
  name: "@djangocfg/ext-support",
2950
- version: "1.0.22",
2957
+ version: "1.0.23",
2951
2958
  description: "Support ticket system extension for DjangoCFG",
2952
2959
  keywords: [
2953
2960
  "django",
@@ -3015,14 +3022,15 @@ var package_default = {
3015
3022
  "@djangocfg/ext-base": "workspace:*",
3016
3023
  "@djangocfg/i18n": "workspace:*",
3017
3024
  "@djangocfg/ui-core": "workspace:*",
3025
+ "@hookform/resolvers": "^5.2.2",
3018
3026
  consola: "^3.4.2",
3019
3027
  "lucide-react": "^0.545.0",
3020
3028
  moment: "^2.30.1",
3021
3029
  next: "^16",
3030
+ "next-intl": "^4",
3022
3031
  "p-retry": "^7.0.0",
3023
3032
  react: "^19",
3024
3033
  "react-hook-form": "^7.69.0",
3025
- "@hookform/resolvers": "^5.2.2",
3026
3034
  swr: "^2.3.7",
3027
3035
  zod: "^4.3.4"
3028
3036
  },
@@ -3036,6 +3044,7 @@ var package_default = {
3036
3044
  "@types/react": "^19.0.0",
3037
3045
  consola: "^3.4.2",
3038
3046
  moment: "^2.30.1",
3047
+ "next-intl": "^4.1.0",
3039
3048
  "p-retry": "^7.0.0",
3040
3049
  swr: "^2.3.7",
3041
3050
  tsup: "^8.5.0",
package/dist/hooks.js CHANGED
@@ -4,8 +4,7 @@ import { z } from 'zod';
4
4
  import { initializeExtensionAPI, createExtensionAPI } from '@djangocfg/ext-base/api';
5
5
  import { Clock, MessageSquare, Loader2, Send, Plus, Headphones, User, ArrowLeft, LifeBuoy } from 'lucide-react';
6
6
  import React8, { createContext, useContext, useMemo, useCallback, useState, useEffect, useRef } from 'react';
7
- import { createExtensionI18n, createTypedExtensionT } from '@djangocfg/ext-base/i18n';
8
- import { useT } from '@djangocfg/i18n';
7
+ import { useLocale } from 'next-intl';
9
8
  import { Card, CardContent, Badge, Skeleton, ScrollArea, Button, Textarea, useToast as useToast$1, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Form, FormField, FormItem, FormLabel, FormControl, Input, FormMessage, Avatar, AvatarImage, AvatarFallback, ResizablePanelGroup, ResizablePanel, ResizableHandle } from '@djangocfg/ui-core';
10
9
  import useSWR, { useSWRConfig } from 'swr';
11
10
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -1822,14 +1821,28 @@ var ko = {
1822
1821
  }
1823
1822
  };
1824
1823
 
1825
- // src/i18n/index.ts
1826
- var SUPPORT_NAMESPACE = "support";
1827
- var supportI18n = createExtensionI18n({
1828
- namespace: SUPPORT_NAMESPACE,
1829
- defaultLocale: "en",
1830
- locales: { en, ru, ko }
1831
- });
1832
- supportI18n.getAllTranslations();
1824
+ // src/i18n/useSupportT.ts
1825
+ var translations = { en, ru, ko };
1826
+ function getNestedValue(obj, path) {
1827
+ const keys = path.split(".");
1828
+ let result = obj;
1829
+ for (const key of keys) {
1830
+ if (result && typeof result === "object" && key in result) {
1831
+ result = result[key];
1832
+ } else {
1833
+ return path;
1834
+ }
1835
+ }
1836
+ return typeof result === "string" ? result : path;
1837
+ }
1838
+ function useSupportT() {
1839
+ const locale = useLocale();
1840
+ const t = useMemo(() => translations[locale] || translations.en, [locale]);
1841
+ return useCallback(
1842
+ (key) => getNestedValue(t, key),
1843
+ [t]
1844
+ );
1845
+ }
1833
1846
  function useSupportTicketsList(params, client) {
1834
1847
  return useSWR(
1835
1848
  params ? ["cfg-support-tickets", params] : "cfg-support-tickets",
@@ -2045,8 +2058,7 @@ var getStatusBadgeVariant = (status) => {
2045
2058
  }
2046
2059
  };
2047
2060
  var TicketCard = ({ ticket, isSelected, onClick }) => {
2048
- const baseT = useT();
2049
- const st = createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2061
+ const st = useSupportT();
2050
2062
  const labels = useMemo(() => ({
2051
2063
  status: {
2052
2064
  open: st("status.open"),
@@ -2372,8 +2384,7 @@ function useSupportLayoutContext() {
2372
2384
  return context;
2373
2385
  }
2374
2386
  var TicketList = () => {
2375
- const baseT = useT();
2376
- const st = createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2387
+ const st = useSupportT();
2377
2388
  const { selectedTicket, selectTicket } = useSupportLayoutContext();
2378
2389
  const {
2379
2390
  tickets,
@@ -2519,8 +2530,7 @@ var MessageBubble = ({ message, isFromUser, currentUser, labels }) => {
2519
2530
  );
2520
2531
  };
2521
2532
  var MessageList = () => {
2522
- const baseT = useT();
2523
- const st = createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2533
+ const st = useSupportT();
2524
2534
  const { selectedTicket } = useSupportLayoutContext();
2525
2535
  const { user } = useAuth();
2526
2536
  const labels = useMemo(() => ({
@@ -2671,8 +2681,7 @@ var logger = createConsola({
2671
2681
  }).withTag("ext-support");
2672
2682
  var supportLogger = logger;
2673
2683
  var MessageInput = () => {
2674
- const baseT = useT();
2675
- const st = createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2684
+ const st = useSupportT();
2676
2685
  const { selectedTicket, sendMessage } = useSupportLayoutContext();
2677
2686
  const { toast } = useToast();
2678
2687
  const [message, setMessage] = useState("");
@@ -2737,8 +2746,7 @@ var MessageInput = () => {
2737
2746
  ] });
2738
2747
  };
2739
2748
  var CreateTicketDialog = () => {
2740
- const baseT = useT();
2741
- const st = createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2749
+ const st = useSupportT();
2742
2750
  const { uiState, createTicket, closeCreateDialog } = useSupportLayoutContext();
2743
2751
  const { toast } = useToast$1();
2744
2752
  const [isSubmitting, setIsSubmitting] = React8.useState(false);
@@ -2852,8 +2860,7 @@ var CreateTicketDialog = () => {
2852
2860
  ] }) });
2853
2861
  };
2854
2862
  var SupportLayoutContent = () => {
2855
- const baseT = useT();
2856
- const st = createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2863
+ const st = useSupportT();
2857
2864
  const { selectedTicket, selectTicket, openCreateDialog, getUnreadCount } = useSupportLayoutContext();
2858
2865
  const [isMobile, setIsMobile] = React8.useState(false);
2859
2866
  const labels = useMemo(() => ({
@@ -2937,7 +2944,7 @@ var SupportLayout = () => {
2937
2944
  // package.json
2938
2945
  var package_default = {
2939
2946
  name: "@djangocfg/ext-support",
2940
- version: "1.0.22",
2947
+ version: "1.0.23",
2941
2948
  description: "Support ticket system extension for DjangoCFG",
2942
2949
  keywords: [
2943
2950
  "django",
@@ -3005,14 +3012,15 @@ var package_default = {
3005
3012
  "@djangocfg/ext-base": "workspace:*",
3006
3013
  "@djangocfg/i18n": "workspace:*",
3007
3014
  "@djangocfg/ui-core": "workspace:*",
3015
+ "@hookform/resolvers": "^5.2.2",
3008
3016
  consola: "^3.4.2",
3009
3017
  "lucide-react": "^0.545.0",
3010
3018
  moment: "^2.30.1",
3011
3019
  next: "^16",
3020
+ "next-intl": "^4",
3012
3021
  "p-retry": "^7.0.0",
3013
3022
  react: "^19",
3014
3023
  "react-hook-form": "^7.69.0",
3015
- "@hookform/resolvers": "^5.2.2",
3016
3024
  swr: "^2.3.7",
3017
3025
  zod: "^4.3.4"
3018
3026
  },
@@ -3026,6 +3034,7 @@ var package_default = {
3026
3034
  "@types/react": "^19.0.0",
3027
3035
  consola: "^3.4.2",
3028
3036
  moment: "^2.30.1",
3037
+ "next-intl": "^4.1.0",
3029
3038
  "p-retry": "^7.0.0",
3030
3039
  swr: "^2.3.7",
3031
3040
  tsup: "^8.5.0",
package/dist/i18n.cjs CHANGED
@@ -1,3 +1,4 @@
1
+ "use client";
1
2
  var __defProp = Object.defineProperty;
2
3
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
3
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
@@ -19,12 +20,16 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
19
20
  // src/i18n/index.ts
20
21
  var i18n_exports = {};
21
22
  __export(i18n_exports, {
22
- SUPPORT_NAMESPACE: () => SUPPORT_NAMESPACE,
23
- supportI18n: () => supportI18n,
24
- supportTranslations: () => supportTranslations
23
+ en: () => en,
24
+ ko: () => ko,
25
+ ru: () => ru,
26
+ useSupportT: () => useSupportT
25
27
  });
26
28
  module.exports = __toCommonJS(i18n_exports);
27
- var import_i18n = require("@djangocfg/ext-base/i18n");
29
+
30
+ // src/i18n/useSupportT.ts
31
+ var import_next_intl = require("next-intl");
32
+ var import_react = require("react");
28
33
 
29
34
  // src/i18n/locales/en.ts
30
35
  var en = {
@@ -230,17 +235,32 @@ var ko = {
230
235
  }
231
236
  };
232
237
 
233
- // src/i18n/index.ts
234
- var SUPPORT_NAMESPACE = "support";
235
- var supportI18n = (0, import_i18n.createExtensionI18n)({
236
- namespace: SUPPORT_NAMESPACE,
237
- defaultLocale: "en",
238
- locales: { en, ru, ko }
239
- });
240
- var supportTranslations = supportI18n.getAllTranslations();
238
+ // src/i18n/useSupportT.ts
239
+ var translations = { en, ru, ko };
240
+ function getNestedValue(obj, path) {
241
+ const keys = path.split(".");
242
+ let result = obj;
243
+ for (const key of keys) {
244
+ if (result && typeof result === "object" && key in result) {
245
+ result = result[key];
246
+ } else {
247
+ return path;
248
+ }
249
+ }
250
+ return typeof result === "string" ? result : path;
251
+ }
252
+ function useSupportT() {
253
+ const locale = (0, import_next_intl.useLocale)();
254
+ const t = (0, import_react.useMemo)(() => translations[locale] || translations.en, [locale]);
255
+ return (0, import_react.useCallback)(
256
+ (key) => getNestedValue(t, key),
257
+ [t]
258
+ );
259
+ }
241
260
  // Annotate the CommonJS export names for ESM import in node:
242
261
  0 && (module.exports = {
243
- SUPPORT_NAMESPACE,
244
- supportI18n,
245
- supportTranslations
262
+ en,
263
+ ko,
264
+ ru,
265
+ useSupportT
246
266
  });
package/dist/i18n.d.cts CHANGED
@@ -1,16 +1,14 @@
1
- import * as _djangocfg_ext_base_i18n from '@djangocfg/ext-base/i18n';
2
- import { ExtensionKeys, PathKeys } from '@djangocfg/ext-base/i18n';
3
-
4
1
  /**
5
2
  * Support Extension I18n Types
6
3
  */
7
-
8
4
  /**
9
- * All valid keys for support translations (with namespace)
5
+ * Helper type to get dot-notation paths from nested object
10
6
  */
11
- type SupportKeys = ExtensionKeys<'support', SupportTranslations>;
7
+ type PathKeys<T, Prefix extends string = ''> = T extends object ? {
8
+ [K in keyof T]: K extends string ? T[K] extends object ? PathKeys<T[K], `${Prefix}${K}.`> : `${Prefix}${K}` : never;
9
+ }[keyof T] : never;
12
10
  /**
13
- * Keys without namespace prefix (for createTypedExtensionT)
11
+ * Keys for support translations
14
12
  */
15
13
  type SupportLocalKeys = PathKeys<SupportTranslations>;
16
14
  interface SupportTranslations {
@@ -89,11 +87,26 @@ interface SupportTranslations {
89
87
  };
90
88
  }
91
89
 
92
- /** Support extension namespace */
93
- declare const SUPPORT_NAMESPACE: "support";
94
- declare const supportI18n: _djangocfg_ext_base_i18n.ExtensionI18n<SupportTranslations>;
95
- declare const supportTranslations: Record<string, {
96
- [namespace: string]: SupportTranslations;
97
- }>;
90
+ /**
91
+ * Self-contained translation hook for support extension
92
+ *
93
+ * Uses built-in translations based on current locale from next-intl.
94
+ * No need to add translations to app's i18n config.
95
+ *
96
+ * @example
97
+ * ```tsx
98
+ * function TicketList() {
99
+ * const t = useSupportT();
100
+ * return <h1>{t('layout.title')}</h1>;
101
+ * }
102
+ * ```
103
+ */
104
+ declare function useSupportT(): (key: SupportLocalKeys) => string;
105
+
106
+ declare const en: SupportTranslations;
107
+
108
+ declare const ru: SupportTranslations;
109
+
110
+ declare const ko: SupportTranslations;
98
111
 
99
- export { SUPPORT_NAMESPACE, type SupportKeys, type SupportLocalKeys, type SupportTranslations, supportI18n, supportTranslations };
112
+ export { type SupportLocalKeys, type SupportTranslations, en, ko, ru, useSupportT };
package/dist/i18n.d.ts CHANGED
@@ -1,16 +1,14 @@
1
- import * as _djangocfg_ext_base_i18n from '@djangocfg/ext-base/i18n';
2
- import { ExtensionKeys, PathKeys } from '@djangocfg/ext-base/i18n';
3
-
4
1
  /**
5
2
  * Support Extension I18n Types
6
3
  */
7
-
8
4
  /**
9
- * All valid keys for support translations (with namespace)
5
+ * Helper type to get dot-notation paths from nested object
10
6
  */
11
- type SupportKeys = ExtensionKeys<'support', SupportTranslations>;
7
+ type PathKeys<T, Prefix extends string = ''> = T extends object ? {
8
+ [K in keyof T]: K extends string ? T[K] extends object ? PathKeys<T[K], `${Prefix}${K}.`> : `${Prefix}${K}` : never;
9
+ }[keyof T] : never;
12
10
  /**
13
- * Keys without namespace prefix (for createTypedExtensionT)
11
+ * Keys for support translations
14
12
  */
15
13
  type SupportLocalKeys = PathKeys<SupportTranslations>;
16
14
  interface SupportTranslations {
@@ -89,11 +87,26 @@ interface SupportTranslations {
89
87
  };
90
88
  }
91
89
 
92
- /** Support extension namespace */
93
- declare const SUPPORT_NAMESPACE: "support";
94
- declare const supportI18n: _djangocfg_ext_base_i18n.ExtensionI18n<SupportTranslations>;
95
- declare const supportTranslations: Record<string, {
96
- [namespace: string]: SupportTranslations;
97
- }>;
90
+ /**
91
+ * Self-contained translation hook for support extension
92
+ *
93
+ * Uses built-in translations based on current locale from next-intl.
94
+ * No need to add translations to app's i18n config.
95
+ *
96
+ * @example
97
+ * ```tsx
98
+ * function TicketList() {
99
+ * const t = useSupportT();
100
+ * return <h1>{t('layout.title')}</h1>;
101
+ * }
102
+ * ```
103
+ */
104
+ declare function useSupportT(): (key: SupportLocalKeys) => string;
105
+
106
+ declare const en: SupportTranslations;
107
+
108
+ declare const ru: SupportTranslations;
109
+
110
+ declare const ko: SupportTranslations;
98
111
 
99
- export { SUPPORT_NAMESPACE, type SupportKeys, type SupportLocalKeys, type SupportTranslations, supportI18n, supportTranslations };
112
+ export { type SupportLocalKeys, type SupportTranslations, en, ko, ru, useSupportT };
package/dist/i18n.js CHANGED
@@ -1,5 +1,8 @@
1
- // src/i18n/index.ts
2
- import { createExtensionI18n } from "@djangocfg/ext-base/i18n";
1
+ "use client";
2
+
3
+ // src/i18n/useSupportT.ts
4
+ import { useLocale } from "next-intl";
5
+ import { useMemo, useCallback } from "react";
3
6
 
4
7
  // src/i18n/locales/en.ts
5
8
  var en = {
@@ -205,16 +208,31 @@ var ko = {
205
208
  }
206
209
  };
207
210
 
208
- // src/i18n/index.ts
209
- var SUPPORT_NAMESPACE = "support";
210
- var supportI18n = createExtensionI18n({
211
- namespace: SUPPORT_NAMESPACE,
212
- defaultLocale: "en",
213
- locales: { en, ru, ko }
214
- });
215
- var supportTranslations = supportI18n.getAllTranslations();
211
+ // src/i18n/useSupportT.ts
212
+ var translations = { en, ru, ko };
213
+ function getNestedValue(obj, path) {
214
+ const keys = path.split(".");
215
+ let result = obj;
216
+ for (const key of keys) {
217
+ if (result && typeof result === "object" && key in result) {
218
+ result = result[key];
219
+ } else {
220
+ return path;
221
+ }
222
+ }
223
+ return typeof result === "string" ? result : path;
224
+ }
225
+ function useSupportT() {
226
+ const locale = useLocale();
227
+ const t = useMemo(() => translations[locale] || translations.en, [locale]);
228
+ return useCallback(
229
+ (key) => getNestedValue(t, key),
230
+ [t]
231
+ );
232
+ }
216
233
  export {
217
- SUPPORT_NAMESPACE,
218
- supportI18n,
219
- supportTranslations
234
+ en,
235
+ ko,
236
+ ru,
237
+ useSupportT
220
238
  };
package/dist/index.cjs CHANGED
@@ -6,8 +6,7 @@ var zod = require('zod');
6
6
  var api = require('@djangocfg/ext-base/api');
7
7
  var lucideReact = require('lucide-react');
8
8
  var React8 = require('react');
9
- var i18n = require('@djangocfg/ext-base/i18n');
10
- var i18n$1 = require('@djangocfg/i18n');
9
+ var nextIntl = require('next-intl');
11
10
  var uiCore = require('@djangocfg/ui-core');
12
11
  var useSWR = require('swr');
13
12
  var jsxRuntime = require('react/jsx-runtime');
@@ -1832,14 +1831,28 @@ var ko = {
1832
1831
  }
1833
1832
  };
1834
1833
 
1835
- // src/i18n/index.ts
1836
- var SUPPORT_NAMESPACE = "support";
1837
- var supportI18n = i18n.createExtensionI18n({
1838
- namespace: SUPPORT_NAMESPACE,
1839
- defaultLocale: "en",
1840
- locales: { en, ru, ko }
1841
- });
1842
- supportI18n.getAllTranslations();
1834
+ // src/i18n/useSupportT.ts
1835
+ var translations = { en, ru, ko };
1836
+ function getNestedValue(obj, path) {
1837
+ const keys = path.split(".");
1838
+ let result = obj;
1839
+ for (const key of keys) {
1840
+ if (result && typeof result === "object" && key in result) {
1841
+ result = result[key];
1842
+ } else {
1843
+ return path;
1844
+ }
1845
+ }
1846
+ return typeof result === "string" ? result : path;
1847
+ }
1848
+ function useSupportT() {
1849
+ const locale = nextIntl.useLocale();
1850
+ const t = React8.useMemo(() => translations[locale] || translations.en, [locale]);
1851
+ return React8.useCallback(
1852
+ (key) => getNestedValue(t, key),
1853
+ [t]
1854
+ );
1855
+ }
1843
1856
  function useSupportTicketsList(params, client) {
1844
1857
  return useSWR__default.default(
1845
1858
  params ? ["cfg-support-tickets", params] : "cfg-support-tickets",
@@ -2055,8 +2068,7 @@ var getStatusBadgeVariant = (status) => {
2055
2068
  }
2056
2069
  };
2057
2070
  var TicketCard = ({ ticket, isSelected, onClick }) => {
2058
- const baseT = i18n$1.useT();
2059
- const st = i18n.createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2071
+ const st = useSupportT();
2060
2072
  const labels = React8.useMemo(() => ({
2061
2073
  status: {
2062
2074
  open: st("status.open"),
@@ -2382,8 +2394,7 @@ function useSupportLayoutContext() {
2382
2394
  return context;
2383
2395
  }
2384
2396
  var TicketList = () => {
2385
- const baseT = i18n$1.useT();
2386
- const st = i18n.createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2397
+ const st = useSupportT();
2387
2398
  const { selectedTicket, selectTicket } = useSupportLayoutContext();
2388
2399
  const {
2389
2400
  tickets,
@@ -2529,8 +2540,7 @@ var MessageBubble = ({ message, isFromUser, currentUser, labels }) => {
2529
2540
  );
2530
2541
  };
2531
2542
  var MessageList = () => {
2532
- const baseT = i18n$1.useT();
2533
- const st = i18n.createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2543
+ const st = useSupportT();
2534
2544
  const { selectedTicket } = useSupportLayoutContext();
2535
2545
  const { user } = auth.useAuth();
2536
2546
  const labels = React8.useMemo(() => ({
@@ -2681,8 +2691,7 @@ var logger = consola.createConsola({
2681
2691
  }).withTag("ext-support");
2682
2692
  var supportLogger = logger;
2683
2693
  var MessageInput = () => {
2684
- const baseT = i18n$1.useT();
2685
- const st = i18n.createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2694
+ const st = useSupportT();
2686
2695
  const { selectedTicket, sendMessage } = useSupportLayoutContext();
2687
2696
  const { toast } = hooks.useToast();
2688
2697
  const [message, setMessage] = React8.useState("");
@@ -2747,8 +2756,7 @@ var MessageInput = () => {
2747
2756
  ] });
2748
2757
  };
2749
2758
  var CreateTicketDialog = () => {
2750
- const baseT = i18n$1.useT();
2751
- const st = i18n.createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2759
+ const st = useSupportT();
2752
2760
  const { uiState, createTicket, closeCreateDialog } = useSupportLayoutContext();
2753
2761
  const { toast } = uiCore.useToast();
2754
2762
  const [isSubmitting, setIsSubmitting] = React8__default.default.useState(false);
@@ -2862,8 +2870,7 @@ var CreateTicketDialog = () => {
2862
2870
  ] }) });
2863
2871
  };
2864
2872
  var SupportLayoutContent = () => {
2865
- const baseT = i18n$1.useT();
2866
- const st = i18n.createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2873
+ const st = useSupportT();
2867
2874
  const { selectedTicket, selectTicket, openCreateDialog, getUnreadCount } = useSupportLayoutContext();
2868
2875
  const [isMobile, setIsMobile] = React8__default.default.useState(false);
2869
2876
  const labels = React8.useMemo(() => ({
@@ -2947,7 +2954,7 @@ var SupportLayout = () => {
2947
2954
  // package.json
2948
2955
  var package_default = {
2949
2956
  name: "@djangocfg/ext-support",
2950
- version: "1.0.22",
2957
+ version: "1.0.23",
2951
2958
  description: "Support ticket system extension for DjangoCFG",
2952
2959
  keywords: [
2953
2960
  "django",
@@ -3015,14 +3022,15 @@ var package_default = {
3015
3022
  "@djangocfg/ext-base": "workspace:*",
3016
3023
  "@djangocfg/i18n": "workspace:*",
3017
3024
  "@djangocfg/ui-core": "workspace:*",
3025
+ "@hookform/resolvers": "^5.2.2",
3018
3026
  consola: "^3.4.2",
3019
3027
  "lucide-react": "^0.545.0",
3020
3028
  moment: "^2.30.1",
3021
3029
  next: "^16",
3030
+ "next-intl": "^4",
3022
3031
  "p-retry": "^7.0.0",
3023
3032
  react: "^19",
3024
3033
  "react-hook-form": "^7.69.0",
3025
- "@hookform/resolvers": "^5.2.2",
3026
3034
  swr: "^2.3.7",
3027
3035
  zod: "^4.3.4"
3028
3036
  },
@@ -3036,6 +3044,7 @@ var package_default = {
3036
3044
  "@types/react": "^19.0.0",
3037
3045
  consola: "^3.4.2",
3038
3046
  moment: "^2.30.1",
3047
+ "next-intl": "^4.1.0",
3039
3048
  "p-retry": "^7.0.0",
3040
3049
  swr: "^2.3.7",
3041
3050
  tsup: "^8.5.0",
package/dist/index.js CHANGED
@@ -4,8 +4,7 @@ import { z } from 'zod';
4
4
  import { initializeExtensionAPI, createExtensionAPI } from '@djangocfg/ext-base/api';
5
5
  import { ArrowLeft, LifeBuoy, Plus, MessageSquare, Loader2, Send, Headphones, User, Clock } from 'lucide-react';
6
6
  import React8, { createContext, useState, useCallback, useEffect, useMemo, useContext, useRef } from 'react';
7
- import { createExtensionI18n, createTypedExtensionT } from '@djangocfg/ext-base/i18n';
8
- import { useT } from '@djangocfg/i18n';
7
+ import { useLocale } from 'next-intl';
9
8
  import { Button, ResizablePanelGroup, ResizablePanel, ResizableHandle, Skeleton, ScrollArea, Textarea, useToast as useToast$1, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, Form, FormField, FormItem, FormLabel, FormControl, Input, FormMessage, Avatar, AvatarImage, AvatarFallback, Card, CardContent, Badge } from '@djangocfg/ui-core';
10
9
  import useSWR, { useSWRConfig } from 'swr';
11
10
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
@@ -1822,14 +1821,28 @@ var ko = {
1822
1821
  }
1823
1822
  };
1824
1823
 
1825
- // src/i18n/index.ts
1826
- var SUPPORT_NAMESPACE = "support";
1827
- var supportI18n = createExtensionI18n({
1828
- namespace: SUPPORT_NAMESPACE,
1829
- defaultLocale: "en",
1830
- locales: { en, ru, ko }
1831
- });
1832
- supportI18n.getAllTranslations();
1824
+ // src/i18n/useSupportT.ts
1825
+ var translations = { en, ru, ko };
1826
+ function getNestedValue(obj, path) {
1827
+ const keys = path.split(".");
1828
+ let result = obj;
1829
+ for (const key of keys) {
1830
+ if (result && typeof result === "object" && key in result) {
1831
+ result = result[key];
1832
+ } else {
1833
+ return path;
1834
+ }
1835
+ }
1836
+ return typeof result === "string" ? result : path;
1837
+ }
1838
+ function useSupportT() {
1839
+ const locale = useLocale();
1840
+ const t = useMemo(() => translations[locale] || translations.en, [locale]);
1841
+ return useCallback(
1842
+ (key) => getNestedValue(t, key),
1843
+ [t]
1844
+ );
1845
+ }
1833
1846
  function useSupportTicketsList(params, client) {
1834
1847
  return useSWR(
1835
1848
  params ? ["cfg-support-tickets", params] : "cfg-support-tickets",
@@ -2045,8 +2058,7 @@ var getStatusBadgeVariant = (status) => {
2045
2058
  }
2046
2059
  };
2047
2060
  var TicketCard = ({ ticket, isSelected, onClick }) => {
2048
- const baseT = useT();
2049
- const st = createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2061
+ const st = useSupportT();
2050
2062
  const labels = useMemo(() => ({
2051
2063
  status: {
2052
2064
  open: st("status.open"),
@@ -2372,8 +2384,7 @@ function useSupportLayoutContext() {
2372
2384
  return context;
2373
2385
  }
2374
2386
  var TicketList = () => {
2375
- const baseT = useT();
2376
- const st = createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2387
+ const st = useSupportT();
2377
2388
  const { selectedTicket, selectTicket } = useSupportLayoutContext();
2378
2389
  const {
2379
2390
  tickets,
@@ -2519,8 +2530,7 @@ var MessageBubble = ({ message, isFromUser, currentUser, labels }) => {
2519
2530
  );
2520
2531
  };
2521
2532
  var MessageList = () => {
2522
- const baseT = useT();
2523
- const st = createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2533
+ const st = useSupportT();
2524
2534
  const { selectedTicket } = useSupportLayoutContext();
2525
2535
  const { user } = useAuth();
2526
2536
  const labels = useMemo(() => ({
@@ -2671,8 +2681,7 @@ var logger = createConsola({
2671
2681
  }).withTag("ext-support");
2672
2682
  var supportLogger = logger;
2673
2683
  var MessageInput = () => {
2674
- const baseT = useT();
2675
- const st = createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2684
+ const st = useSupportT();
2676
2685
  const { selectedTicket, sendMessage } = useSupportLayoutContext();
2677
2686
  const { toast } = useToast();
2678
2687
  const [message, setMessage] = useState("");
@@ -2737,8 +2746,7 @@ var MessageInput = () => {
2737
2746
  ] });
2738
2747
  };
2739
2748
  var CreateTicketDialog = () => {
2740
- const baseT = useT();
2741
- const st = createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2749
+ const st = useSupportT();
2742
2750
  const { uiState, createTicket, closeCreateDialog } = useSupportLayoutContext();
2743
2751
  const { toast } = useToast$1();
2744
2752
  const [isSubmitting, setIsSubmitting] = React8.useState(false);
@@ -2852,8 +2860,7 @@ var CreateTicketDialog = () => {
2852
2860
  ] }) });
2853
2861
  };
2854
2862
  var SupportLayoutContent = () => {
2855
- const baseT = useT();
2856
- const st = createTypedExtensionT(baseT, SUPPORT_NAMESPACE);
2863
+ const st = useSupportT();
2857
2864
  const { selectedTicket, selectTicket, openCreateDialog, getUnreadCount } = useSupportLayoutContext();
2858
2865
  const [isMobile, setIsMobile] = React8.useState(false);
2859
2866
  const labels = useMemo(() => ({
@@ -2937,7 +2944,7 @@ var SupportLayout = () => {
2937
2944
  // package.json
2938
2945
  var package_default = {
2939
2946
  name: "@djangocfg/ext-support",
2940
- version: "1.0.22",
2947
+ version: "1.0.23",
2941
2948
  description: "Support ticket system extension for DjangoCFG",
2942
2949
  keywords: [
2943
2950
  "django",
@@ -3005,14 +3012,15 @@ var package_default = {
3005
3012
  "@djangocfg/ext-base": "workspace:*",
3006
3013
  "@djangocfg/i18n": "workspace:*",
3007
3014
  "@djangocfg/ui-core": "workspace:*",
3015
+ "@hookform/resolvers": "^5.2.2",
3008
3016
  consola: "^3.4.2",
3009
3017
  "lucide-react": "^0.545.0",
3010
3018
  moment: "^2.30.1",
3011
3019
  next: "^16",
3020
+ "next-intl": "^4",
3012
3021
  "p-retry": "^7.0.0",
3013
3022
  react: "^19",
3014
3023
  "react-hook-form": "^7.69.0",
3015
- "@hookform/resolvers": "^5.2.2",
3016
3024
  swr: "^2.3.7",
3017
3025
  zod: "^4.3.4"
3018
3026
  },
@@ -3026,6 +3034,7 @@ var package_default = {
3026
3034
  "@types/react": "^19.0.0",
3027
3035
  consola: "^3.4.2",
3028
3036
  moment: "^2.30.1",
3037
+ "next-intl": "^4.1.0",
3029
3038
  "p-retry": "^7.0.0",
3030
3039
  swr: "^2.3.7",
3031
3040
  tsup: "^8.5.0",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@djangocfg/ext-support",
3
- "version": "1.0.22",
3
+ "version": "1.0.23",
4
4
  "description": "Support ticket system extension for DjangoCFG",
5
5
  "keywords": [
6
6
  "django",
@@ -64,31 +64,33 @@
64
64
  "check": "tsc --noEmit"
65
65
  },
66
66
  "peerDependencies": {
67
- "@djangocfg/api": "^2.1.111",
68
- "@djangocfg/ext-base": "^1.0.17",
69
- "@djangocfg/i18n": "^2.1.111",
70
- "@djangocfg/ui-core": "^2.1.111",
67
+ "@djangocfg/api": "^2.1.124",
68
+ "@djangocfg/ext-base": "^1.0.18",
69
+ "@djangocfg/i18n": "^2.1.124",
70
+ "@djangocfg/ui-core": "^2.1.124",
71
+ "@hookform/resolvers": "^5.2.2",
71
72
  "consola": "^3.4.2",
72
73
  "lucide-react": "^0.545.0",
73
74
  "moment": "^2.30.1",
74
75
  "next": "^16",
76
+ "next-intl": "^4",
75
77
  "p-retry": "^7.0.0",
76
78
  "react": "^19",
77
79
  "react-hook-form": "^7.69.0",
78
- "@hookform/resolvers": "^5.2.2",
79
80
  "swr": "^2.3.7",
80
81
  "zod": "^4.3.4"
81
82
  },
82
83
  "devDependencies": {
83
- "@djangocfg/api": "^2.1.111",
84
- "@djangocfg/ext-base": "^1.0.17",
85
- "@djangocfg/i18n": "^2.1.111",
86
- "@djangocfg/ui-core": "^2.1.111",
87
- "@djangocfg/typescript-config": "^2.1.111",
84
+ "@djangocfg/api": "^2.1.124",
85
+ "@djangocfg/ext-base": "^1.0.18",
86
+ "@djangocfg/i18n": "^2.1.124",
87
+ "@djangocfg/ui-core": "^2.1.124",
88
+ "@djangocfg/typescript-config": "^2.1.124",
88
89
  "@types/node": "^24.7.2",
89
90
  "@types/react": "^19.0.0",
90
91
  "consola": "^3.4.2",
91
92
  "moment": "^2.30.1",
93
+ "next-intl": "^4.1.0",
92
94
  "p-retry": "^7.0.0",
93
95
  "swr": "^2.3.7",
94
96
  "tsup": "^8.5.0",
package/src/i18n/index.ts CHANGED
@@ -1,23 +1,26 @@
1
1
  /**
2
2
  * Support Extension I18n
3
+ *
4
+ * Self-contained translations - no app configuration needed.
5
+ *
6
+ * @example
7
+ * ```tsx
8
+ * import { useSupportT } from '@djangocfg/ext-support/i18n';
9
+ *
10
+ * function MyComponent() {
11
+ * const t = useSupportT();
12
+ * return <h1>{t('layout.title')}</h1>;
13
+ * }
14
+ * ```
3
15
  */
4
16
 
5
- import { createExtensionI18n } from '@djangocfg/ext-base/i18n';
6
- import type { SupportTranslations } from './types';
7
- import { en } from './locales/en';
8
- import { ru } from './locales/ru';
9
- import { ko } from './locales/ko';
10
-
11
- /** Support extension namespace */
12
- export const SUPPORT_NAMESPACE = 'support' as const;
13
-
14
- export const supportI18n = createExtensionI18n<SupportTranslations>({
15
- namespace: SUPPORT_NAMESPACE,
16
- defaultLocale: 'en',
17
- locales: { en, ru, ko },
18
- });
19
-
20
- export const supportTranslations = supportI18n.getAllTranslations();
17
+ // Self-contained hook (recommended)
18
+ export { useSupportT } from './useSupportT';
21
19
 
22
20
  // Types
23
- export type { SupportTranslations, SupportKeys, SupportLocalKeys } from './types';
21
+ export type { SupportTranslations, SupportLocalKeys } from './types';
22
+
23
+ // Locales (for direct access if needed)
24
+ export { en } from './locales/en';
25
+ export { ru } from './locales/ru';
26
+ export { ko } from './locales/ko';
package/src/i18n/types.ts CHANGED
@@ -2,15 +2,21 @@
2
2
  * Support Extension I18n Types
3
3
  */
4
4
 
5
- import type { ExtensionKeys, PathKeys } from '@djangocfg/ext-base/i18n';
6
-
7
5
  /**
8
- * All valid keys for support translations (with namespace)
6
+ * Helper type to get dot-notation paths from nested object
9
7
  */
10
- export type SupportKeys = ExtensionKeys<'support', SupportTranslations>;
8
+ type PathKeys<T, Prefix extends string = ''> = T extends object
9
+ ? {
10
+ [K in keyof T]: K extends string
11
+ ? T[K] extends object
12
+ ? PathKeys<T[K], `${Prefix}${K}.`>
13
+ : `${Prefix}${K}`
14
+ : never;
15
+ }[keyof T]
16
+ : never;
11
17
 
12
18
  /**
13
- * Keys without namespace prefix (for createTypedExtensionT)
19
+ * Keys for support translations
14
20
  */
15
21
  export type SupportLocalKeys = PathKeys<SupportTranslations>;
16
22
 
@@ -0,0 +1,60 @@
1
+ 'use client';
2
+
3
+ /**
4
+ * Self-contained translation hook for ext-support
5
+ *
6
+ * Uses built-in translations, no app configuration needed.
7
+ */
8
+
9
+ import { useLocale } from 'next-intl';
10
+ import { useMemo, useCallback } from 'react';
11
+
12
+ import type { SupportTranslations, SupportLocalKeys } from './types';
13
+ import { en } from './locales/en';
14
+ import { ru } from './locales/ru';
15
+ import { ko } from './locales/ko';
16
+
17
+ const translations: Record<string, SupportTranslations> = { en, ru, ko };
18
+
19
+ /**
20
+ * Get nested value from object by dot-notation path
21
+ */
22
+ function getNestedValue(obj: Record<string, unknown>, path: string): string {
23
+ const keys = path.split('.');
24
+ let result: unknown = obj;
25
+
26
+ for (const key of keys) {
27
+ if (result && typeof result === 'object' && key in result) {
28
+ result = (result as Record<string, unknown>)[key];
29
+ } else {
30
+ return path; // Return key if not found
31
+ }
32
+ }
33
+
34
+ return typeof result === 'string' ? result : path;
35
+ }
36
+
37
+ /**
38
+ * Self-contained translation hook for support extension
39
+ *
40
+ * Uses built-in translations based on current locale from next-intl.
41
+ * No need to add translations to app's i18n config.
42
+ *
43
+ * @example
44
+ * ```tsx
45
+ * function TicketList() {
46
+ * const t = useSupportT();
47
+ * return <h1>{t('layout.title')}</h1>;
48
+ * }
49
+ * ```
50
+ */
51
+ export function useSupportT(): (key: SupportLocalKeys) => string {
52
+ const locale = useLocale();
53
+
54
+ const t = useMemo(() => translations[locale] || translations.en, [locale]);
55
+
56
+ return useCallback(
57
+ (key: SupportLocalKeys): string => getNestedValue(t as unknown as Record<string, unknown>, key),
58
+ [t]
59
+ );
60
+ }
@@ -9,9 +9,7 @@
9
9
  import { ArrowLeft, LifeBuoy, Plus } from 'lucide-react';
10
10
  import React, { useMemo } from 'react';
11
11
 
12
- import { createTypedExtensionT } from '@djangocfg/ext-base/i18n';
13
- import { useT } from '@djangocfg/i18n';
14
- import { SUPPORT_NAMESPACE, type SupportTranslations } from '../../i18n';
12
+ import { useSupportT } from '../../i18n';
15
13
  import { Button, ResizableHandle, ResizablePanel, ResizablePanelGroup } from '@djangocfg/ui-core';
16
14
 
17
15
  import { SupportProvider } from '../../contexts/SupportContext';
@@ -23,8 +21,7 @@ import { SupportLayoutProvider, useSupportLayoutContext } from './context';
23
21
  // ─────────────────────────────────────────────────────────────────────────
24
22
 
25
23
  const SupportLayoutContent: React.FC = () => {
26
- const baseT = useT();
27
- const st = createTypedExtensionT<typeof SUPPORT_NAMESPACE, SupportTranslations>(baseT, SUPPORT_NAMESPACE);
24
+ const st = useSupportT();
28
25
  const { selectedTicket, selectTicket, openCreateDialog, getUnreadCount } =
29
26
  useSupportLayoutContext();
30
27
  const [isMobile, setIsMobile] = React.useState(false);
@@ -11,9 +11,7 @@ import React, { useMemo } from 'react';
11
11
  import { useForm } from 'react-hook-form';
12
12
  import { z } from 'zod';
13
13
 
14
- import { createTypedExtensionT } from '@djangocfg/ext-base/i18n';
15
- import { useT } from '@djangocfg/i18n';
16
- import { SUPPORT_NAMESPACE, type SupportTranslations } from '../../../i18n';
14
+ import { useSupportT } from '../../../i18n';
17
15
  import {
18
16
  Button, Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle, Form, FormControl,
19
17
  FormField, FormItem, FormLabel, FormMessage, Input, Textarea, useToast
@@ -26,8 +24,7 @@ import { useSupportLayoutContext } from '../context';
26
24
  import type { TicketFormData } from '../types';
27
25
 
28
26
  export const CreateTicketDialog: React.FC = () => {
29
- const baseT = useT();
30
- const st = createTypedExtensionT<typeof SUPPORT_NAMESPACE, SupportTranslations>(baseT, SUPPORT_NAMESPACE);
27
+ const st = useSupportT();
31
28
  const { uiState, createTicket, closeCreateDialog } = useSupportLayoutContext();
32
29
  const { toast } = useToast();
33
30
  const [isSubmitting, setIsSubmitting] = React.useState(false);
@@ -8,9 +8,7 @@
8
8
  import { Send } from 'lucide-react';
9
9
  import React, { useState, useMemo } from 'react';
10
10
 
11
- import { createTypedExtensionT } from '@djangocfg/ext-base/i18n';
12
- import { useT } from '@djangocfg/i18n';
13
- import { SUPPORT_NAMESPACE, type SupportTranslations } from '../../../i18n';
11
+ import { useSupportT } from '../../../i18n';
14
12
  import { Button, Textarea } from '@djangocfg/ui-core';
15
13
  import { useToast } from '@djangocfg/ui-core/hooks';
16
14
 
@@ -18,8 +16,7 @@ import { supportLogger } from '../../../utils/logger';
18
16
  import { useSupportLayoutContext } from '../context';
19
17
 
20
18
  export const MessageInput: React.FC = () => {
21
- const baseT = useT();
22
- const st = createTypedExtensionT<typeof SUPPORT_NAMESPACE, SupportTranslations>(baseT, SUPPORT_NAMESPACE);
19
+ const st = useSupportT();
23
20
  const { selectedTicket, sendMessage } = useSupportLayoutContext();
24
21
  const { toast } = useToast();
25
22
  const [message, setMessage] = useState('');
@@ -10,9 +10,7 @@ import moment from 'moment';
10
10
  import React, { useCallback, useEffect, useRef, useMemo } from 'react';
11
11
 
12
12
  import { useAuth } from '@djangocfg/api/auth';
13
- import { createTypedExtensionT } from '@djangocfg/ext-base/i18n';
14
- import { useT } from '@djangocfg/i18n';
15
- import { SUPPORT_NAMESPACE, type SupportTranslations } from '../../../i18n';
13
+ import { useSupportT } from '../../../i18n';
16
14
  import {
17
15
  Avatar, AvatarFallback, AvatarImage, Button, Card, CardContent, ScrollArea, Skeleton
18
16
  } from '@djangocfg/ui-core';
@@ -124,8 +122,7 @@ const MessageBubble: React.FC<MessageBubbleProps> = ({ message, isFromUser, curr
124
122
  };
125
123
 
126
124
  export const MessageList: React.FC = () => {
127
- const baseT = useT();
128
- const st = createTypedExtensionT<typeof SUPPORT_NAMESPACE, SupportTranslations>(baseT, SUPPORT_NAMESPACE);
125
+ const st = useSupportT();
129
126
  const { selectedTicket } = useSupportLayoutContext();
130
127
  const { user } = useAuth();
131
128
 
@@ -9,9 +9,7 @@ import { Clock, MessageSquare } from 'lucide-react';
9
9
  import moment from 'moment';
10
10
  import React, { useMemo, useCallback } from 'react';
11
11
 
12
- import { createTypedExtensionT } from '@djangocfg/ext-base/i18n';
13
- import { useT } from '@djangocfg/i18n';
14
- import { SUPPORT_NAMESPACE, type SupportTranslations } from '../../../i18n';
12
+ import { useSupportT } from '../../../i18n';
15
13
  import { Badge, Card, CardContent } from '@djangocfg/ui-core';
16
14
  import { cn } from '@djangocfg/ui-core/lib';
17
15
 
@@ -43,8 +41,7 @@ const getStatusBadgeVariant = (
43
41
  };
44
42
 
45
43
  export const TicketCard: React.FC<TicketCardProps> = ({ ticket, isSelected, onClick }) => {
46
- const baseT = useT();
47
- const st = createTypedExtensionT<typeof SUPPORT_NAMESPACE, SupportTranslations>(baseT, SUPPORT_NAMESPACE);
44
+ const st = useSupportT();
48
45
 
49
46
  const labels = useMemo(() => ({
50
47
  status: {
@@ -8,9 +8,7 @@
8
8
  import { Loader2, MessageSquare } from 'lucide-react';
9
9
  import React, { useEffect, useRef, useMemo } from 'react';
10
10
 
11
- import { createTypedExtensionT } from '@djangocfg/ext-base/i18n';
12
- import { useT } from '@djangocfg/i18n';
13
- import { SUPPORT_NAMESPACE, type SupportTranslations } from '../../../i18n';
11
+ import { useSupportT } from '../../../i18n';
14
12
  import { Button, ScrollArea, Skeleton } from '@djangocfg/ui-core';
15
13
 
16
14
  import { useSupportLayoutContext } from '../context';
@@ -19,8 +17,7 @@ import { useInfiniteTickets } from '../hooks';
19
17
  import { TicketCard } from './TicketCard';
20
18
 
21
19
  export const TicketList: React.FC = () => {
22
- const baseT = useT();
23
- const st = createTypedExtensionT<typeof SUPPORT_NAMESPACE, SupportTranslations>(baseT, SUPPORT_NAMESPACE);
20
+ const st = useSupportT();
24
21
  const { selectedTicket, selectTicket } = useSupportLayoutContext();
25
22
  const {
26
23
  tickets,