@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.
- package/dist/components/common/NoData.d.ts +3 -4
- package/dist/components/common/NoData.d.ts.map +1 -1
- package/dist/components/common/NoData.js +4 -2
- package/dist/components/cv/ResponsivePreview.d.ts +7 -0
- package/dist/components/cv/ResponsivePreview.d.ts.map +1 -0
- package/dist/components/cv/ResponsivePreview.js +47 -0
- package/dist/components/cv-builder/forms/AboutForm.d.ts +2 -0
- package/dist/components/cv-builder/forms/AboutForm.d.ts.map +1 -0
- package/dist/components/cv-builder/forms/AboutForm.js +86 -0
- package/dist/components/cv-builder/forms/AdditionalDetailsForm.d.ts +2 -0
- package/dist/components/cv-builder/forms/AdditionalDetailsForm.d.ts.map +1 -0
- package/dist/components/cv-builder/forms/AdditionalDetailsForm.js +227 -0
- package/dist/components/cv-builder/forms/EducationForm.d.ts +2 -0
- package/dist/components/cv-builder/forms/EducationForm.d.ts.map +1 -0
- package/dist/components/cv-builder/forms/EducationForm.js +168 -0
- package/dist/components/cv-builder/forms/ExperienceForm.d.ts +2 -0
- package/dist/components/cv-builder/forms/ExperienceForm.d.ts.map +1 -0
- package/dist/components/cv-builder/forms/ExperienceForm.js +266 -0
- package/dist/components/cv-builder/forms/PortfolioForm.d.ts +2 -0
- package/dist/components/cv-builder/forms/PortfolioForm.d.ts.map +1 -0
- package/dist/components/cv-builder/forms/PortfolioForm.js +159 -0
- package/dist/components/cv-builder/forms/ProjectsForm.d.ts +2 -0
- package/dist/components/cv-builder/forms/ProjectsForm.d.ts.map +1 -0
- package/dist/components/cv-builder/forms/ProjectsForm.js +134 -0
- package/dist/components/cv-builder/forms/SkillsForm.d.ts +2 -0
- package/dist/components/cv-builder/forms/SkillsForm.d.ts.map +1 -0
- package/dist/components/cv-builder/forms/SkillsForm.js +250 -0
- package/dist/components/ui/BulletListTextarea.d.ts.map +1 -1
- package/dist/components/ui/BulletListTextarea.js +3 -2
- package/dist/components/ui/DesignationSelect.d.ts +1 -4
- package/dist/components/ui/DesignationSelect.d.ts.map +1 -1
- package/dist/components/ui/DesignationSelect.js +6 -7
- package/dist/components/ui/IndustrySelect.d.ts +1 -4
- package/dist/components/ui/IndustrySelect.d.ts.map +1 -1
- package/dist/components/ui/IndustrySelect.js +6 -7
- package/dist/components/ui/MultiSelectOptions.d.ts +2 -4
- package/dist/components/ui/MultiSelectOptions.d.ts.map +1 -1
- package/dist/components/ui/MultiSelectOptions.js +17 -20
- package/dist/index.d.ts +0 -33
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -27
- 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;
|
|
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 {
|
|
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(
|
|
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,
|
|
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;
|
|
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 '
|
|
6
|
-
import { cn } from '
|
|
7
|
-
import { useDebounce } from '
|
|
8
|
-
import { Popover, PopoverContent, PopoverTrigger } from '
|
|
9
|
-
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from '
|
|
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
|
-
|
|
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,
|
|
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;
|
|
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 '
|
|
6
|
-
import { cn } from '
|
|
7
|
-
import { useDebounce } from '
|
|
8
|
-
import { Popover, PopoverContent, PopoverTrigger } from '
|
|
9
|
-
import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from '
|
|
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
|
-
|
|
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 '
|
|
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,
|
|
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":"
|
|
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 '
|
|
4
|
-
import { Command, CommandInput, CommandItem, CommandList, CommandGroup, CommandEmpty, } from '
|
|
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
|
|
7
|
-
import {
|
|
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("
|
|
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,
|
|
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
|
|
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
|
|
60
|
+
// Infinite scroll
|
|
59
61
|
useEffect(() => {
|
|
60
|
-
if (
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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(
|
|
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
|
package/dist/index.d.ts.map
CHANGED
|
@@ -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;
|
|
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
|
-
//
|
|
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';
|