@recruitnepal/shared-packages 1.7.1 → 1.7.4

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.
Files changed (42) hide show
  1. package/dist/components/common/NoData.d.ts +3 -4
  2. package/dist/components/common/NoData.d.ts.map +1 -1
  3. package/dist/components/common/NoData.js +4 -2
  4. package/dist/components/cv/ResponsivePreview.d.ts +7 -0
  5. package/dist/components/cv/ResponsivePreview.d.ts.map +1 -0
  6. package/dist/components/cv/ResponsivePreview.js +47 -0
  7. package/dist/components/cv-builder/forms/AboutForm.d.ts +2 -0
  8. package/dist/components/cv-builder/forms/AboutForm.d.ts.map +1 -0
  9. package/dist/components/cv-builder/forms/AboutForm.js +86 -0
  10. package/dist/components/cv-builder/forms/AdditionalDetailsForm.d.ts +2 -0
  11. package/dist/components/cv-builder/forms/AdditionalDetailsForm.d.ts.map +1 -0
  12. package/dist/components/cv-builder/forms/AdditionalDetailsForm.js +227 -0
  13. package/dist/components/cv-builder/forms/EducationForm.d.ts +2 -0
  14. package/dist/components/cv-builder/forms/EducationForm.d.ts.map +1 -0
  15. package/dist/components/cv-builder/forms/EducationForm.js +168 -0
  16. package/dist/components/cv-builder/forms/ExperienceForm.d.ts +2 -0
  17. package/dist/components/cv-builder/forms/ExperienceForm.d.ts.map +1 -0
  18. package/dist/components/cv-builder/forms/ExperienceForm.js +266 -0
  19. package/dist/components/cv-builder/forms/PortfolioForm.d.ts +2 -0
  20. package/dist/components/cv-builder/forms/PortfolioForm.d.ts.map +1 -0
  21. package/dist/components/cv-builder/forms/PortfolioForm.js +159 -0
  22. package/dist/components/cv-builder/forms/ProjectsForm.d.ts +2 -0
  23. package/dist/components/cv-builder/forms/ProjectsForm.d.ts.map +1 -0
  24. package/dist/components/cv-builder/forms/ProjectsForm.js +134 -0
  25. package/dist/components/cv-builder/forms/SkillsForm.d.ts +2 -0
  26. package/dist/components/cv-builder/forms/SkillsForm.d.ts.map +1 -0
  27. package/dist/components/cv-builder/forms/SkillsForm.js +250 -0
  28. package/dist/components/ui/BulletListTextarea.d.ts.map +1 -1
  29. package/dist/components/ui/BulletListTextarea.js +3 -2
  30. package/dist/components/ui/DesignationSelect.d.ts +1 -4
  31. package/dist/components/ui/DesignationSelect.d.ts.map +1 -1
  32. package/dist/components/ui/DesignationSelect.js +6 -7
  33. package/dist/components/ui/IndustrySelect.d.ts +1 -4
  34. package/dist/components/ui/IndustrySelect.d.ts.map +1 -1
  35. package/dist/components/ui/IndustrySelect.js +6 -7
  36. package/dist/components/ui/MultiSelectOptions.d.ts +2 -4
  37. package/dist/components/ui/MultiSelectOptions.d.ts.map +1 -1
  38. package/dist/components/ui/MultiSelectOptions.js +17 -20
  39. package/dist/index.d.ts +0 -33
  40. package/dist/index.d.ts.map +1 -1
  41. package/dist/index.js +1 -27
  42. package/package.json +44 -51
@@ -0,0 +1,250 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
+ import { useEffect, useRef, useCallback, useMemo } from 'react';
4
+ import { useForm, useFieldArray } from 'react-hook-form';
5
+ import { zodResolver } from '@hookform/resolvers/zod';
6
+ import { z } from 'zod';
7
+ import { Form, FormControl, FormField, FormItem, FormLabel, FormMessage, } from '@/components/ui/form';
8
+ import { Input } from '@/components/ui/input';
9
+ import { Textarea } from '@/components/ui/textarea';
10
+ import { Button } from '@/components/ui/button';
11
+ import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, } from '@/components/ui/accordion';
12
+ import { Plus, Trash2 } from 'lucide-react';
13
+ import { useCvPreview } from '@/stores/cvPreview.store';
14
+ import { useCvDraftsStore } from '@/stores/cvDrafts.store';
15
+ import { MultiSelectOptions } from '@/components/multi-select';
16
+ import { useSkills } from '@/hooks/api/useSkills';
17
+ import { monthsDropdown, yearsDropdown } from '@/utils/commonDropdownOptions';
18
+ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from '@/components/ui/select';
19
+ import NoData from '@/components/common/no-data';
20
+ const dateSchema = z.object({
21
+ year: z
22
+ .union([
23
+ z.number().int().gte(1000).lte(9999),
24
+ z.string().regex(/^\d{4}$/, 'Year must be a 4-digit number'),
25
+ ])
26
+ .transform((val) => (typeof val === 'string' ? Number(val) : val)),
27
+ month: z
28
+ .union([
29
+ z.number().int().gte(1).lte(12),
30
+ z.string().regex(/^([1-9]|1[0-2])$/, 'Month must be between 1 and 12'),
31
+ ])
32
+ .transform((val) => (typeof val === 'string' ? Number(val) : val)),
33
+ day: z
34
+ .union([
35
+ z.number().int().default(1),
36
+ z.string().transform((val) => Number(val)),
37
+ ])
38
+ .default(1),
39
+ });
40
+ const skillTrainingSchema = z.object({
41
+ id: z.string().optional(),
42
+ institute_name: z.string().min(1, { message: 'Institute Name is required' }),
43
+ course_name: z.string().min(1, { message: 'Course Name is required' }),
44
+ description: z.string().min(1, { message: 'Description is required' }),
45
+ skills: z
46
+ .array(z.string())
47
+ .min(1, { message: 'Please add at least one skill.' }),
48
+ start: dateSchema,
49
+ end: dateSchema,
50
+ training_url: z.string().url().optional().or(z.literal('')),
51
+ });
52
+ const skillTrainingFormSchema = z.object({
53
+ trainingEntries: z.array(skillTrainingSchema).min(0),
54
+ // Global skills field
55
+ globalSkills: z.array(z.string()).min(0),
56
+ });
57
+ export default function SkillsForm() {
58
+ const { live, setSections } = useCvPreview();
59
+ const { getCurrentDraft, updateDraft } = useCvDraftsStore();
60
+ const { skillsQuery: infiniteSkillsQuery } = useSkills();
61
+ // Extract trainings from live data
62
+ const trainingsList = useMemo(() => {
63
+ return (live?.sections?.trainings && Array.isArray(live.sections.trainings))
64
+ ? live.sections.trainings
65
+ : [];
66
+ }, [live?.sections?.trainings]);
67
+ // Extract global skills
68
+ const skillsCategory = live?.sections?.skills?.[0];
69
+ const skillsList = skillsCategory?.skills || [];
70
+ const skillsArray = skillsList.map(s => s.name).filter(Boolean);
71
+ // Transform trainings to form format
72
+ const defaultTrainings = useMemo(() => {
73
+ return trainingsList.map((t) => ({
74
+ id: t.id,
75
+ institute_name: t.institute || '',
76
+ course_name: t.course || '',
77
+ description: t.description || '',
78
+ skills: t.skills || [],
79
+ start: t.startDate
80
+ ? {
81
+ year: new Date(t.startDate).getFullYear(),
82
+ month: new Date(t.startDate).getMonth() + 1,
83
+ day: 1,
84
+ }
85
+ : { year: new Date().getFullYear(), month: 1, day: 1 },
86
+ end: t.endDate
87
+ ? {
88
+ year: new Date(t.endDate).getFullYear(),
89
+ month: new Date(t.endDate).getMonth() + 1,
90
+ day: 1,
91
+ }
92
+ : { year: new Date().getFullYear(), month: 1, day: 1 },
93
+ training_url: t.url || '',
94
+ }));
95
+ }, [trainingsList]);
96
+ const form = useForm({
97
+ resolver: zodResolver(skillTrainingFormSchema),
98
+ defaultValues: {
99
+ trainingEntries: defaultTrainings.length > 0 ? defaultTrainings : [],
100
+ globalSkills: skillsArray,
101
+ },
102
+ });
103
+ const { fields, append, remove } = useFieldArray({
104
+ control: form.control,
105
+ name: 'trainingEntries',
106
+ });
107
+ // Track if we've initialized to prevent reset loops
108
+ const initializedRef = useRef(false);
109
+ const prevTrainingsRef = useRef('');
110
+ const prevSkillsRef = useRef('');
111
+ useEffect(() => {
112
+ const currentTrainingsStr = JSON.stringify(defaultTrainings);
113
+ // Only reset if:
114
+ // 1. We haven't initialized yet
115
+ // 2. OR the data actually changed from an external source (different structure)
116
+ if (!initializedRef.current) {
117
+ form.reset({
118
+ trainingEntries: defaultTrainings.length > 0 ? defaultTrainings : [],
119
+ globalSkills: skillsArray,
120
+ });
121
+ initializedRef.current = true;
122
+ prevTrainingsRef.current = currentTrainingsStr;
123
+ prevSkillsRef.current = JSON.stringify(skillsArray);
124
+ }
125
+ else {
126
+ // Only reset if the structure changed significantly (e.g., loading a draft)
127
+ const prevTrainings = JSON.parse(prevTrainingsRef.current || '[]');
128
+ const currentIds = defaultTrainings.map(e => e.id).sort().join(',');
129
+ const prevIds = prevTrainings.map((e) => e.id).sort().join(',');
130
+ // Only reset trainings if IDs changed (new draft loaded) or count changed significantly
131
+ if (currentIds !== prevIds || Math.abs(defaultTrainings.length - prevTrainings.length) > 0) {
132
+ form.reset({
133
+ trainingEntries: defaultTrainings.length > 0 ? defaultTrainings : [],
134
+ globalSkills: skillsArray,
135
+ });
136
+ prevTrainingsRef.current = currentTrainingsStr;
137
+ prevSkillsRef.current = JSON.stringify(skillsArray);
138
+ }
139
+ else {
140
+ const currentSkillsStr = JSON.stringify(skillsArray);
141
+ if (prevSkillsRef.current !== currentSkillsStr) {
142
+ // Only update globalSkills if it changed from external source
143
+ // Don't reset if user is typing (that would be handled by the watch)
144
+ form.setValue('globalSkills', skillsArray);
145
+ prevSkillsRef.current = currentSkillsStr;
146
+ }
147
+ }
148
+ }
149
+ }, [defaultTrainings, skillsArray, form]);
150
+ const debRefTrainings = useRef(null);
151
+ const debRefSkills = useRef(null);
152
+ // Format "YYYY-MM" safely from {year, month}
153
+ const mapTrainings = useCallback((rows) => {
154
+ const ymToStr = (ym) => ym?.year && ym?.month
155
+ ? `${String(ym.year).padStart(4, '0')}-${String(ym.month).padStart(2, '0')}`
156
+ : undefined;
157
+ return (rows ?? []).map((t, i) => ({
158
+ id: String(t.id ?? `tmp-training-${i}`),
159
+ course: t.course_name || '',
160
+ institute: t.institute_name || '',
161
+ description: t.description || '',
162
+ skills: Array.isArray(t.skills) ? t.skills : [],
163
+ startDate: ymToStr(t.start),
164
+ endDate: ymToStr(t.end),
165
+ url: t.training_url || '',
166
+ }));
167
+ }, []);
168
+ const pushTrainings = useCallback((rows) => {
169
+ if (debRefTrainings.current)
170
+ clearTimeout(debRefTrainings.current);
171
+ const payload = mapTrainings(rows);
172
+ debRefTrainings.current = window.setTimeout(() => {
173
+ setSections({ trainings: payload });
174
+ }, 160);
175
+ }, [setSections, mapTrainings]);
176
+ const pushSkills = useCallback((skillsArray) => {
177
+ if (debRefSkills.current)
178
+ clearTimeout(debRefSkills.current);
179
+ debRefSkills.current = window.setTimeout(() => {
180
+ const skillNames = skillsArray.filter(Boolean);
181
+ if (skillNames.length === 0) {
182
+ setSections({ skills: [] });
183
+ return;
184
+ }
185
+ const templateSkills = skillNames.map(name => ({ name }));
186
+ const category = {
187
+ id: 'all-skills',
188
+ category: 'Skills',
189
+ skills: templateSkills,
190
+ };
191
+ setSections({ skills: [category] });
192
+ }, 300);
193
+ }, [setSections]);
194
+ // Watch form changes for trainings
195
+ useEffect(() => {
196
+ const sub = form.watch((_v, { name }) => {
197
+ if (!name?.startsWith('trainingEntries'))
198
+ return;
199
+ pushTrainings(form.getValues().trainingEntries ?? []);
200
+ });
201
+ // bootstrap once
202
+ pushTrainings(form.getValues().trainingEntries ?? []);
203
+ return () => {
204
+ sub?.unsubscribe?.();
205
+ if (debRefTrainings.current)
206
+ clearTimeout(debRefTrainings.current);
207
+ };
208
+ }, [form, pushTrainings]);
209
+ // Watch global skills
210
+ useEffect(() => {
211
+ const sub = form.watch((v) => {
212
+ if (Array.isArray(v.globalSkills)) {
213
+ const skills = v.globalSkills.filter((s) => typeof s === 'string' && s.length > 0);
214
+ pushSkills(skills);
215
+ }
216
+ else {
217
+ pushSkills([]);
218
+ }
219
+ });
220
+ return () => {
221
+ sub?.unsubscribe?.();
222
+ if (debRefSkills.current)
223
+ clearTimeout(debRefSkills.current);
224
+ };
225
+ }, [form, pushSkills]);
226
+ // Update draft when data changes
227
+ useEffect(() => {
228
+ const currentDraft = getCurrentDraft();
229
+ if (currentDraft && live) {
230
+ updateDraft(currentDraft.id, {
231
+ cv_data: live,
232
+ });
233
+ }
234
+ }, [live, getCurrentDraft, updateDraft]);
235
+ return (_jsxs("div", { className: "mb-6", children: [_jsx("h1", { className: "text-2xl mb-2 font-medium", children: "Skills & Trainings" }), _jsx("p", { className: "text-sm mb-6", children: "Add your skills and training certifications." }), _jsx(Form, { ...form, children: _jsxs("form", { className: "space-y-6", children: [_jsx("div", { className: "mb-6", children: _jsx(FormField, { control: form.control, name: "globalSkills", render: ({ field }) => (_jsxs(FormItem, { children: [_jsx(FormLabel, { children: "Skills" }), _jsx(FormControl, { children: _jsx(MultiSelectOptions, { value: field.value || [], onChange: field.onChange, options: [], query: infiniteSkillsQuery }) }), _jsx(FormMessage, {})] })) }) }), _jsxs("div", { children: [_jsx("h2", { className: "text-lg font-medium mb-4", children: "Trainings & Certifications" }), !fields.length && _jsx(NoData, {}), fields.map((field, index) => (_jsx(Accordion, { type: "single", collapsible: true, children: _jsxs(AccordionItem, { value: `training-${index}`, className: "border-none", children: [_jsxs("div", { className: "flex items-center justify-between bg-primary/10 py-3 px-4 rounded-xl accordion-grow", children: [_jsx(AccordionTrigger, { className: "h-[50px] flex-grow hover:no-underline p-0", children: _jsx("div", { className: "flex items-center justify-between w-full", children: _jsxs("div", { className: "flex flex-col items-start", children: [_jsx("p", { className: "text-base font-semibold", children: form.watch(`trainingEntries.${index}.course_name`) || 'New Training Entry' }), _jsx("p", { className: "text-sm font-light", children: form.watch(`trainingEntries.${index}.institute_name`) })] }) }) }), _jsx("div", { className: "pl-3 border-l border-black/60 ml-4", children: _jsx(Button, { variant: "link", type: "button", size: "sm", onClick: (e) => {
236
+ e.stopPropagation();
237
+ remove(index);
238
+ }, className: "h-8 w-8 p-0 hover:text-destructive", children: _jsx(Trash2, { size: 20, className: "text-text-primary hover:text-destructive" }) }) })] }), _jsx(AccordionContent, { children: _jsx("div", { className: "p-4 pt-0", children: _jsxs("div", { className: "space-y-4", children: [_jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsx(FormField, { control: form.control, name: `trainingEntries.${index}.institute_name`, render: ({ field }) => (_jsxs(FormItem, { className: "w-full", children: [_jsx(FormLabel, { children: "Institution Name" }), _jsx(FormControl, { children: _jsx(Input, { placeholder: "Enter Institution Name", ...field }) }), _jsx(FormMessage, {})] })) }), _jsx(FormField, { control: form.control, name: `trainingEntries.${index}.course_name`, render: ({ field }) => (_jsxs(FormItem, { className: "w-full", children: [_jsx(FormLabel, { children: "Course Name" }), _jsx(FormControl, { children: _jsx(Input, { placeholder: "Enter course name", ...field }) }), _jsx(FormMessage, {})] })) })] }), _jsxs("div", { className: "grid grid-cols-2 gap-4", children: [_jsxs("div", { children: [_jsx(FormLabel, { children: "Start Date" }), _jsxs("div", { className: "flex gap-2", children: [_jsx(FormField, { control: form.control, name: `trainingEntries.${index}.start.month`, render: ({ field }) => (_jsxs(FormItem, { className: "w-full", children: [_jsxs(Select, { onValueChange: (val) => field.onChange(Number(val)), value: field.value?.toString(), children: [_jsx(FormControl, { children: _jsx(SelectTrigger, { children: _jsx(SelectValue, { placeholder: "Month" }) }) }), _jsx(SelectContent, { children: monthsDropdown.map((month) => (_jsx(SelectItem, { value: month.value.toString(), children: month.label }, month.value))) })] }), _jsx(FormMessage, {})] })) }), _jsx(FormField, { control: form.control, name: `trainingEntries.${index}.start.year`, render: ({ field }) => (_jsxs(FormItem, { className: "w-full", children: [_jsxs(Select, { onValueChange: (val) => field.onChange(Number(val)), value: field.value?.toString(), children: [_jsx(FormControl, { children: _jsx(SelectTrigger, { children: _jsx(SelectValue, { placeholder: "Year" }) }) }), _jsx(SelectContent, { children: yearsDropdown.map((year) => (_jsx(SelectItem, { value: year, children: year }, year))) })] }), _jsx(FormMessage, {})] })) })] })] }), _jsxs("div", { children: [_jsx(FormLabel, { children: "End Date" }), _jsxs("div", { className: "flex gap-2", children: [_jsx(FormField, { control: form.control, name: `trainingEntries.${index}.end.month`, render: ({ field }) => (_jsxs(FormItem, { className: "w-full", children: [_jsxs(Select, { onValueChange: (val) => field.onChange(Number(val)), value: field.value?.toString(), children: [_jsx(FormControl, { children: _jsx(SelectTrigger, { children: _jsx(SelectValue, { placeholder: "Month" }) }) }), _jsx(SelectContent, { children: monthsDropdown.map((month) => (_jsx(SelectItem, { value: month.value.toString(), children: month.label }, month.value))) })] }), _jsx(FormMessage, {})] })) }), _jsx(FormField, { control: form.control, name: `trainingEntries.${index}.end.year`, render: ({ field }) => (_jsxs(FormItem, { className: "w-full", children: [_jsxs(Select, { onValueChange: (val) => field.onChange(Number(val)), value: field.value?.toString(), children: [_jsx(FormControl, { children: _jsx(SelectTrigger, { children: _jsx(SelectValue, { placeholder: "Year" }) }) }), _jsx(SelectContent, { children: yearsDropdown.map((year) => (_jsx(SelectItem, { value: year, children: year }, year))) })] }), _jsx(FormMessage, {})] })) })] })] })] }), _jsx(FormField, { control: form.control, name: `trainingEntries.${index}.description`, render: ({ field }) => (_jsxs(FormItem, { className: "w-full", children: [_jsx(FormLabel, { children: "Training Description" }), _jsx(FormControl, { children: _jsx(Textarea, { placeholder: "Start Typing...", ...field }) }), _jsx(FormMessage, {})] })) }), _jsx(FormField, { control: form.control, name: `trainingEntries.${index}.training_url`, render: ({ field }) => (_jsxs(FormItem, { className: "w-full", children: [_jsx(FormLabel, { children: "Training URL (optional)" }), _jsx(FormControl, { children: _jsx(Input, { placeholder: "https://example.com/certificate", ...field }) }), _jsx(FormMessage, {})] })) }), _jsx(FormField, { control: form.control, name: `trainingEntries.${index}.skills`, render: ({ field }) => (_jsxs(FormItem, { children: [_jsx(FormLabel, { children: "Skills Acquired" }), _jsx(FormControl, { children: _jsx(MultiSelectOptions, { value: field.value || [], onChange: field.onChange, options: [], query: infiniteSkillsQuery }) }), _jsx(FormMessage, {})] })) })] }) }) })] }) }, field.id))), _jsxs(Button, { type: "button", variant: "outline", size: "sm", className: "text-primary w-fit", onClick: () => {
239
+ append({
240
+ id: undefined,
241
+ institute_name: '',
242
+ course_name: '',
243
+ description: '',
244
+ skills: [],
245
+ start: { year: new Date().getFullYear(), month: 1, day: 1 },
246
+ end: { year: new Date().getFullYear(), month: 1, day: 1 },
247
+ training_url: '',
248
+ });
249
+ }, children: [_jsx(Plus, { className: "h-4 w-4 mr-1" }), " Add Training"] })] })] }) })] }));
250
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"BulletListTextarea.d.ts","sourceRoot":"","sources":["../../../src/components/ui/BulletListTextarea.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAG/B,QAAA,MAAM,MAAM,YAAO,CAAC;AAEpB,iBAAS,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,EAAE,CAQ/E;AAED,iBAAS,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzC;AAED,MAAM,WAAW,uBAAuB;IACtC,iGAAiG;IACjG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAC5C,+DAA+D;IAC/D,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB;AAED,QAAA,MAAM,kBAAkB,qGA2EvB,CAAC;AAIF,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,CAAC"}
1
+ {"version":3,"file":"BulletListTextarea.d.ts","sourceRoot":"","sources":["../../../src/components/ui/BulletListTextarea.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAI/B,QAAA,MAAM,MAAM,YAAO,CAAC;AAEpB,iBAAS,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,MAAM,EAAE,CAQ/E;AAED,iBAAS,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAEzC;AAED,MAAM,WAAW,uBAAuB;IACtC,iGAAiG;IACjG,KAAK,EAAE,MAAM,EAAE,GAAG,MAAM,GAAG,SAAS,GAAG,IAAI,CAAC;IAC5C,+DAA+D;IAC/D,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6CAA6C;IAC7C,IAAI,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;CACxB;AAED,QAAA,MAAM,kBAAkB,qGAwEvB,CAAC;AAIF,OAAO,EAAE,kBAAkB,EAAE,MAAM,EAAE,WAAW,EAAE,gBAAgB,EAAE,CAAC"}
@@ -1,7 +1,8 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import * as React from 'react';
4
- import { cn } from '../../utils/cn';
4
+ import { Textarea } from '@/components/ui/textarea';
5
+ import { cn } from '@/utils/lib/utils';
5
6
  const BULLET = '• ';
6
7
  function normalizeToArray(value) {
7
8
  if (Array.isArray(value)) {
@@ -54,7 +55,7 @@ const BulletListTextarea = React.forwardRef(({ value, onChange, placeholder = `$
54
55
  }
55
56
  }
56
57
  };
57
- return (_jsxs("div", { className: "space-y-1.5", children: [_jsx("textarea", { ref: ref, placeholder: placeholder, value: textValue, onChange: handleChange, onKeyDown: handleKeyDown, rows: rows, disabled: disabled, className: cn('min-h-[120px] w-full resize-y rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50', className) }), hint && _jsx("p", { className: "text-xs text-muted-foreground", children: hint })] }));
58
+ return (_jsxs("div", { className: "space-y-1.5", children: [_jsx(Textarea, { ref: ref, placeholder: placeholder, value: textValue, onChange: handleChange, onKeyDown: handleKeyDown, rows: rows, disabled: disabled, className: cn('min-h-[120px] resize-y text-base', className) }), hint && _jsx("p", { className: "text-xs text-muted-foreground", children: hint })] }));
58
59
  });
59
60
  BulletListTextarea.displayName = 'BulletListTextarea';
60
61
  export { BulletListTextarea, BULLET, stripBullet, normalizeToArray };
@@ -5,9 +5,6 @@ export interface DesignationSelectProps {
5
5
  disabled?: boolean;
6
6
  className?: string;
7
7
  valueType?: 'id' | 'title';
8
- /** Optional auth token (e.g. from useSessionStore) */
9
- token?: string | null;
10
8
  }
11
- export default function DesignationSelect({ value, onChange, placeholder, disabled, className, valueType, // Default to title since most forms use title
12
- token, }: DesignationSelectProps): import("react/jsx-runtime").JSX.Element;
9
+ export default function DesignationSelect({ value, onChange, placeholder, disabled, className, valueType, }: DesignationSelectProps): import("react/jsx-runtime").JSX.Element;
13
10
  //# sourceMappingURL=DesignationSelect.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"DesignationSelect.d.ts","sourceRoot":"","sources":["../../../src/components/ui/DesignationSelect.tsx"],"names":[],"mappings":"AAkBA,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC;IAC3B,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAQD,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,EACxC,KAAK,EACL,QAAQ,EACR,WAAoC,EACpC,QAAQ,EACR,SAAS,EACT,SAAmB,EAAE,8CAA8C;AACnE,KAAK,GACN,EAAE,sBAAsB,2CA6JxB"}
1
+ {"version":3,"file":"DesignationSelect.d.ts","sourceRoot":"","sources":["../../../src/components/ui/DesignationSelect.tsx"],"names":[],"mappings":"AAkBA,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC;CAC5B;AAQD,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,EACxC,KAAK,EACL,QAAQ,EACR,WAAoC,EACpC,QAAQ,EACR,SAAS,EACT,SAAmB,GACpB,EAAE,sBAAsB,2CA4JxB"}
@@ -2,16 +2,16 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import * as React from 'react';
4
4
  import { ChevronsUpDown, Check } from 'lucide-react';
5
- import { useDesignations } from '../../hooks/useDesignations';
6
- import { cn } from '../../utils/cn';
7
- import { useDebounce } from '../../hooks/useDebounce';
8
- import { Popover, PopoverContent, PopoverTrigger } from './popover';
9
- import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from './command';
5
+ import { useDesignations } from '@/hooks/api/designations/useDesignations';
6
+ import { cn } from '@/utils/lib/utils';
7
+ import { useDebounce } from '@/hooks/useDebounce';
8
+ import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
9
+ import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from '@/components/ui/command';
10
10
  /** Matches ShadCN <SelectTrigger> so it looks like a normal input */
11
11
  const selectTriggerClasses = 'flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none disabled:cursor-not-allowed cursor-pointer disabled:opacity-50';
12
12
  const toString = (v) => String(v ?? '');
13
13
  export default function DesignationSelect({ value, onChange, placeholder = 'Select a designation', disabled, className, valueType = 'title', // Default to title since most forms use title
14
- token, }) {
14
+ }) {
15
15
  const [open, setOpen] = React.useState(false);
16
16
  const [searchQuery, setSearchQuery] = React.useState('');
17
17
  const debouncedSearch = useDebounce(searchQuery, 300);
@@ -19,7 +19,6 @@ token, }) {
19
19
  const { designations = [], designationsQuery, isLoading, } = useDesignations({
20
20
  queryObject: debouncedSearch ? { search: debouncedSearch } : {},
21
21
  limit: 50,
22
- token,
23
22
  });
24
23
  const handleListScroll = React.useCallback((e) => {
25
24
  if (!designationsQuery.hasNextPage ||
@@ -5,9 +5,6 @@ export interface IndustrySelectProps {
5
5
  disabled?: boolean;
6
6
  className?: string;
7
7
  valueType?: 'id' | 'title';
8
- /** Optional auth token (e.g. from useSessionStore) */
9
- token?: string | null;
10
8
  }
11
- export default function IndustrySelect({ value, onChange, placeholder, disabled, className, valueType, // Default to ID for backward compatibility
12
- token, }: IndustrySelectProps): import("react/jsx-runtime").JSX.Element;
9
+ export default function IndustrySelect({ value, onChange, placeholder, disabled, className, valueType, }: IndustrySelectProps): import("react/jsx-runtime").JSX.Element;
13
10
  //# sourceMappingURL=IndustrySelect.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IndustrySelect.d.ts","sourceRoot":"","sources":["../../../src/components/ui/IndustrySelect.tsx"],"names":[],"mappings":"AAkBA,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC;IAC3B,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB;AAQD,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EACrC,KAAK,EACL,QAAQ,EACR,WAAkC,EAClC,QAAQ,EACR,SAAS,EACT,SAAgB,EAAE,2CAA2C;AAC7D,KAAK,GACN,EAAE,mBAAmB,2CA6JrB"}
1
+ {"version":3,"file":"IndustrySelect.d.ts","sourceRoot":"","sources":["../../../src/components/ui/IndustrySelect.tsx"],"names":[],"mappings":"AAkBA,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,IAAI,GAAG,OAAO,CAAC;CAC5B;AAQD,MAAM,CAAC,OAAO,UAAU,cAAc,CAAC,EACrC,KAAK,EACL,QAAQ,EACR,WAAkC,EAClC,QAAQ,EACR,SAAS,EACT,SAAgB,GACjB,EAAE,mBAAmB,2CA4JrB"}
@@ -2,16 +2,16 @@
2
2
  import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
3
  import * as React from 'react';
4
4
  import { ChevronsUpDown, Check } from 'lucide-react';
5
- import { useIndustries } from '../../hooks/useIndustries';
6
- import { cn } from '../../utils/cn';
7
- import { useDebounce } from '../../hooks/useDebounce';
8
- import { Popover, PopoverContent, PopoverTrigger } from './popover';
9
- import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from './command';
5
+ import { useIndustries } from '@/hooks/api/industries/useIndustries';
6
+ import { cn } from '@/utils/lib/utils';
7
+ import { useDebounce } from '@/hooks/useDebounce';
8
+ import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover';
9
+ import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from '@/components/ui/command';
10
10
  /** Matches ShadCN <SelectTrigger> so it looks like a normal input */
11
11
  const selectTriggerClasses = 'flex h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none disabled:cursor-not-allowed cursor-pointer disabled:opacity-50';
12
12
  const toString = (v) => String(v ?? '');
13
13
  export default function IndustrySelect({ value, onChange, placeholder = 'Select an industry', disabled, className, valueType = 'id', // Default to ID for backward compatibility
14
- token, }) {
14
+ }) {
15
15
  const [open, setOpen] = React.useState(false);
16
16
  const [searchQuery, setSearchQuery] = React.useState('');
17
17
  const debouncedSearch = useDebounce(searchQuery, 300);
@@ -19,7 +19,6 @@ token, }) {
19
19
  const { industries = [], industriesQuery, isLoading, } = useIndustries({
20
20
  queryObject: debouncedSearch ? { search: debouncedSearch } : {},
21
21
  limit: 50,
22
- token,
23
22
  });
24
23
  const handleListScroll = React.useCallback((e) => {
25
24
  if (!industriesQuery.hasNextPage ||
@@ -1,5 +1,5 @@
1
1
  import type { InfiniteData, UseInfiniteQueryResult } from '@tanstack/react-query';
2
- import type { Skill } from '../../hooks/useSkills';
2
+ import type { Skill } from '@/hooks/api/useSkills';
3
3
  type Props = {
4
4
  value: string[];
5
5
  onChange: (value: string[]) => void;
@@ -10,9 +10,7 @@ type Props = {
10
10
  }>, Error>;
11
11
  disabled?: boolean;
12
12
  staticOnly?: boolean;
13
- /** Optional auth token (e.g. from useSessionStore) */
14
- token?: string | null;
15
13
  };
16
- export declare function MultiSelectOptions({ value, onChange, options, query: externalQuery, disabled, staticOnly, token, }: Props): import("react/jsx-runtime").JSX.Element;
14
+ export declare function MultiSelectOptions({ value, onChange, options, query: externalQuery, disabled, staticOnly, }: Props): import("react/jsx-runtime").JSX.Element;
17
15
  export {};
18
16
  //# sourceMappingURL=MultiSelectOptions.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"MultiSelectOptions.d.ts","sourceRoot":"","sources":["../../../src/components/ui/MultiSelectOptions.tsx"],"names":[],"mappings":"AAiBA,OAAO,KAAK,EACV,YAAY,EACZ,sBAAsB,EACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAGnD,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACpC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,sBAAsB,CAC5B,YAAY,CAAC;QAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,EACxD,KAAK,CACN,CAAC;IACF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACvB,CAAC;AA8BF,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,QAAQ,EACR,OAAO,EACP,KAAK,EAAE,aAAa,EACpB,QAAQ,EACR,UAAkB,EAClB,KAAK,GACN,EAAE,KAAK,2CA+KP"}
1
+ {"version":3,"file":"MultiSelectOptions.d.ts","sourceRoot":"","sources":["../../../src/components/ui/MultiSelectOptions.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EACV,YAAY,EACZ,sBAAsB,EACvB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAGnD,KAAK,KAAK,GAAG;IACX,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC;IACpC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,KAAK,CAAC,EAAE,sBAAsB,CAC5B,YAAY,CAAC;QAAE,IAAI,EAAE,KAAK,EAAE,CAAC;QAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,EACxD,KAAK,CACN,CAAC;IACF,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,UAAU,CAAC,EAAE,OAAO,CAAC;CACtB,CAAC;AAsCF,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,QAAQ,EACR,OAAO,EACP,KAAK,EAAE,aAAa,EACpB,QAAQ,EACR,UAAkB,GACnB,EAAE,KAAK,2CAuKP"}
@@ -1,19 +1,22 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
- import { Popover, PopoverTrigger, PopoverContent, } from './popover';
4
- import { Command, CommandInput, CommandItem, CommandList, CommandGroup, CommandEmpty, } from './command';
3
+ import { Popover, PopoverTrigger, PopoverContent, } from '@/components/ui/popover';
4
+ import { Command, CommandInput, CommandItem, CommandList, CommandGroup, CommandEmpty, } from '@/components/ui/command';
5
+ import { Button } from '@/components/ui/button';
6
+ import { Badge } from '@/components/ui/badge';
5
7
  import { X } from 'lucide-react';
6
- import { useEffect, useState, useMemo, useRef } from 'react';
7
- import { useSkills } from '../../hooks/useSkills';
8
+ import { useEffect, useState, useMemo } from 'react';
9
+ import { useInView } from 'react-intersection-observer';
10
+ import { useSkills } from '@/hooks/api/useSkills';
8
11
  // Sub-component for badges
9
12
  function SelectedBadges({ skills, removeSkill, }) {
10
- return (_jsx("div", { className: "flex flex-wrap gap-1 w-full", children: skills.map((skill) => (_jsxs("span", { className: "flex items-center gap-1 px-1.5 py-0.5 rounded-lg bg-primary text-white text-[11px] leading-tight sm:text-xs max-w-full break-words", children: [_jsx("span", { className: "inline-block max-w-[72vw] sm:max-w-full overflow-hidden text-ellipsis", children: skill }), _jsx(X, { className: "w-3 h-3 cursor-pointer shrink-0", onClick: (e) => removeSkill(skill, e) })] }, skill))) }));
13
+ return (_jsx("div", { className: "flex flex-wrap gap-1 w-full", children: skills.map((skill) => (_jsxs(Badge, { variant: "secondary", className: "\n flex items-center gap-1\n px-1.5 py-0.5\n rounded-lg\n bg-primary text-white\n text-[11px] leading-tight sm:text-xs\n max-w-full break-words\n ", children: [_jsx("span", { className: "inline-block max-w-[72vw] sm:max-w-full overflow-hidden text-ellipsis", children: skill }), _jsx(X, { className: "w-3 h-3 cursor-pointer shrink-0", onClick: (e) => removeSkill(skill, e) })] }, skill))) }));
11
14
  }
12
- export function MultiSelectOptions({ value, onChange, options, query: externalQuery, disabled, staticOnly = false, token, }) {
15
+ export function MultiSelectOptions({ value, onChange, options, query: externalQuery, disabled, staticOnly = false, }) {
13
16
  const [open, setOpen] = useState(false);
14
17
  const [search, setSearch] = useState('');
15
18
  const [debouncedSearch, setDebouncedSearch] = useState('');
16
- const loadMoreRef = useRef(null);
19
+ const { ref, inView } = useInView();
17
20
  // Debounce search input to reduce API calls
18
21
  useEffect(() => {
19
22
  const timer = setTimeout(() => {
@@ -30,7 +33,6 @@ export function MultiSelectOptions({ value, onChange, options, query: externalQu
30
33
  limit: debouncedSearch ? 50 : 20, // 50 when searching, 20 for initial load
31
34
  batchSize: 1, // Single page per load for faster response
32
35
  queryObject: debouncedSearch ? { search: debouncedSearch } : {},
33
- token,
34
36
  });
35
37
  // Use internal query when searching, otherwise use external query if provided
36
38
  // If staticOnly, don't use any query
@@ -55,18 +57,13 @@ export function MultiSelectOptions({ value, onChange, options, query: externalQu
55
57
  setDebouncedSearch('');
56
58
  }
57
59
  }, [open]);
58
- // Infinite scroll using IntersectionObserver
60
+ // Infinite scroll
59
61
  useEffect(() => {
60
- if (!loadMoreRef.current || !query?.hasNextPage || query?.isFetchingNextPage)
61
- return;
62
- const observer = new IntersectionObserver((entries) => {
63
- if (entries[0]?.isIntersecting) {
64
- query.fetchNextPage?.();
65
- }
66
- }, { threshold: 0.1 });
67
- observer.observe(loadMoreRef.current);
68
- return () => observer.disconnect();
69
- }, [query?.hasNextPage, query?.isFetchingNextPage, query]);
62
+ if (inView && query?.hasNextPage && !query?.isFetchingNextPage) {
63
+ const timeout = setTimeout(() => query.fetchNextPage?.(), 200);
64
+ return () => clearTimeout(timeout);
65
+ }
66
+ }, [inView, query?.hasNextPage, query?.isFetchingNextPage, query]);
70
67
  // Handlers
71
68
  const toggleSkill = (skill) => onChange(value.includes(skill)
72
69
  ? value.filter((s) => s !== skill)
@@ -81,5 +78,5 @@ export function MultiSelectOptions({ value, onChange, options, query: externalQu
81
78
  const canAddCustom = trimmedSearch &&
82
79
  !combinedOptions.includes(trimmedSearch) &&
83
80
  !value.includes(trimmedSearch);
84
- return (_jsx("div", { className: "w-full", children: _jsxs(Popover, { open: open, onOpenChange: setOpen, children: [_jsx(PopoverTrigger, { disabled: disabled, asChild: true, children: _jsx("button", { type: "button", className: "w-full min-h-10 justify-start border border-slate-200 rounded-md bg-background px-2 py-1 h-auto text-left hover:bg-accent hover:text-accent-foreground disabled:cursor-not-allowed disabled:opacity-50", children: value.length > 0 ? (_jsx(SelectedBadges, { skills: value, removeSkill: removeSkill })) : (_jsx("span", { className: "text-muted-foreground", children: "Select Options" })) }) }), _jsx(PopoverContent, { className: "max-w-sm max-h-[300px] overflow-y-auto p-0", children: _jsxs(Command, { shouldFilter: false, children: [_jsx(CommandInput, { value: search, onValueChange: setSearch, placeholder: "Search or add..." }), _jsxs(CommandList, { className: "max-h-[250px] overflow-y-auto", children: [!staticOnly && query?.isFetching && combinedOptions.length === 0 && (_jsx("div", { className: "text-center text-muted-foreground text-xs py-4", children: "Searching..." })), _jsxs(CommandGroup, { children: [combinedOptions.map((skill) => (_jsx(CommandItem, { onSelect: () => toggleSkill(skill), className: "cursor-pointer", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("input", { type: "checkbox", checked: value.includes(skill), readOnly: true, className: "accent-primary" }), _jsx("span", { children: skill })] }) }, skill))), canAddCustom && (_jsxs(CommandItem, { onSelect: () => toggleSkill(trimmedSearch), className: "cursor-pointer text-primary space-x-2", children: [_jsx("span", { className: "px-2 py-0.5 bg-green-600 hover:bg-green-500 rounded-sm text-xs text-white", children: "Add" }), _jsx("span", { children: trimmedSearch })] }))] }), combinedOptions.length === 0 && !canAddCustom && (!staticOnly && !query?.isFetching) && (_jsx(CommandEmpty, { children: "No matches found." })), !staticOnly && query?.hasNextPage && !query?.isFetching && (_jsx("div", { ref: loadMoreRef, className: "text-center text-muted-foreground text-xs py-2", children: "Loading more..." }))] })] }) })] }) }));
81
+ return (_jsx("div", { className: "w-full", children: _jsxs(Popover, { open: open, onOpenChange: setOpen, children: [_jsx(PopoverTrigger, { disabled: disabled, asChild: true, children: _jsx(Button, { variant: "outline", className: "w-full min-h-10 justify-start border-slate-200 px-2 py-1 h-auto", children: value.length > 0 ? (_jsx(SelectedBadges, { skills: value, removeSkill: removeSkill })) : (_jsx("span", { className: "text-muted-foreground", children: "Select Options" })) }) }), _jsx(PopoverContent, { className: "max-w-sm max-h-[300px] overflow-y-auto p-0", children: _jsxs(Command, { shouldFilter: false, children: [_jsx(CommandInput, { value: search, onValueChange: setSearch, placeholder: "Search or add..." }), _jsxs(CommandList, { className: "max-h-[250px] overflow-y-auto", children: [!staticOnly && query?.isFetching && combinedOptions.length === 0 && (_jsx("div", { className: "text-center text-muted-foreground text-xs py-4", children: "Searching..." })), _jsxs(CommandGroup, { children: [combinedOptions.map((skill) => (_jsx(CommandItem, { onSelect: () => toggleSkill(skill), className: "cursor-pointer", children: _jsxs("div", { className: "flex items-center gap-2", children: [_jsx("input", { type: "checkbox", checked: value.includes(skill), readOnly: true, className: "accent-primary" }), _jsx("span", { children: skill })] }) }, skill))), canAddCustom && (_jsxs(CommandItem, { onSelect: () => toggleSkill(trimmedSearch), className: "cursor-pointer text-primary space-x-2", children: [_jsx("span", { className: "px-2 py-0.5 bg-green-600 hover:bg-green-500 rounded-sm text-xs text-white", children: "Add" }), _jsx("span", { children: trimmedSearch })] }))] }), combinedOptions.length === 0 && !canAddCustom && (!staticOnly && !query?.isFetching) && (_jsx(CommandEmpty, { children: "No matches found." })), !staticOnly && query?.hasNextPage && !query?.isFetching && (_jsx("div", { ref: ref, className: "text-center text-muted-foreground text-xs py-2", children: "Loading more..." }))] })] }) })] }) }));
85
82
  }
package/dist/index.d.ts CHANGED
@@ -7,9 +7,6 @@ export { WORKSTATUS, WORK_STATUS_VALUES, } from './types/easy-apply';
7
7
  export type { WorkStatusValue, QuestionsAPIRes, ScreeningAnswersApiResNew, } from './types/easy-apply';
8
8
  export { apiRequest } from './utils/api-request';
9
9
  export type { ApiResponse } from './utils/api-request';
10
- export { generateSearchQuery } from './utils/generateSearchQuery';
11
- export { monthsDropdown, yearsDropdown } from './utils/commonDropdownOptions';
12
- export { cn } from './utils/cn';
13
10
  export { useGetAllVacancy } from './hooks/useGetAllVacancy';
14
11
  export { default as useGetAllVacancyDefault } from './hooks/useGetAllVacancy';
15
12
  export { useSavedVacancyMutations } from './hooks/useSavedVacancyMutations';
@@ -22,39 +19,9 @@ export { useEasyApplyMutations } from './hooks/useEasyApplyMutations';
22
19
  export type { UseEasyApplyMutationsParams } from './hooks/useEasyApplyMutations';
23
20
  export { useEasyApplyFormHook, easyApplyUserSchema, screeningAnswerSchema, screeningAnswersSchema, } from './hooks/useEasyApplyFormHook';
24
21
  export type { EasyApplyFormValues, EasyApplyScreeningAnswer, EasyApplyScreeningAnswers, UseEasyApplyFormHookParams, } from './hooks/useEasyApplyFormHook';
25
- export { useDebounce } from './hooks/useDebounce';
26
- export { useSkills } from './hooks/useSkills';
27
- export type { Skill, UseSkillsParams } from './hooks/useSkills';
28
- export { useIndustries } from './hooks/useIndustries';
29
- export type { Industry, IndustryPayload, UseIndustriesParams } from './hooks/useIndustries';
30
- export { useDesignations } from './hooks/useDesignations';
31
- export type { Designation, DesignationPayload, UseDesignationsParams } from './hooks/useDesignations';
32
22
  export { default as JobsClient } from './components/JobsClient';
33
23
  export type { JobsClientProps } from './components/JobsClient';
34
24
  export { default as JobDescriptionClient } from './components/JobDescriptionClient';
35
25
  export type { JobDescriptionClientProps } from './components/JobDescriptionClient';
36
- export type { TemplateData, TemplatePersonalInfo, TemplateSections, TemplateExperience, TemplateEducation, TemplateProject, TemplateSkill, TemplateSkillCategory, TemplateCertification, TemplateLanguage, TemplateReference, TemplateTraining, TemplateLink, TemplateProps, } from './types/template.types';
37
- export type { CvBlock, CvBlockType, CvBlockStyle, CvLayout, } from './types/cv-blocks.types';
38
- export type { CvDraft, CreateCvDraftPayload, UpdateCvDraftPayload, CvDraftListResponse, } from './types/cv-draft.types';
39
- export { convertTemplateToBlocks, getDefaultColumns, getDefaultStyles, } from './utils/cv-block-converter';
40
- export { preprocessTemplateCssClient, clearCssCacheClient, } from './utils/cv/pdf/styles/preprocessCssClient';
41
- export { useCvPreview } from './stores/cvPreview.store';
42
- export { useCvLayout } from './stores/cvLayout.store';
43
- export { useCvDraftsStore } from './stores/cvDrafts.store';
44
- export { default as TemplateRenderer } from './components/cv/TemplateRenderer';
45
- export type { CvTemplateRegistry, TemplateRendererProps } from './components/cv/TemplateRenderer';
46
- export { default as TemplatePicker } from './components/cv/TemplatePicker';
47
- export type { TemplatePickerProps } from './components/cv/TemplatePicker';
48
- export { generateSampleTemplateData } from './components/cv/TemplatePicker';
49
26
  export { RatingStars } from './components/ui/RatingStars';
50
- export { BulletListTextarea } from './components/ui/BulletListTextarea';
51
- export type { BulletListTextareaProps } from './components/ui/BulletListTextarea';
52
- export { default as IndustrySelect } from './components/ui/IndustrySelect';
53
- export type { IndustrySelectProps } from './components/ui/IndustrySelect';
54
- export { default as DesignationSelect } from './components/ui/DesignationSelect';
55
- export type { DesignationSelectProps } from './components/ui/DesignationSelect';
56
- export { MultiSelectOptions } from './components/ui/MultiSelectOptions';
57
- export { NoData } from './components/common/NoData';
58
- export { Popover, PopoverTrigger, PopoverContent } from './components/ui/popover';
59
- export { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, } from './components/ui/command';
60
27
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAGxD,YAAY,EACV,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,eAAe,GAChB,MAAM,SAAS,CAAC;AACjB,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,gBAAgB,EAChB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,UAAU,EACV,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,eAAe,EACf,eAAe,EACf,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,+BAA+B,CAAC;AAC9E,OAAO,EAAE,EAAE,EAAE,MAAM,YAAY,CAAC;AAGhC,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,YAAY,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AACjF,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,8BAA8B,CAAC;AACtC,YAAY,EACV,mBAAmB,EACnB,wBAAwB,EACxB,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,8BAA8B,CAAC;AACtC,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,SAAS,EAAE,MAAM,mBAAmB,CAAC;AAC9C,YAAY,EAAE,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAC5F,OAAO,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC1D,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,yBAAyB,CAAC;AAGtG,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACpF,YAAY,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAGnF,YAAY,EACV,YAAY,EACZ,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,qBAAqB,EACrB,qBAAqB,EACrB,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,aAAa,GACd,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,OAAO,EACP,WAAW,EACX,YAAY,EACZ,QAAQ,GACT,MAAM,yBAAyB,CAAC;AACjC,YAAY,EACV,OAAO,EACP,oBAAoB,EACpB,oBAAoB,EACpB,mBAAmB,GACpB,MAAM,wBAAwB,CAAC;AAGhC,OAAO,EACL,uBAAuB,EACvB,iBAAiB,EACjB,gBAAgB,GACjB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,2BAA2B,EAC3B,mBAAmB,GACpB,MAAM,2CAA2C,CAAC;AAGnD,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAG3D,OAAO,EAAE,OAAO,IAAI,gBAAgB,EAAE,MAAM,kCAAkC,CAAC;AAC/E,YAAY,EAAE,kBAAkB,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAClG,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAC3E,YAAY,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,EAAE,0BAA0B,EAAE,MAAM,gCAAgC,CAAC;AAG5E,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC1D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,YAAY,EAAE,uBAAuB,EAAE,MAAM,oCAAoC,CAAC;AAClF,OAAO,EAAE,OAAO,IAAI,cAAc,EAAE,MAAM,gCAAgC,CAAC;AAC3E,YAAY,EAAE,mBAAmB,EAAE,MAAM,gCAAgC,CAAC;AAC1E,OAAO,EAAE,OAAO,IAAI,iBAAiB,EAAE,MAAM,mCAAmC,CAAC;AACjF,YAAY,EAAE,sBAAsB,EAAE,MAAM,mCAAmC,CAAC;AAChF,OAAO,EAAE,kBAAkB,EAAE,MAAM,oCAAoC,CAAC;AACxE,OAAO,EAAE,MAAM,EAAE,MAAM,4BAA4B,CAAC;AAGpD,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,cAAc,EAAE,MAAM,yBAAyB,CAAC;AAClF,OAAO,EACL,OAAO,EACP,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,WAAW,GACZ,MAAM,yBAAyB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,cAAc,CAAC;AAGxD,YAAY,EACV,gBAAgB,EAChB,aAAa,EACb,UAAU,EACV,eAAe,GAChB,MAAM,SAAS,CAAC;AACjB,YAAY,EACV,aAAa,EACb,oBAAoB,EACpB,gBAAgB,GACjB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,gBAAgB,EAChB,uBAAuB,EACvB,mBAAmB,GACpB,MAAM,uBAAuB,CAAC;AAC/B,YAAY,EACV,QAAQ,EACR,YAAY,EACZ,wBAAwB,GACzB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,UAAU,EACV,kBAAkB,GACnB,MAAM,oBAAoB,CAAC;AAC5B,YAAY,EACV,eAAe,EACf,eAAe,EACf,yBAAyB,GAC1B,MAAM,oBAAoB,CAAC;AAG5B,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AACjD,YAAY,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,OAAO,IAAI,uBAAuB,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EAAE,wBAAwB,EAAE,MAAM,kCAAkC,CAAC;AAC5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,+BAA+B,CAAC;AACtE,YAAY,EAAE,2BAA2B,EAAE,MAAM,+BAA+B,CAAC;AACjF,OAAO,EACL,oBAAoB,EACpB,mBAAmB,EACnB,qBAAqB,EACrB,sBAAsB,GACvB,MAAM,8BAA8B,CAAC;AACtC,YAAY,EACV,mBAAmB,EACnB,wBAAwB,EACxB,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,8BAA8B,CAAC;AAGtC,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EAAE,eAAe,EAAE,MAAM,yBAAyB,CAAC;AAC/D,OAAO,EAAE,OAAO,IAAI,oBAAoB,EAAE,MAAM,mCAAmC,CAAC;AACpF,YAAY,EAAE,yBAAyB,EAAE,MAAM,mCAAmC,CAAC;AAGnF,OAAO,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC"}
package/dist/index.js CHANGED
@@ -3,9 +3,6 @@ export { initApi, getBaseURL, API } from './api-client';
3
3
  export { WORKSTATUS, WORK_STATUS_VALUES, } from './types/easy-apply';
4
4
  // Utils
5
5
  export { apiRequest } from './utils/api-request';
6
- export { generateSearchQuery } from './utils/generateSearchQuery';
7
- export { monthsDropdown, yearsDropdown } from './utils/commonDropdownOptions';
8
- export { cn } from './utils/cn';
9
6
  // Hooks
10
7
  export { useGetAllVacancy } from './hooks/useGetAllVacancy';
11
8
  export { default as useGetAllVacancyDefault } from './hooks/useGetAllVacancy';
@@ -17,31 +14,8 @@ export { useVacancyQuestions } from './hooks/useVacancyQuestions';
17
14
  export { useShareJob } from './hooks/useShareJob';
18
15
  export { useEasyApplyMutations } from './hooks/useEasyApplyMutations';
19
16
  export { useEasyApplyFormHook, easyApplyUserSchema, screeningAnswerSchema, screeningAnswersSchema, } from './hooks/useEasyApplyFormHook';
20
- export { useDebounce } from './hooks/useDebounce';
21
- export { useSkills } from './hooks/useSkills';
22
- export { useIndustries } from './hooks/useIndustries';
23
- export { useDesignations } from './hooks/useDesignations';
24
17
  // Components
25
18
  export { default as JobsClient } from './components/JobsClient';
26
19
  export { default as JobDescriptionClient } from './components/JobDescriptionClient';
27
- // CV Builder: utils
28
- export { convertTemplateToBlocks, getDefaultColumns, getDefaultStyles, } from './utils/cv-block-converter';
29
- export { preprocessTemplateCssClient, clearCssCacheClient, } from './utils/cv/pdf/styles/preprocessCssClient';
30
- // CV Builder: stores
31
- export { useCvPreview } from './stores/cvPreview.store';
32
- export { useCvLayout } from './stores/cvLayout.store';
33
- export { useCvDraftsStore } from './stores/cvDrafts.store';
34
- // CV Builder: components (registry-based; no templates in package)
35
- export { default as TemplateRenderer } from './components/cv/TemplateRenderer';
36
- export { default as TemplatePicker } from './components/cv/TemplatePicker';
37
- export { generateSampleTemplateData } from './components/cv/TemplatePicker';
38
- // UI Components
20
+ // UI Components (only those with no app-specific deps; IndustrySelect, DesignationSelect, etc. live in each repo)
39
21
  export { RatingStars } from './components/ui/RatingStars';
40
- export { BulletListTextarea } from './components/ui/BulletListTextarea';
41
- export { default as IndustrySelect } from './components/ui/IndustrySelect';
42
- export { default as DesignationSelect } from './components/ui/DesignationSelect';
43
- export { MultiSelectOptions } from './components/ui/MultiSelectOptions';
44
- export { NoData } from './components/common/NoData';
45
- // UI Primitives (Popover, Command)
46
- export { Popover, PopoverTrigger, PopoverContent } from './components/ui/popover';
47
- export { Command, CommandInput, CommandList, CommandEmpty, CommandGroup, CommandItem, } from './components/ui/command';