@recruitnepal/shared-packages 1.0.0 → 1.1.0

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 (40) hide show
  1. package/README.md +0 -0
  2. package/dist/api-client.d.ts +15 -0
  3. package/dist/api-client.d.ts.map +1 -1
  4. package/dist/api-client.js +15 -0
  5. package/dist/components/JobDescriptionClient.d.ts +59 -0
  6. package/dist/components/JobDescriptionClient.d.ts.map +1 -0
  7. package/dist/components/JobDescriptionClient.js +260 -0
  8. package/dist/hooks/useApplicantList.d.ts +3 -0
  9. package/dist/hooks/useApplicantList.d.ts.map +1 -0
  10. package/dist/hooks/useApplicantList.js +35 -0
  11. package/dist/hooks/useApplicantMutations.d.ts +18 -0
  12. package/dist/hooks/useApplicantMutations.d.ts.map +1 -0
  13. package/dist/hooks/useApplicantMutations.js +100 -0
  14. package/dist/hooks/useSavedVacancyList.d.ts +3 -0
  15. package/dist/hooks/useSavedVacancyList.d.ts.map +1 -0
  16. package/dist/hooks/useSavedVacancyList.js +35 -0
  17. package/dist/hooks/useSavedVacancyMutations.d.ts +9 -0
  18. package/dist/hooks/useSavedVacancyMutations.d.ts.map +1 -0
  19. package/dist/hooks/useSavedVacancyMutations.js +49 -0
  20. package/dist/hooks/useShareJob.d.ts +14 -0
  21. package/dist/hooks/useShareJob.d.ts.map +1 -0
  22. package/dist/hooks/useShareJob.js +44 -0
  23. package/dist/hooks/useVacancyQuestions.d.ts +5 -0
  24. package/dist/hooks/useVacancyQuestions.d.ts.map +1 -0
  25. package/dist/hooks/useVacancyQuestions.js +26 -0
  26. package/dist/index.d.ts +11 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.js +7 -0
  29. package/dist/types/applicant.d.ts +37 -0
  30. package/dist/types/applicant.d.ts.map +1 -0
  31. package/dist/types/applicant.js +1 -0
  32. package/dist/types/questions.d.ts +28 -0
  33. package/dist/types/questions.d.ts.map +1 -0
  34. package/dist/types/questions.js +1 -0
  35. package/dist/types/saved-vacancy.d.ts +22 -0
  36. package/dist/types/saved-vacancy.d.ts.map +1 -0
  37. package/dist/types/saved-vacancy.js +1 -0
  38. package/dist/types.d.ts +2 -0
  39. package/dist/types.d.ts.map +1 -1
  40. package/package.json +39 -39
package/README.md CHANGED
Binary file
@@ -8,5 +8,20 @@ export declare const API: {
8
8
  byId: (id: string) => string;
9
9
  intern: () => string;
10
10
  };
11
+ savedVacancies: {
12
+ list: (page?: number) => string;
13
+ create: () => string;
14
+ delete: (id: string) => string;
15
+ };
16
+ applicants: {
17
+ list: (page?: number) => string;
18
+ create: () => string;
19
+ update: (id: string) => string;
20
+ delete: (id: string) => string;
21
+ batch: () => string;
22
+ };
23
+ questions: {
24
+ byVacancyId: (vacancyId: string) => string;
25
+ };
11
26
  };
12
27
  //# sourceMappingURL=api-client.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAEA,wBAAgB,OAAO,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,QAElD;AAED,wBAAgB,UAAU,WAKzB;AAED,eAAO,MAAM,GAAG;;;mBAGD,MAAM;;;CAGpB,CAAC"}
1
+ {"version":3,"file":"api-client.d.ts","sourceRoot":"","sources":["../src/api-client.ts"],"names":[],"mappings":"AAEA,wBAAgB,OAAO,CAAC,MAAM,EAAE;IAAE,OAAO,EAAE,MAAM,CAAA;CAAE,QAElD;AAED,wBAAgB,UAAU,WAKzB;AAED,eAAO,MAAM,GAAG;;;mBAGD,MAAM;;;;sBAIH,MAAM;;qBAEP,MAAM;;;sBAGL,MAAM;;qBAEP,MAAM;qBACN,MAAM;;;;iCAIM,MAAM;;CAElC,CAAC"}
@@ -14,4 +14,19 @@ export const API = {
14
14
  byId: (id) => `${getBaseURL()}/vacancies/${id}`,
15
15
  intern: () => `${getBaseURL()}/intern/vacancies`,
16
16
  },
17
+ savedVacancies: {
18
+ list: (page) => `${getBaseURL()}/saved/vacancies${page ? `?page=${page}` : ''}`,
19
+ create: () => `${getBaseURL()}/saved/vacancies`,
20
+ delete: (id) => `${getBaseURL()}/saved/vacancies/${id}`,
21
+ },
22
+ applicants: {
23
+ list: (page) => `${getBaseURL()}/applicants${page ? `?page=${page}` : ''}`,
24
+ create: () => `${getBaseURL()}/applicants/`,
25
+ update: (id) => `${getBaseURL()}/applicants/${id}`,
26
+ delete: (id) => `${getBaseURL()}/applicants/${id}`,
27
+ batch: () => `${getBaseURL()}/applicants/multiple`,
28
+ },
29
+ questions: {
30
+ byVacancyId: (vacancyId) => `${getBaseURL()}/application/questions/?vacancyId=${vacancyId}`,
31
+ },
17
32
  };
@@ -0,0 +1,59 @@
1
+ import type { SingleVacancyRes } from '../types';
2
+ export type JobDescriptionClientProps = {
3
+ job: SingleVacancyRes;
4
+ slug: string;
5
+ token?: string;
6
+ sessionStatus?: 'authenticated' | 'unauthenticated' | 'loading';
7
+ personalDetailId?: string;
8
+ imageBaseURL?: string;
9
+ /** Custom components - if not provided, will use basic HTML */
10
+ Button?: React.ComponentType<any>;
11
+ Badge?: React.ComponentType<any>;
12
+ Dialog?: React.ComponentType<any>;
13
+ DialogContent?: React.ComponentType<any>;
14
+ DialogHeader?: React.ComponentType<any>;
15
+ DialogTitle?: React.ComponentType<any>;
16
+ DialogDescription?: React.ComponentType<any>;
17
+ DialogFooter?: React.ComponentType<any>;
18
+ Sheet?: React.ComponentType<any>;
19
+ SheetContent?: React.ComponentType<any>;
20
+ SheetDescription?: React.ComponentType<any>;
21
+ Image?: React.ComponentType<any>;
22
+ Link?: React.ComponentType<any>;
23
+ LoadingButton?: React.ComponentType<any>;
24
+ /** Custom panels/components */
25
+ ScreeningQuestionsPanel?: React.ComponentType<any>;
26
+ CVSelectionPanel?: React.ComponentType<any>;
27
+ EasyApply?: React.ComponentType<any>;
28
+ /** Additional content */
29
+ randomTraining?: {
30
+ id: string;
31
+ title: string;
32
+ description: string;
33
+ imageUrl: string;
34
+ } | null;
35
+ randomDlyticaCourse?: {
36
+ id: string;
37
+ title: string;
38
+ description: string;
39
+ imageUrl: string;
40
+ };
41
+ /** Callbacks */
42
+ onApply?: () => void;
43
+ onSave?: () => void;
44
+ onShare?: (method: 'copy' | 'whatsapp' | 'viber' | 'messenger') => void;
45
+ onLoginRequired?: (action: 'apply' | 'save') => void;
46
+ /** Utility functions */
47
+ capitalize?: (str: string) => string;
48
+ sanitizeHTML?: (html: string) => string;
49
+ extractPlainText?: (html: string) => string;
50
+ /** Share icons */
51
+ shareIcons?: {
52
+ whatsapp: string;
53
+ viber: string;
54
+ messenger: string;
55
+ chain: string;
56
+ };
57
+ };
58
+ export default function JobDescriptionClient({ job, slug, token, sessionStatus, personalDetailId, imageBaseURL, Button, Badge, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, Sheet, SheetContent, SheetDescription, Image, Link, LoadingButton, ScreeningQuestionsPanel, CVSelectionPanel, EasyApply, randomTraining, randomDlyticaCourse, onApply, onSave, onShare, onLoginRequired, capitalize, sanitizeHTML, extractPlainText, shareIcons, }: JobDescriptionClientProps): import("react/jsx-runtime").JSX.Element;
59
+ //# sourceMappingURL=JobDescriptionClient.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"JobDescriptionClient.d.ts","sourceRoot":"","sources":["../../src/components/JobDescriptionClient.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,260 @@
1
+ 'use client';
2
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
3
+ import { useState, useEffect } from 'react';
4
+ import { useRouter, useSearchParams } from 'next/navigation';
5
+ import { useSavedVacancyMutations } from '../hooks/useSavedVacancyMutations';
6
+ import { useSavedVacancyList } from '../hooks/useSavedVacancyList';
7
+ import { useApplicantMutations } from '../hooks/useApplicantMutations';
8
+ import { useApplicantList } from '../hooks/useApplicantList';
9
+ import { useVacancyQuestions } from '../hooks/useVacancyQuestions';
10
+ import { useShareJob } from '../hooks/useShareJob';
11
+ // Helper functions
12
+ const formatJobTypes = (types) => Array.isArray(types) && types.length
13
+ ? types
14
+ .map((t) => t.replace(/_/g, ' ').replace(/\b\w/g, (c) => c.toUpperCase()))
15
+ .join(', ')
16
+ : 'Not Specified';
17
+ const getSalaryText = (job) => {
18
+ if (job.offered_salary && typeof job.offered_salary.min === 'number') {
19
+ const { min, max } = job.offered_salary;
20
+ return `NPR ${min.toLocaleString()} - ${max.toLocaleString()}${job.salary_type ? ` (${job.salary_type})` : ''}`;
21
+ }
22
+ return job.salary_type || 'Not Disclosed';
23
+ };
24
+ export default function JobDescriptionClient({ job, slug, token, sessionStatus = 'unauthenticated', personalDetailId, imageBaseURL = '', Button, Badge, Dialog, DialogContent, DialogHeader, DialogTitle, DialogDescription, DialogFooter, Sheet, SheetContent, SheetDescription, Image, Link, LoadingButton, ScreeningQuestionsPanel, CVSelectionPanel, EasyApply, randomTraining, randomDlyticaCourse, onApply, onSave, onShare, onLoginRequired, capitalize = (str) => str, sanitizeHTML = (html) => html, extractPlainText = (html) => html.replace(/<[^>]*>/g, ''), shareIcons, }) {
25
+ const router = useRouter();
26
+ const searchParams = useSearchParams();
27
+ const [openJobOverview, setOpenJobOverview] = useState(false);
28
+ const [openQuestions, setOpenQuestions] = useState(false);
29
+ const [isEasyApplyOpen, setIsEasyApplyOpen] = useState(false);
30
+ const [authDialogOpen, setAuthDialogOpen] = useState(false);
31
+ const [pendingAction, setPendingAction] = useState(null);
32
+ const [showCVSelection, setShowCVSelection] = useState(false);
33
+ const [selectedCV, setSelectedCV] = useState(null);
34
+ const { data: savedVacancy } = useSavedVacancyList(token);
35
+ const { createSavedVacancy, deleteSavedVacancy } = useSavedVacancyMutations(token);
36
+ const { applyToVacancy } = useApplicantMutations(token);
37
+ const { data: applicantList } = useApplicantList(token, sessionStatus === 'authenticated');
38
+ const { data: screeningQuestions } = useVacancyQuestions(job.id, token);
39
+ const { handleCopy, handleWhatsAppShare, handleViberShare, handleMessengerShare, } = useShareJob(`/jobs/${slug}`);
40
+ useEffect(() => {
41
+ const qp = searchParams?.get('open');
42
+ const hash = typeof window !== 'undefined' ? window.location.hash : '';
43
+ const shouldOpenEasy = qp === 'apply' || hash.toLowerCase() === '#apply';
44
+ if (shouldOpenEasy) {
45
+ if (sessionStatus !== 'authenticated') {
46
+ setIsEasyApplyOpen(true);
47
+ }
48
+ else {
49
+ setIsEasyApplyOpen(false);
50
+ setOpenQuestions(true);
51
+ }
52
+ }
53
+ }, [searchParams, sessionStatus]);
54
+ const canApplyToVacancy = () => {
55
+ if (!job)
56
+ return { canApply: false, reason: 'Invalid vacancy' };
57
+ if (job.deadline_date) {
58
+ const deadline = new Date(job.deadline_date);
59
+ const today = new Date();
60
+ today.setHours(0, 0, 0, 0);
61
+ deadline.setHours(0, 0, 0, 0);
62
+ if (deadline < today) {
63
+ return {
64
+ canApply: false,
65
+ reason: 'Application deadline has passed. You cannot apply to this vacancy anymore.',
66
+ };
67
+ }
68
+ }
69
+ return { canApply: true };
70
+ };
71
+ const isSaved = !!job &&
72
+ savedVacancy?.some((v) => String(v.vacancy_id) === String(job.id));
73
+ const isApplied = !!job &&
74
+ applicantList?.some((a) => a.vacancy_id === job.id && a.personal_detail_id === personalDetailId);
75
+ const applyValidation = canApplyToVacancy();
76
+ const canApply = applyValidation.canApply;
77
+ const handleBookmarkClick = () => {
78
+ if (!job)
79
+ return;
80
+ if (sessionStatus !== 'authenticated') {
81
+ setPendingAction('save');
82
+ setAuthDialogOpen(true);
83
+ onLoginRequired?.('save');
84
+ return;
85
+ }
86
+ const matched = savedVacancy?.find((v) => String(v.vacancy_id) === String(job.id));
87
+ if (matched) {
88
+ deleteSavedVacancy.mutate({ vacancy_id: matched.id });
89
+ }
90
+ else {
91
+ createSavedVacancy.mutate({ vacancy_id: job.id });
92
+ }
93
+ onSave?.();
94
+ };
95
+ const onApplyJobClick = () => {
96
+ if (!job)
97
+ return;
98
+ const validation = canApplyToVacancy();
99
+ if (!validation.canApply) {
100
+ return;
101
+ }
102
+ if (sessionStatus !== 'authenticated') {
103
+ setPendingAction('apply');
104
+ setAuthDialogOpen(true);
105
+ onLoginRequired?.('apply');
106
+ return;
107
+ }
108
+ if (!personalDetailId) {
109
+ return;
110
+ }
111
+ const hasQuestions = screeningQuestions?.data &&
112
+ Array.isArray(screeningQuestions.data) &&
113
+ screeningQuestions.data.length > 0;
114
+ if (hasQuestions) {
115
+ setOpenQuestions(true);
116
+ return;
117
+ }
118
+ setShowCVSelection(true);
119
+ };
120
+ const handleApplyWithCV = () => {
121
+ if (!job)
122
+ return;
123
+ const validation = canApplyToVacancy();
124
+ if (!validation.canApply) {
125
+ setShowCVSelection(false);
126
+ setSelectedCV(null);
127
+ return;
128
+ }
129
+ if (!personalDetailId) {
130
+ return;
131
+ }
132
+ const payload = {
133
+ personal_detail_id: personalDetailId,
134
+ vacancy_id: job.id,
135
+ };
136
+ if (selectedCV) {
137
+ payload.cv_id = selectedCV.id;
138
+ payload.cv_type = selectedCV.type;
139
+ }
140
+ applyToVacancy.mutate(payload);
141
+ setShowCVSelection(false);
142
+ setSelectedCV(null);
143
+ onApply?.();
144
+ };
145
+ const handleIsEasyApplyOpen = () => setIsEasyApplyOpen((s) => !s);
146
+ const handleAuthRequiredAction = (t) => {
147
+ setPendingAction(t);
148
+ setAuthDialogOpen(true);
149
+ onLoginRequired?.(t);
150
+ };
151
+ const confirmLoginRedirect = () => {
152
+ if (pendingAction) {
153
+ setAuthDialogOpen(false);
154
+ router.push('/login');
155
+ }
156
+ };
157
+ const companyLogoSrc = job.company_logo
158
+ ? job.company_logo.startsWith('http')
159
+ ? job.company_logo
160
+ : `${imageBaseURL}/${job.company_logo}`
161
+ : null;
162
+ // Bridge object for ScreeningQuestionsPanel
163
+ const selectedVacancyForQuestions = {
164
+ companies: {
165
+ id: job.company_id,
166
+ organization_name: job.organization_name,
167
+ company_logo: job.company_logo,
168
+ },
169
+ vacancies: {
170
+ id: job.id,
171
+ slug: job.slug,
172
+ job_title: job.title,
173
+ location: job.location,
174
+ employment_type: job.employment_type,
175
+ expected_salary: job.offered_salary
176
+ ? [
177
+ { value: job.offered_salary.min, inclusive: true },
178
+ { value: job.offered_salary.max, inclusive: true },
179
+ ]
180
+ : [],
181
+ skills_required: job.skills_required,
182
+ description: job.description,
183
+ key_responsibilities: job.key_responsibilities,
184
+ education_level: job.education_level,
185
+ },
186
+ };
187
+ // Use provided share handlers or default ones
188
+ const shareHandlers = {
189
+ copy: () => {
190
+ handleCopy();
191
+ onShare?.('copy');
192
+ },
193
+ whatsapp: () => {
194
+ handleWhatsAppShare();
195
+ onShare?.('whatsapp');
196
+ },
197
+ viber: () => {
198
+ handleViberShare();
199
+ onShare?.('viber');
200
+ },
201
+ messenger: () => {
202
+ handleMessengerShare();
203
+ onShare?.('messenger');
204
+ },
205
+ };
206
+ // Basic fallback components
207
+ const ButtonComponent = (Button || 'button');
208
+ const BadgeComponent = (Badge || 'span');
209
+ const ImageComponent = (Image || 'img');
210
+ const LinkComponent = (Link || 'a');
211
+ // Helper to create button props conditionally
212
+ const getButtonProps = (props) => {
213
+ if (Button) {
214
+ return props;
215
+ }
216
+ // For native button, remove custom props
217
+ const { size, variant, ...nativeProps } = props;
218
+ return nativeProps;
219
+ };
220
+ return (_jsxs("div", { className: "container", children: [_jsx("div", { className: "md:flex justify-between items-center rounded-2xl p-8 bg-primary/5 mb-8 relative", children: _jsxs("div", { className: "flex justify-between w-full", children: [_jsx("div", { children: _jsxs("div", { className: "flex gap-4 mb-2", children: [companyLogoSrc && ImageComponent && (_jsx(ImageComponent, { src: job.hide_company_name
221
+ ? '/assets/leading-company.png'
222
+ : companyLogoSrc, alt: "company-logo", width: 64, height: 64, className: "object-contain h-16 w-16 p-0.5 rounded-xl" })), _jsxs("div", { children: [_jsx("h2", { className: "text-base md:text-2xl", children: job.title }), _jsx("p", { className: "text-sm text-text-secondary", children: job.organization_name })] })] }) }), _jsx("div", { className: "flex flex-col items-end gap-2", children: _jsx("div", { className: "flex gap-3", children: isApplied ? (_jsx(ButtonComponent, { ...getButtonProps({
223
+ size: 'sm',
224
+ variant: 'secondary',
225
+ disabled: true,
226
+ className: 'hidden md:flex px-10',
227
+ }), children: "Applied" })) : sessionStatus === 'authenticated' ? (LoadingButton ? (_jsx(LoadingButton, { size: "sm", loading: applyToVacancy.isPending, onClick: onApplyJobClick, className: "hidden md:flex px-10", disabled: !canApply, children: "Apply Now" })) : (_jsx(ButtonComponent, { ...getButtonProps({
228
+ size: 'sm',
229
+ onClick: onApplyJobClick,
230
+ className: 'hidden md:flex px-10',
231
+ disabled: !canApply || applyToVacancy.isPending,
232
+ }), children: applyToVacancy.isPending ? 'Applying...' : 'Apply Now' }))) : (_jsxs(_Fragment, { children: [_jsx(ButtonComponent, { ...getButtonProps({
233
+ size: 'sm',
234
+ variant: 'secondary',
235
+ className: 'hidden md:flex px-10',
236
+ onClick: handleIsEasyApplyOpen,
237
+ disabled: !canApply,
238
+ }), children: "Easy Apply" }), _jsx(ButtonComponent, { ...getButtonProps({
239
+ size: 'sm',
240
+ className: 'hidden md:flex px-10',
241
+ onClick: () => handleAuthRequiredAction('apply'),
242
+ disabled: !canApply,
243
+ }), children: "Apply Now" })] })) }) })] }) }), _jsx("div", { className: "grid md:grid-cols-3 gap-4", children: _jsxs("div", { className: "md:col-span-2 space-y-8", children: [_jsxs("section", { children: [_jsx("p", { className: "text-lg font-medium", children: "Job Description" }), extractPlainText(job.description) ? (_jsx("div", { className: "text-text-secondary prose prose-sm max-w-none", dangerouslySetInnerHTML: {
244
+ __html: sanitizeHTML(job.description),
245
+ } })) : (_jsx("p", { className: "text-text-secondary", children: "No description provided." }))] }), _jsxs("section", { children: [_jsx("p", { className: "text-lg font-medium", children: "Key Responsibilities" }), extractPlainText(job.key_responsibilities) ? (_jsx("div", { className: "text-text-secondary prose prose-sm max-w-none", dangerouslySetInnerHTML: {
246
+ __html: sanitizeHTML(job.key_responsibilities),
247
+ } })) : (_jsx("p", { className: "text-text-secondary", children: "No responsibilities listed." }))] }), _jsxs("section", { children: [_jsx("p", { className: "text-lg font-medium", children: "Skills" }), _jsx("ul", { className: "list-disc list-inside space-y-2 text-text-secondary", children: job.skills_required?.map((skill, index) => (_jsx("li", { children: skill }, index))) })] })] }) }), ScreeningQuestionsPanel && (_jsx(ScreeningQuestionsPanel, { isOpen: openQuestions, setOpen: setOpenQuestions, selectedVacancy: selectedVacancyForQuestions, questions: screeningQuestions?.data || [] })), EasyApply && (_jsx(EasyApply, { isSheetOpen: isEasyApplyOpen, setSheetOpen: setIsEasyApplyOpen, selectedVacancy: job, mode: "advanced" })), Dialog &&
248
+ DialogContent &&
249
+ DialogHeader &&
250
+ DialogTitle &&
251
+ DialogDescription &&
252
+ DialogFooter &&
253
+ CVSelectionPanel && (_jsx(Dialog, { open: showCVSelection, onOpenChange: setShowCVSelection, children: _jsxs(DialogContent, { className: "max-w-2xl max-h-[90vh] overflow-hidden flex flex-col", children: [_jsxs(DialogHeader, { children: [_jsx(DialogTitle, { children: "Select CV for Application" }), _jsxs(DialogDescription, { children: ["Choose which CV to send with your application for", ' ', _jsx("span", { className: "font-semibold", children: job?.title })] })] }), _jsx("div", { className: "flex-1 overflow-y-auto pr-4", children: _jsx(CVSelectionPanel, { selectedCV: selectedCV, onCVSelect: setSelectedCV }) }), _jsxs(DialogFooter, { children: [_jsx(ButtonComponent, { ...getButtonProps({
254
+ variant: 'outline',
255
+ onClick: () => {
256
+ setShowCVSelection(false);
257
+ setSelectedCV(null);
258
+ },
259
+ }), children: "Cancel" }), LoadingButton ? (_jsx(LoadingButton, { loading: applyToVacancy.isPending, onClick: handleApplyWithCV, children: "Apply Now" })) : (_jsx(ButtonComponent, { onClick: handleApplyWithCV, disabled: applyToVacancy.isPending, children: applyToVacancy.isPending ? 'Applying...' : 'Apply Now' }))] })] }) }))] }));
260
+ }
@@ -0,0 +1,3 @@
1
+ import type { ApplicantItem } from '../types/applicant';
2
+ export declare const useApplicantList: (token?: string, enabled?: boolean) => import("@tanstack/react-query").UseQueryResult<ApplicantItem[], Error>;
3
+ //# sourceMappingURL=useApplicantList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useApplicantList.d.ts","sourceRoot":"","sources":["../../src/hooks/useApplicantList.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,aAAa,EAAwB,MAAM,oBAAoB,CAAC;AAG9E,eAAO,MAAM,gBAAgB,GAAI,QAAQ,MAAM,EAAE,UAAS,OAAc,2EAoCvE,CAAC"}
@@ -0,0 +1,35 @@
1
+ 'use client';
2
+ import { useQuery } from '@tanstack/react-query';
3
+ import { apiRequest } from '../utils/api-request';
4
+ import { API } from '../api-client';
5
+ export const useApplicantList = (token, enabled = true) => {
6
+ return useQuery({
7
+ queryKey: ['applicants', token],
8
+ queryFn: async () => {
9
+ if (!token)
10
+ return [];
11
+ let page = 1;
12
+ let hasNextPage = true;
13
+ const allApplicants = [];
14
+ while (hasNextPage) {
15
+ const response = await apiRequest({
16
+ endpoint: API.applicants.list(page),
17
+ token,
18
+ });
19
+ if (!response.success || !response.data) {
20
+ break;
21
+ }
22
+ const pageData = response.data?.data;
23
+ if (!Array.isArray(pageData) || pageData.length === 0) {
24
+ break;
25
+ }
26
+ allApplicants.push(...pageData);
27
+ hasNextPage = !!response.data?.pagination?.nextPage;
28
+ page++;
29
+ }
30
+ return allApplicants;
31
+ },
32
+ enabled: enabled && !!token,
33
+ staleTime: 1000 * 60 * 2, // 2 minutes
34
+ });
35
+ };
@@ -0,0 +1,18 @@
1
+ import type { ApplicantPayload } from '../types/applicant';
2
+ export declare const useApplicantMutations: (token?: string) => {
3
+ applyToVacancy: import("@tanstack/react-query").UseMutationResult<unknown, Error, ApplicantPayload, unknown>;
4
+ updateApplication: import("@tanstack/react-query").UseMutationResult<unknown, Error, {
5
+ id: string;
6
+ data: ApplicantPayload;
7
+ }, unknown>;
8
+ deleteApplication: import("@tanstack/react-query").UseMutationResult<unknown, Error, string, unknown>;
9
+ applyToVacancyBatch: import("@tanstack/react-query").UseMutationResult<unknown, Error, {
10
+ personal_detail_id: string;
11
+ vacancy_id: string;
12
+ }[], unknown>;
13
+ statusUpdate: import("@tanstack/react-query").UseMutationResult<unknown, Error, {
14
+ status: string;
15
+ id: string;
16
+ }, unknown>;
17
+ };
18
+ //# sourceMappingURL=useApplicantMutations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useApplicantMutations.d.ts","sourceRoot":"","sources":["../../src/hooks/useApplicantMutations.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAG3D,eAAO,MAAM,qBAAqB,GAAI,QAAQ,MAAM;;;YA4B1C,MAAM;cACJ,gBAAgB;;;;4BA0CA,MAAM;oBACd,MAAM;;;gBAsBuB,MAAM;YAAM,MAAM;;CA4BlE,CAAC"}
@@ -0,0 +1,100 @@
1
+ 'use client';
2
+ import { useMutation, useQueryClient } from '@tanstack/react-query';
3
+ import { apiRequest } from '../utils/api-request';
4
+ import { API } from '../api-client';
5
+ export const useApplicantMutations = (token) => {
6
+ const queryClient = useQueryClient();
7
+ const applyToVacancy = useMutation({
8
+ mutationFn: async (data) => {
9
+ const res = await apiRequest({
10
+ endpoint: API.applicants.create(),
11
+ method: 'POST',
12
+ data,
13
+ token: token,
14
+ });
15
+ if (!res.success) {
16
+ throw new Error(res.errors?.general?.[0] || 'Application failed');
17
+ }
18
+ return res.data;
19
+ },
20
+ onSuccess: () => {
21
+ queryClient.invalidateQueries({ queryKey: ['applicants'] });
22
+ },
23
+ });
24
+ const updateApplication = useMutation({
25
+ mutationFn: async ({ id, data, }) => {
26
+ const res = await apiRequest({
27
+ endpoint: API.applicants.update(id),
28
+ method: 'PUT',
29
+ data,
30
+ token: token,
31
+ });
32
+ if (!res.success) {
33
+ throw new Error(res.errors?.general?.[0] || 'Update failed');
34
+ }
35
+ return res.data;
36
+ },
37
+ onSuccess: () => {
38
+ queryClient.invalidateQueries({ queryKey: ['applicants'] });
39
+ },
40
+ });
41
+ const deleteApplication = useMutation({
42
+ mutationFn: async (id) => {
43
+ const res = await apiRequest({
44
+ endpoint: API.applicants.delete(id),
45
+ method: 'DELETE',
46
+ token: token,
47
+ });
48
+ if (!res.success) {
49
+ throw new Error(res.errors?.general?.[0] || 'Delete failed');
50
+ }
51
+ return res.data;
52
+ },
53
+ onSuccess: () => {
54
+ queryClient.invalidateQueries({ queryKey: ['applicants'] });
55
+ },
56
+ });
57
+ const applyToVacancyBatch = useMutation({
58
+ mutationFn: async (payload) => {
59
+ const res = await apiRequest({
60
+ endpoint: API.applicants.batch(),
61
+ method: 'POST',
62
+ data: payload,
63
+ token: token,
64
+ });
65
+ if (!res.success) {
66
+ throw new Error(res.errors?.general?.[0] || 'Failed to assign application');
67
+ }
68
+ return res.data;
69
+ },
70
+ onSuccess: () => {
71
+ queryClient.invalidateQueries({ queryKey: ['applicants'] });
72
+ },
73
+ });
74
+ const statusUpdate = useMutation({
75
+ mutationFn: async ({ status, id }) => {
76
+ const res = await apiRequest({
77
+ endpoint: API.applicants.update(id),
78
+ method: 'PATCH',
79
+ token: token,
80
+ data: {
81
+ status: status,
82
+ },
83
+ });
84
+ if (!res.success) {
85
+ throw new Error(res.errors?.general?.[0] || 'Failed to Update status');
86
+ }
87
+ return res.data;
88
+ },
89
+ onSuccess: () => {
90
+ queryClient.invalidateQueries({ queryKey: ['applicants'] });
91
+ },
92
+ });
93
+ return {
94
+ applyToVacancy,
95
+ updateApplication,
96
+ deleteApplication,
97
+ applyToVacancyBatch,
98
+ statusUpdate,
99
+ };
100
+ };
@@ -0,0 +1,3 @@
1
+ import type { SavedVacancyItem } from '../types/saved-vacancy';
2
+ export declare const useSavedVacancyList: (token?: string) => import("@tanstack/react-query").UseQueryResult<SavedVacancyItem[], Error>;
3
+ //# sourceMappingURL=useSavedVacancyList.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSavedVacancyList.d.ts","sourceRoot":"","sources":["../../src/hooks/useSavedVacancyList.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,gBAAgB,EAA2B,MAAM,wBAAwB,CAAC;AAGxF,eAAO,MAAM,mBAAmB,GAAI,QAAQ,MAAM,8EAmCjD,CAAC"}
@@ -0,0 +1,35 @@
1
+ 'use client';
2
+ import { useQuery } from '@tanstack/react-query';
3
+ import { apiRequest } from '../utils/api-request';
4
+ import { API } from '../api-client';
5
+ export const useSavedVacancyList = (token) => {
6
+ return useQuery({
7
+ queryKey: ['saved-vacancy', token],
8
+ enabled: !!token,
9
+ staleTime: 1000 * 60 * 2,
10
+ queryFn: async () => {
11
+ if (!token)
12
+ return [];
13
+ let page = 1;
14
+ let hasNextPage = true;
15
+ const allSavedVacancies = [];
16
+ while (hasNextPage) {
17
+ const res = await apiRequest({
18
+ endpoint: API.savedVacancies.list(page),
19
+ token,
20
+ });
21
+ if (!res.success || !res.data) {
22
+ break;
23
+ }
24
+ const paginated = res.data;
25
+ const rows = paginated?.data;
26
+ if (!Array.isArray(rows) || rows.length === 0)
27
+ break;
28
+ allSavedVacancies.push(...rows);
29
+ hasNextPage = Boolean(paginated?.pagination?.nextPage);
30
+ page = paginated?.pagination?.nextPage ?? page + 1;
31
+ }
32
+ return allSavedVacancies;
33
+ },
34
+ });
35
+ };
@@ -0,0 +1,9 @@
1
+ import type { SavedVacancyPayload } from '../types/saved-vacancy';
2
+ export declare const useSavedVacancyMutations: (token?: string) => {
3
+ createSavedVacancy: import("@tanstack/react-query").UseMutationResult<unknown, Error, SavedVacancyPayload, unknown>;
4
+ deleteSavedVacancy: import("@tanstack/react-query").UseMutationResult<unknown, Error, {
5
+ vacancy_id: string;
6
+ id?: string;
7
+ }, unknown>;
8
+ };
9
+ //# sourceMappingURL=useSavedVacancyMutations.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useSavedVacancyMutations.d.ts","sourceRoot":"","sources":["../../src/hooks/useSavedVacancyMutations.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,wBAAwB,CAAC;AAGlE,eAAO,MAAM,wBAAwB,GAAI,QAAQ,MAAM;;;oBA0BZ,MAAM;aAAO,MAAM;;CAyB7D,CAAC"}
@@ -0,0 +1,49 @@
1
+ 'use client';
2
+ import { useMutation, useQueryClient } from '@tanstack/react-query';
3
+ import { apiRequest } from '../utils/api-request';
4
+ import { API } from '../api-client';
5
+ export const useSavedVacancyMutations = (token) => {
6
+ const queryClient = useQueryClient();
7
+ const createSavedVacancy = useMutation({
8
+ mutationFn: async (data) => {
9
+ const res = await apiRequest({
10
+ endpoint: API.savedVacancies.create(),
11
+ method: 'POST',
12
+ data: data,
13
+ token: token,
14
+ });
15
+ if (!res.success) {
16
+ throw new Error(res.errors?.general?.[0] || 'Something went wrong');
17
+ }
18
+ return res.data;
19
+ },
20
+ onSuccess: () => {
21
+ queryClient.invalidateQueries({
22
+ queryKey: ['saved-vacancy'],
23
+ });
24
+ },
25
+ });
26
+ const deleteSavedVacancy = useMutation({
27
+ mutationFn: async (data) => {
28
+ const id = data.id || data.vacancy_id;
29
+ const res = await apiRequest({
30
+ endpoint: API.savedVacancies.delete(id),
31
+ method: 'DELETE',
32
+ token: token,
33
+ });
34
+ if (!res.success) {
35
+ throw new Error(res.errors?.general?.[0] || 'Something went wrong');
36
+ }
37
+ return res.data;
38
+ },
39
+ onSuccess: () => {
40
+ queryClient.invalidateQueries({
41
+ queryKey: ['saved-vacancy'],
42
+ });
43
+ },
44
+ });
45
+ return {
46
+ createSavedVacancy,
47
+ deleteSavedVacancy,
48
+ };
49
+ };
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Hook for sharing job links via social media
3
+ * Pass a FULL path like "/jobs/<slug>"
4
+ */
5
+ export declare function useShareJob(path?: string): {
6
+ isShareOpen: boolean;
7
+ toggleShare: () => void;
8
+ currentUrl: string;
9
+ handleCopy: () => Promise<boolean>;
10
+ handleWhatsAppShare: () => Window | null;
11
+ handleViberShare: () => Window | null;
12
+ handleMessengerShare: () => void;
13
+ };
14
+ //# sourceMappingURL=useShareJob.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useShareJob.d.ts","sourceRoot":"","sources":["../../src/hooks/useShareJob.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,WAAW,CAAC,IAAI,CAAC,EAAE,MAAM;;;;;;;;EAqDxC"}
@@ -0,0 +1,44 @@
1
+ 'use client';
2
+ import { useState, useEffect } from 'react';
3
+ /**
4
+ * Hook for sharing job links via social media
5
+ * Pass a FULL path like "/jobs/<slug>"
6
+ */
7
+ export function useShareJob(path) {
8
+ const [isShareOpen, setIsShareOpen] = useState(false);
9
+ const [currentUrl, setCurrentUrl] = useState('');
10
+ useEffect(() => {
11
+ if (typeof window !== 'undefined' && path) {
12
+ const clean = path.startsWith('/') ? path : `/${path}`;
13
+ setCurrentUrl(`${window.location.origin}${clean}`);
14
+ }
15
+ }, [path]);
16
+ const toggleShare = () => setIsShareOpen((prev) => !prev);
17
+ const handleCopy = async () => {
18
+ try {
19
+ await navigator.clipboard.writeText(currentUrl);
20
+ return true;
21
+ }
22
+ catch (err) {
23
+ console.error('Failed to copy: ', err);
24
+ return false;
25
+ }
26
+ };
27
+ const handleWhatsAppShare = () => window.open(`https://wa.me/?text=${encodeURIComponent(currentUrl)}`, '_blank');
28
+ const handleViberShare = () => window.open(`viber://forward?text=${encodeURIComponent(currentUrl)}`, '_blank');
29
+ const handleMessengerShare = () => {
30
+ const appId = '1440291940427577';
31
+ const redirectUri = currentUrl;
32
+ const url = `https://www.facebook.com/dialog/send?link=${encodeURIComponent(currentUrl)}&app_id=${appId}&redirect_uri=${encodeURIComponent(redirectUri)}`;
33
+ window.open(url, '_blank');
34
+ };
35
+ return {
36
+ isShareOpen,
37
+ toggleShare,
38
+ currentUrl,
39
+ handleCopy,
40
+ handleWhatsAppShare,
41
+ handleViberShare,
42
+ handleMessengerShare,
43
+ };
44
+ }
@@ -0,0 +1,5 @@
1
+ import type { VacancyQuestionsResponse } from '../types/questions';
2
+ export declare const useVacancyQuestions: (vacancyId: string, token?: string, options?: {
3
+ enabled?: boolean;
4
+ }) => import("@tanstack/react-query").UseQueryResult<VacancyQuestionsResponse, Error>;
5
+ //# sourceMappingURL=useVacancyQuestions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useVacancyQuestions.d.ts","sourceRoot":"","sources":["../../src/hooks/useVacancyQuestions.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AAGnE,eAAO,MAAM,mBAAmB,GAC9B,WAAW,MAAM,EACjB,QAAQ,MAAM,EACd,UAAU;IAAE,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,oFA2BhC,CAAC"}
@@ -0,0 +1,26 @@
1
+ 'use client';
2
+ import { useQuery } from '@tanstack/react-query';
3
+ import { apiRequest } from '../utils/api-request';
4
+ import { API } from '../api-client';
5
+ export const useVacancyQuestions = (vacancyId, token, options) => {
6
+ return useQuery({
7
+ queryKey: ['vacancy-questions', vacancyId],
8
+ queryFn: async () => {
9
+ const res = await apiRequest({
10
+ endpoint: API.questions.byVacancyId(vacancyId),
11
+ method: 'GET',
12
+ token: token,
13
+ });
14
+ if (!res.success || !res.data) {
15
+ throw new Error(res.errors?.general?.[0] ||
16
+ 'Failed to fetch screening questions');
17
+ }
18
+ return res.data;
19
+ },
20
+ enabled: !!vacancyId &&
21
+ typeof window !== 'undefined' &&
22
+ !!token &&
23
+ (options?.enabled !== false),
24
+ ...options,
25
+ });
26
+ };
package/dist/index.d.ts CHANGED
@@ -1,9 +1,20 @@
1
1
  export { initApi, getBaseURL, API } from './api-client';
2
2
  export type { SingleVacancyRes, VacancyApiRes, Pagination, ExperienceLevel, } from './types';
3
+ export type { ApplicantItem, ApplicantApiResponse, ApplicantPayload, } from './types/applicant';
4
+ export type { SavedVacancyItem, SavedVacancyApiResponse, SavedVacancyPayload, } from './types/saved-vacancy';
5
+ export type { Question, AnswerOption, VacancyQuestionsResponse, } from './types/questions';
3
6
  export { apiRequest } from './utils/api-request';
4
7
  export type { ApiResponse } from './utils/api-request';
5
8
  export { useGetAllVacancy } from './hooks/useGetAllVacancy';
6
9
  export { default as useGetAllVacancyDefault } from './hooks/useGetAllVacancy';
10
+ export { useSavedVacancyMutations } from './hooks/useSavedVacancyMutations';
11
+ export { useSavedVacancyList } from './hooks/useSavedVacancyList';
12
+ export { useApplicantMutations } from './hooks/useApplicantMutations';
13
+ export { useApplicantList } from './hooks/useApplicantList';
14
+ export { useVacancyQuestions } from './hooks/useVacancyQuestions';
15
+ export { useShareJob } from './hooks/useShareJob';
7
16
  export { default as JobsClient } from './components/JobsClient';
8
17
  export type { JobsClientProps } from './components/JobsClient';
18
+ export { default as JobDescriptionClient } from './components/JobDescriptionClient';
19
+ export type { JobDescriptionClientProps } from './components/JobDescriptionClient';
9
20
  //# 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;AAGjB,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;AAG9E,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAChE,YAAY,EAAE,eAAe,EAAE,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;AAG3B,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;AAGlD,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"}
package/dist/index.js CHANGED
@@ -5,5 +5,12 @@ export { apiRequest } from './utils/api-request';
5
5
  // Hooks
6
6
  export { useGetAllVacancy } from './hooks/useGetAllVacancy';
7
7
  export { default as useGetAllVacancyDefault } from './hooks/useGetAllVacancy';
8
+ export { useSavedVacancyMutations } from './hooks/useSavedVacancyMutations';
9
+ export { useSavedVacancyList } from './hooks/useSavedVacancyList';
10
+ export { useApplicantMutations } from './hooks/useApplicantMutations';
11
+ export { useApplicantList } from './hooks/useApplicantList';
12
+ export { useVacancyQuestions } from './hooks/useVacancyQuestions';
13
+ export { useShareJob } from './hooks/useShareJob';
8
14
  // Components
9
15
  export { default as JobsClient } from './components/JobsClient';
16
+ export { default as JobDescriptionClient } from './components/JobDescriptionClient';
@@ -0,0 +1,37 @@
1
+ export interface ApplicantItem {
2
+ id: string;
3
+ personal_detail_id: string;
4
+ vacancy_id: string;
5
+ created_at: string;
6
+ updated_at: string;
7
+ status: string;
8
+ applicant_vacancy: {
9
+ id: string;
10
+ title: string;
11
+ deadline_date: string;
12
+ vacancy_company: {
13
+ id: string;
14
+ organization_name: string;
15
+ };
16
+ };
17
+ }
18
+ export interface ApplicantApiResponse {
19
+ data: ApplicantItem[];
20
+ pagination?: {
21
+ total: number;
22
+ page: number;
23
+ pages: number;
24
+ nextPage: number | null;
25
+ };
26
+ }
27
+ export type ApplicantPayload = {
28
+ personal_detail_id: string;
29
+ vacancy_id: string;
30
+ applicant_answers?: {
31
+ question_id: string;
32
+ answer: string;
33
+ }[];
34
+ cv_id?: string;
35
+ cv_type?: 'upload' | 'draft';
36
+ };
37
+ //# sourceMappingURL=applicant.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"applicant.d.ts","sourceRoot":"","sources":["../../src/types/applicant.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,iBAAiB,EAAE;QACjB,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,aAAa,EAAE,MAAM,CAAC;QACtB,eAAe,EAAE;YACf,EAAE,EAAE,MAAM,CAAC;YACX,iBAAiB,EAAE,MAAM,CAAC;SAC3B,CAAC;KACH,CAAC;CACH;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,aAAa,EAAE,CAAC;IACtB,UAAU,CAAC,EAAE;QACX,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB,CAAC;CACH;AAED,MAAM,MAAM,gBAAgB,GAAG;IAC7B,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,iBAAiB,CAAC,EAAE;QAClB,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,MAAM,CAAC;KAChB,EAAE,CAAC;IACJ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,CAAC,EAAE,QAAQ,GAAG,OAAO,CAAC;CAC9B,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,28 @@
1
+ export interface Question {
2
+ id: string;
3
+ question: string;
4
+ type: 'text' | 'tagbox' | 'radiogroup' | 'rating' | 'comment' | 'multiple_choice';
5
+ vacancy_id: string;
6
+ created_at: string;
7
+ updated_at: string;
8
+ application_answers?: AnswerOption[];
9
+ answers?: AnswerOption[];
10
+ }
11
+ export interface AnswerOption {
12
+ id: string;
13
+ question_id: string;
14
+ answer: string;
15
+ is_right: boolean | null;
16
+ created_at: string;
17
+ updated_at: string;
18
+ }
19
+ export interface VacancyQuestionsResponse {
20
+ data: Question[];
21
+ pagination: {
22
+ total: number;
23
+ page: number;
24
+ pages: number;
25
+ nextPage: number | null;
26
+ };
27
+ }
28
+ //# sourceMappingURL=questions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"questions.d.ts","sourceRoot":"","sources":["../../src/types/questions.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,GAAG,QAAQ,GAAG,YAAY,GAAG,QAAQ,GAAG,SAAS,GAAG,iBAAiB,CAAC;IAClF,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,mBAAmB,CAAC,EAAE,YAAY,EAAE,CAAC;IACrC,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED,MAAM,WAAW,YAAY;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,OAAO,GAAG,IAAI,CAAC;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,wBAAwB;IACvC,IAAI,EAAE,QAAQ,EAAE,CAAC;IACjB,UAAU,EAAE;QACV,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB,CAAC;CACH"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,22 @@
1
+ export interface SavedVacancyItem {
2
+ id: string;
3
+ vacancy_id: string;
4
+ saved_vacancies?: {
5
+ id: string;
6
+ title: string;
7
+ location: string;
8
+ };
9
+ }
10
+ export interface SavedVacancyApiResponse {
11
+ data: SavedVacancyItem[];
12
+ pagination: {
13
+ total: number;
14
+ page: number;
15
+ pages: number;
16
+ nextPage: number | null;
17
+ };
18
+ }
19
+ export type SavedVacancyPayload = {
20
+ vacancy_id: string;
21
+ };
22
+ //# sourceMappingURL=saved-vacancy.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"saved-vacancy.d.ts","sourceRoot":"","sources":["../../src/types/saved-vacancy.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE;QAChB,EAAE,EAAE,MAAM,CAAC;QACX,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;KAClB,CAAC;CACH;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,gBAAgB,EAAE,CAAC;IACzB,UAAU,EAAE;QACV,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;KACzB,CAAC;CACH;AAED,MAAM,MAAM,mBAAmB,GAAG;IAChC,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC"}
@@ -0,0 +1 @@
1
+ export {};
package/dist/types.d.ts CHANGED
@@ -1,4 +1,6 @@
1
1
  export type ExperienceLevel = {
2
+ max: number;
3
+ min: number;
2
4
  level: string;
3
5
  };
4
6
  export type SingleVacancyRes = {
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IAGb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,EAAE,MAAM,CAAC;IAG7B,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,gBAAgB,EAAE,OAAO,CAAC;IAG1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IAGpB,cAAc,EAAE;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;KACb,GAAG,IAAI,CAAC;IAET,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,EAAE,MAAM,EAAE,CAAC;IAGnB,gBAAgB,EAAE,eAAe,CAAC;IAGlC,QAAQ,EAAE,MAAM,CAAC;IAGjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,iBAAiB,EAAE,OAAO,CAAC;IAE3B,aAAa,EAAE,OAAO,CAAC;IAGvB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IAEnB,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,EAAE,MAAM,CAAC;IAG7B,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IAGvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE;QACJ,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;QACxB,gBAAgB,EAAE,MAAM,CAAC;QACzB,gBAAgB,EAAE,MAAM,CAAC;QACzB,eAAe,EAAE,MAAM,CAAC;QACxB,gBAAgB,EAAE,MAAM,CAAC;QACzB,IAAI,EAAE,gBAAgB,EAAE,CAAC;QACzB,UAAU,EAAE,UAAU,CAAC;KACxB,CAAC;CACH,CAAC"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,eAAe,GAAG;IAC5B,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;CACf,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IAGb,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,MAAM,CAAC;IACpB,oBAAoB,EAAE,MAAM,CAAC;IAG7B,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,aAAa,EAAE,MAAM,EAAE,CAAC;IACxB,mBAAmB,EAAE,MAAM,GAAG,IAAI,CAAC;IACnC,gBAAgB,EAAE,MAAM,CAAC;IACzB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,gBAAgB,EAAE,OAAO,CAAC;IAG1B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IAGpB,cAAc,EAAE;QACd,GAAG,EAAE,MAAM,CAAC;QACZ,GAAG,EAAE,MAAM,CAAC;KACb,GAAG,IAAI,CAAC;IAET,eAAe,EAAE,MAAM,EAAE,CAAC;IAC1B,QAAQ,EAAE,MAAM,EAAE,CAAC;IAGnB,gBAAgB,EAAE,eAAe,CAAC;IAGlC,QAAQ,EAAE,MAAM,CAAC;IAGjB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,MAAM,CAAC;IACrB,aAAa,EAAE,MAAM,CAAC;IACtB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5B,iBAAiB,EAAE,OAAO,CAAC;IAE3B,aAAa,EAAE,OAAO,CAAC;IAGvB,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,GAAG,MAAM,CAAC;IAC7B,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IAEnB,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,EAAE,MAAM,CAAC;IAG7B,gBAAgB,EAAE,MAAM,CAAC;IACzB,cAAc,EAAE,MAAM,CAAC;IAGvB,WAAW,CAAC,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,UAAU,GAAG;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,aAAa,GAAG;IAC1B,IAAI,EAAE;QACJ,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;QACxB,gBAAgB,EAAE,MAAM,CAAC;QACzB,gBAAgB,EAAE,MAAM,CAAC;QACzB,eAAe,EAAE,MAAM,CAAC;QACxB,gBAAgB,EAAE,MAAM,CAAC;QACzB,IAAI,EAAE,gBAAgB,EAAE,CAAC;QACzB,UAAU,EAAE,UAAU,CAAC;KACxB,CAAC;CACH,CAAC"}
package/package.json CHANGED
@@ -1,39 +1,39 @@
1
- {
2
- "name": "@recruitnepal/shared-packages",
3
- "version": "1.0.0",
4
- "description": "Shared UI components and hooks for Recruit Nepal projects",
5
- "main": "dist/index.js",
6
- "types": "dist/index.d.ts",
7
- "scripts": {
8
- "build": "tsc",
9
- "dev": "tsc --watch",
10
- "prepublishOnly": "npm run build"
11
- },
12
- "keywords": [
13
- "react",
14
- "nextjs",
15
- "recruit-nepal",
16
- "shared-components"
17
- ],
18
- "author": "",
19
- "license": "MIT",
20
- "peerDependencies": {
21
- "react": "^18.2.0",
22
- "react-dom": "^18.2.0",
23
- "next": "^14.0.0",
24
- "@tanstack/react-query": "^5.50.0"
25
- },
26
- "dependencies": {
27
- "axios": "^1.7.8"
28
- },
29
- "devDependencies": {
30
- "@types/node": "^20.11.17",
31
- "@types/react": "^18.2.55",
32
- "@types/react-dom": "^18.2.19",
33
- "typescript": "^5.3.3"
34
- },
35
- "files": [
36
- "dist",
37
- "README.md"
38
- ]
39
- }
1
+ {
2
+ "name": "@recruitnepal/shared-packages",
3
+ "version": "1.1.0",
4
+ "description": "Shared UI components and hooks for Recruit Nepal projects",
5
+ "main": "dist/index.js",
6
+ "types": "dist/index.d.ts",
7
+ "scripts": {
8
+ "build": "tsc",
9
+ "dev": "tsc --watch",
10
+ "prepublishOnly": "npm run build"
11
+ },
12
+ "keywords": [
13
+ "react",
14
+ "nextjs",
15
+ "recruit-nepal",
16
+ "shared-components"
17
+ ],
18
+ "author": "",
19
+ "license": "MIT",
20
+ "peerDependencies": {
21
+ "react": "^18.2.0",
22
+ "react-dom": "^18.2.0",
23
+ "next": "^14.0.0",
24
+ "@tanstack/react-query": "^5.50.0"
25
+ },
26
+ "dependencies": {
27
+ "axios": "^1.7.8"
28
+ },
29
+ "devDependencies": {
30
+ "@types/node": "^20.11.17",
31
+ "@types/react": "^18.2.55",
32
+ "@types/react-dom": "^18.2.19",
33
+ "typescript": "^5.3.3"
34
+ },
35
+ "files": [
36
+ "dist",
37
+ "README.md"
38
+ ]
39
+ }