@next-degree/pickle-shared-js 0.11.0 → 0.12.2

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 (111) hide show
  1. package/dist/{company_service_sanity-CGNCrk8e.d.cts → company_service_sanity-2J1ZuUnu.d.cts} +384 -384
  2. package/dist/{company_service_sanity-CAyYirw5.d.ts → company_service_sanity-KaAGfnNV.d.ts} +384 -384
  3. package/dist/components/jobCard/JobLocation.cjs +97 -14
  4. package/dist/components/jobCard/JobLocation.cjs.map +1 -1
  5. package/dist/components/jobCard/JobLocation.d.cts +8 -6
  6. package/dist/components/jobCard/JobLocation.d.ts +8 -6
  7. package/dist/components/jobCard/JobLocation.js +93 -14
  8. package/dist/components/jobCard/JobLocation.js.map +1 -1
  9. package/dist/components/jobPost/JobDescription.cjs +3 -1
  10. package/dist/components/jobPost/JobDescription.cjs.map +1 -1
  11. package/dist/components/jobPost/JobDescription.js +3 -1
  12. package/dist/components/jobPost/JobDescription.js.map +1 -1
  13. package/dist/components/jobPost/JobHeader.cjs +1 -0
  14. package/dist/components/jobPost/JobHeader.cjs.map +1 -1
  15. package/dist/components/jobPost/JobHeader.js +1 -0
  16. package/dist/components/jobPost/JobHeader.js.map +1 -1
  17. package/dist/components/jobPost/JobPost.cjs +26 -18
  18. package/dist/components/jobPost/JobPost.cjs.map +1 -1
  19. package/dist/components/jobPost/JobPost.d.cts +1 -1
  20. package/dist/components/jobPost/JobPost.d.ts +1 -1
  21. package/dist/components/jobPost/JobPost.js +26 -18
  22. package/dist/components/jobPost/JobPost.js.map +1 -1
  23. package/dist/components/primitives/command.d.cts +3 -3
  24. package/dist/components/primitives/command.d.ts +3 -3
  25. package/dist/components/primitives/input-otp.d.cts +2 -2
  26. package/dist/components/primitives/input-otp.d.ts +2 -2
  27. package/dist/components/ui/Chip.cjs +1 -0
  28. package/dist/components/ui/Chip.cjs.map +1 -1
  29. package/dist/components/ui/Chip.d.cts +1 -1
  30. package/dist/components/ui/Chip.d.ts +1 -1
  31. package/dist/components/ui/Chip.js +1 -0
  32. package/dist/components/ui/Chip.js.map +1 -1
  33. package/dist/components/ui/Combobox.cjs +28 -19
  34. package/dist/components/ui/Combobox.cjs.map +1 -1
  35. package/dist/components/ui/Combobox.js +29 -20
  36. package/dist/components/ui/Combobox.js.map +1 -1
  37. package/dist/components/ui/DismissibleBanner.cjs +85 -0
  38. package/dist/components/ui/DismissibleBanner.cjs.map +1 -0
  39. package/dist/components/ui/DismissibleBanner.d.cts +11 -0
  40. package/dist/components/ui/DismissibleBanner.d.ts +11 -0
  41. package/dist/components/ui/DismissibleBanner.js +60 -0
  42. package/dist/components/ui/DismissibleBanner.js.map +1 -0
  43. package/dist/components/ui/ReadMore.cjs +3 -1
  44. package/dist/components/ui/ReadMore.cjs.map +1 -1
  45. package/dist/components/ui/ReadMore.js +3 -1
  46. package/dist/components/ui/ReadMore.js.map +1 -1
  47. package/dist/components/ui/Select.cjs +1 -0
  48. package/dist/components/ui/Select.cjs.map +1 -1
  49. package/dist/components/ui/Select.js +1 -0
  50. package/dist/components/ui/Select.js.map +1 -1
  51. package/dist/{displayText-DHKm6_JF.d.cts → displayText-DW0qiJqh.d.cts} +2 -2
  52. package/dist/{displayText-D8MYOaYK.d.ts → displayText-DahwdHdi.d.ts} +2 -2
  53. package/dist/hooks/useDisplayText.d.cts +3 -3
  54. package/dist/hooks/useDisplayText.d.ts +3 -3
  55. package/dist/index.cjs +1260 -1131
  56. package/dist/index.cjs.map +1 -1
  57. package/dist/index.d.cts +10 -5
  58. package/dist/index.d.ts +10 -5
  59. package/dist/index.js +1198 -1072
  60. package/dist/index.js.map +1 -1
  61. package/dist/{job_posting_service_latest-DaKYQh30.d.cts → job_posting_service_latest-C_TEBzCf.d.cts} +289 -289
  62. package/dist/{job_posting_service_latest-DaKYQh30.d.ts → job_posting_service_latest-C_TEBzCf.d.ts} +289 -289
  63. package/dist/{job_posting_service_latest-C8PT9mxn.d.cts → job_posting_service_latest-DdgK8Nnz.d.cts} +290 -290
  64. package/dist/{job_posting_service_latest-C8PT9mxn.d.ts → job_posting_service_latest-DdgK8Nnz.d.ts} +290 -290
  65. package/dist/{job_posting_service_sanity-nyUCPROx.d.ts → job_posting_service_sanity-BKo9TBDT.d.ts} +630 -630
  66. package/dist/{job_posting_service_sanity-BK7jdr2W.d.cts → job_posting_service_sanity-BNq-Am9N.d.cts} +630 -630
  67. package/dist/lib/locations.cjs +32 -7
  68. package/dist/lib/locations.cjs.map +1 -1
  69. package/dist/lib/locations.d.cts +8 -5
  70. package/dist/lib/locations.d.ts +8 -5
  71. package/dist/lib/locations.js +30 -6
  72. package/dist/lib/locations.js.map +1 -1
  73. package/dist/lib/mappings.d.cts +3 -3
  74. package/dist/lib/mappings.d.ts +3 -3
  75. package/dist/lib/salaryRange.cjs +14 -12
  76. package/dist/lib/salaryRange.cjs.map +1 -1
  77. package/dist/lib/salaryRange.d.cts +2 -2
  78. package/dist/lib/salaryRange.d.ts +2 -2
  79. package/dist/lib/salaryRange.js +14 -12
  80. package/dist/lib/salaryRange.js.map +1 -1
  81. package/dist/services/displayText.d.cts +3 -3
  82. package/dist/services/displayText.d.ts +3 -3
  83. package/dist/styles/globals.css +3 -7
  84. package/dist/styles/globals.css.map +1 -1
  85. package/dist/types/data/company_service_latest.d.cts +1 -1
  86. package/dist/types/data/company_service_latest.d.ts +1 -1
  87. package/dist/types/data/job_posting_service_latest.d.cts +1 -1
  88. package/dist/types/data/job_posting_service_latest.d.ts +1 -1
  89. package/dist/types/data/shared_pickle_output_latest.d.cts +1 -1
  90. package/dist/types/data/shared_pickle_output_latest.d.ts +1 -1
  91. package/dist/types/index.d.cts +5 -5
  92. package/dist/types/index.d.ts +5 -5
  93. package/dist/types/latest/company_service_latest.d.cts +1 -1
  94. package/dist/types/latest/company_service_latest.d.ts +1 -1
  95. package/dist/types/latest/custom/company_service_sanity.d.cts +3 -3
  96. package/dist/types/latest/custom/company_service_sanity.d.ts +3 -3
  97. package/dist/types/latest/custom/job_posting_service_sanity.d.cts +3 -3
  98. package/dist/types/latest/custom/job_posting_service_sanity.d.ts +3 -3
  99. package/dist/types/latest/job_posting_service_latest.d.cts +1 -1
  100. package/dist/types/latest/job_posting_service_latest.d.ts +1 -1
  101. package/dist/types/latest/shared_pickle_output_latest.d.cts +1 -1
  102. package/dist/types/latest/shared_pickle_output_latest.d.ts +1 -1
  103. package/package.json +4 -3
  104. package/dist/{company_service_latest-o6X0atwz.d.cts → company_service_latest-C7Moeufo.d.cts} +228 -228
  105. package/dist/{company_service_latest-o6X0atwz.d.ts → company_service_latest-C7Moeufo.d.ts} +228 -228
  106. package/dist/{company_service_latest-DpBsftTD.d.cts → company_service_latest-CITz7F53.d.cts} +228 -228
  107. package/dist/{company_service_latest-DpBsftTD.d.ts → company_service_latest-CITz7F53.d.ts} +228 -228
  108. package/dist/{shared_pickle_output_latest-BjRRmT8R.d.cts → shared_pickle_output_latest-CXBCG04N.d.cts} +15 -15
  109. package/dist/{shared_pickle_output_latest-BjRRmT8R.d.ts → shared_pickle_output_latest-CXBCG04N.d.ts} +15 -15
  110. package/dist/{shared_pickle_output_latest-BVF7Zh2H.d.cts → shared_pickle_output_latest-CtvHTPeX.d.cts} +15 -15
  111. package/dist/{shared_pickle_output_latest-BVF7Zh2H.d.ts → shared_pickle_output_latest-CtvHTPeX.d.ts} +15 -15
@@ -30,7 +30,7 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
30
30
  // src/components/jobCard/JobLocation.tsx
31
31
  var JobLocation_exports = {};
32
32
  __export(JobLocation_exports, {
33
- default: () => JobLocation_default
33
+ JobLocation: () => JobLocation
34
34
  });
35
35
  module.exports = __toCommonJS(JobLocation_exports);
36
36
  var import_lucide_react = require("lucide-react");
@@ -65,21 +65,104 @@ var TooltipContent = React.forwardRef(({ className, sideOffset = 4, ...props },
65
65
  ));
66
66
  TooltipContent.displayName = TooltipPrimitive.Content.displayName;
67
67
 
68
- // src/components/jobCard/JobLocation.tsx
68
+ // src/components/ui/Chip.tsx
69
+ var import_cva = require("cva");
70
+ var import_tailwind_merge2 = require("tailwind-merge");
69
71
  var import_jsx_runtime2 = require("react/jsx-runtime");
70
- function JobLocation({ mainLocation, extendedLocations }) {
71
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "flex items-center gap-2", "data-testid": "job-card-location", children: [
72
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_lucide_react.MapPin, { size: 16 }),
73
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-sm font-thin", children: mainLocation }),
74
- extendedLocations && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(Tooltip, { children: [
75
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TooltipTrigger, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "length-text group rounded-full bg-grey-5 px-2 py-1 text-sm font-bold text-gray-700 group-hover:cursor-pointer", children: [
76
- "+ ",
77
- extendedLocations.length,
78
- " more"
79
- ] }) }),
80
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(TooltipContent, { className: "border-1 rounded-md border border-grey-5 bg-white p-2", children: extendedLocations.map((location) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "text-nowrap text-sm", children: location }, location)) })
72
+ var Chip = ({ className, variant, size, ...props }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: (0, import_tailwind_merge2.twMerge)(chipVariants({ variant, size, className })), ...props });
73
+ var chipVariants = (0, import_cva.cva)(["flex", "items-center", "rounded-3xl", "border", "w-fit"], {
74
+ variants: {
75
+ variant: {
76
+ neutral: ["text-grey-80", "border-grey-10"],
77
+ primary: ["text-purple-100", "border-purple-20"],
78
+ danger: ["text-pumpkin-100", "border-pumpkin-20"],
79
+ jobLocation: ["text-grey-80", "border-grey-10", "bg-grey-5"],
80
+ onboarding: ["text-green-100", "bg-green-10", "cursor-pointer"],
81
+ onboardingSelected: ["text-white", "bg-green-90", "cursor-pointer"]
82
+ },
83
+ size: {
84
+ small: ["text-sm", "leading-5", "px-2", "py-1", "gap-1.5"],
85
+ medium: ["text-base", "leading-6", "px-3", "py-2", "gap-2"]
86
+ }
87
+ },
88
+ defaultVariants: {
89
+ variant: "neutral",
90
+ size: "medium"
91
+ }
92
+ });
93
+ var Chip_default = Chip;
94
+
95
+ // src/lib/locations.ts
96
+ function formattedAddress(address, isRemote = false) {
97
+ if (!address) return null;
98
+ const { addressLocality, addressRegion, addressCountry } = address;
99
+ const remoteMessage = isRemote ? " | Remote" : "";
100
+ if (addressLocality && addressRegion)
101
+ return `${addressLocality}, ${addressRegion + remoteMessage}`;
102
+ if (addressRegion && addressCountry) return `${addressRegion}, ${addressCountry + remoteMessage}`;
103
+ if (addressRegion) return `${addressRegion + remoteMessage}`;
104
+ if (addressCountry) return `${addressCountry + remoteMessage}`;
105
+ return null;
106
+ }
107
+ function getAddressList(jobPost) {
108
+ const locations = [];
109
+ if (jobPost.jobLocation) {
110
+ const address = formattedAddress(jobPost.jobLocation, jobPost.isRemote);
111
+ if (address) locations.push(address);
112
+ }
113
+ if (jobPost.applicableOffices && jobPost.applicableOffices.length > 0) {
114
+ jobPost.applicableOffices.map((office) => {
115
+ const address = formattedAddress(office?.geoLocation?.address, jobPost.isRemote);
116
+ if (address && !locations.includes(address)) locations.push(address);
117
+ });
118
+ }
119
+ if (jobPost.applicantLocationRequirements && jobPost.applicantLocationRequirements.length > 0) {
120
+ jobPost.applicantLocationRequirements.map((place) => {
121
+ const address = formattedAddress(place?.address, jobPost.isRemote);
122
+ if (address && !locations.includes(address)) locations.push(address);
123
+ });
124
+ }
125
+ return locations;
126
+ }
127
+
128
+ // src/components/jobCard/JobLocation.tsx
129
+ var import_jsx_runtime3 = require("react/jsx-runtime");
130
+ function JobLocation({ jobPost }) {
131
+ const locations = getAddressList(jobPost);
132
+ if (!locations || locations.length === 0) return null;
133
+ const primaryOffice = locations[0];
134
+ const extendedLocations = locations.slice(1).map((address) => address);
135
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex items-center gap-2", "data-testid": "job-location-element", children: [
136
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_lucide_react.MapPin, { size: 16 }),
137
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-sm font-thin", children: primaryOffice }),
138
+ extendedLocations.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TooltipProvider, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(Tooltip, { children: [
139
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(TooltipTrigger, { children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
140
+ Chip_default,
141
+ {
142
+ className: "font-bold",
143
+ size: "small",
144
+ variant: "jobLocation",
145
+ "data-testid": "job-location-tooltip",
146
+ children: [
147
+ "+ ",
148
+ extendedLocations.length,
149
+ " more"
150
+ ]
151
+ }
152
+ ) }),
153
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
154
+ TooltipContent,
155
+ {
156
+ className: "border-1 rounded-md border border-grey-5 bg-white p-2",
157
+ "data-testid": "job-location-tooltip-content",
158
+ children: extendedLocations.map((location) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("div", { className: "text-nowrap text-sm", children: location }, location))
159
+ }
160
+ )
81
161
  ] }) })
82
162
  ] });
83
163
  }
84
- var JobLocation_default = JobLocation;
164
+ // Annotate the CommonJS export names for ESM import in node:
165
+ 0 && (module.exports = {
166
+ JobLocation
167
+ });
85
168
  //# sourceMappingURL=JobLocation.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/jobCard/JobLocation.tsx","../../../src/components/primitives/tooltip.tsx","../../../src/lib/utils.ts"],"sourcesContent":["import { MapPin } from 'lucide-react'\n\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '@/components/primitives/tooltip'\n\ntype JobLocationProps = Readonly<{\n mainLocation: string\n extendedLocations?: string[]\n}>\n\nfunction JobLocation({ mainLocation, extendedLocations }: JobLocationProps) {\n return (\n <div className=\"flex items-center gap-2\" data-testid=\"job-card-location\">\n <MapPin size={16} />\n <span className=\"text-sm font-thin\">{mainLocation}</span>\n {extendedLocations && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger>\n <div className=\"length-text group rounded-full bg-grey-5 px-2 py-1 text-sm font-bold text-gray-700 group-hover:cursor-pointer\">\n + {extendedLocations.length} more\n </div>\n </TooltipTrigger>\n <TooltipContent className=\"border-1 rounded-md border border-grey-5 bg-white p-2\">\n {extendedLocations.map((location) => (\n <div key={location} className=\"text-nowrap text-sm\">\n {location}\n </div>\n ))}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n )\n}\n\nexport default JobLocation\n","'use client'\n\nimport * as TooltipPrimitive from '@radix-ui/react-tooltip'\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nconst TooltipProvider = TooltipPrimitive.Provider\n\nconst Tooltip = TooltipPrimitive.Root\n\nconst TooltipTrigger = TooltipPrimitive.Trigger\n\nconst TooltipContent = React.forwardRef<\n React.ElementRef<typeof TooltipPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n <TooltipPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n 'z-50 overflow-hidden rounded-md border border-neutral-200 bg-white px-3 py-1.5 text-sm text-neutral-950 shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:border-neutral-800 dark:bg-neutral-950 dark:text-neutral-50',\n className\n )}\n {...props}\n />\n))\nTooltipContent.displayName = TooltipPrimitive.Content.displayName\n\nexport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger }\n","import { type ClassValue, clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,0BAAuB;;;ACEvB,uBAAkC;AAClC,YAAuB;;;ACHvB,kBAAsC;AACtC,4BAAwB;AAEjB,SAAS,MAAM,QAAsB;AAC1C,aAAO,mCAAQ,kBAAK,MAAM,CAAC;AAC7B;;;ADYE;AAVF,IAAM,kBAAmC;AAEzC,IAAM,UAA2B;AAEjC,IAAM,iBAAkC;AAExC,IAAM,iBAAuB,iBAG3B,CAAC,EAAE,WAAW,aAAa,GAAG,GAAG,MAAM,GAAG,QAC1C;AAAA,EAAkB;AAAA,EAAjB;AAAA,IACC;AAAA,IACA;AAAA,IACA,WAAW;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,IACC,GAAG;AAAA;AACN,CACD;AACD,eAAe,cAA+B,yBAAQ;;;ADVhD,IAAAA,sBAAA;AAHN,SAAS,YAAY,EAAE,cAAc,kBAAkB,GAAqB;AAC1E,SACE,8CAAC,SAAI,WAAU,2BAA0B,eAAY,qBACnD;AAAA,iDAAC,8BAAO,MAAM,IAAI;AAAA,IAClB,6CAAC,UAAK,WAAU,qBAAqB,wBAAa;AAAA,IACjD,qBACC,6CAAC,mBACC,wDAAC,WACC;AAAA,mDAAC,kBACC,wDAAC,SAAI,WAAU,iHAAgH;AAAA;AAAA,QAC1H,kBAAkB;AAAA,QAAO;AAAA,SAC9B,GACF;AAAA,MACA,6CAAC,kBAAe,WAAU,yDACvB,4BAAkB,IAAI,CAAC,aACtB,6CAAC,SAAmB,WAAU,uBAC3B,sBADO,QAEV,CACD,GACH;AAAA,OACF,GACF;AAAA,KAEJ;AAEJ;AAEA,IAAO,sBAAQ;","names":["import_jsx_runtime"]}
1
+ {"version":3,"sources":["../../../src/components/jobCard/JobLocation.tsx","../../../src/components/primitives/tooltip.tsx","../../../src/lib/utils.ts","../../../src/components/ui/Chip.tsx","../../../src/lib/locations.ts"],"sourcesContent":["import { MapPin } from 'lucide-react'\nimport { type z } from 'zod'\n\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '@/components/primitives/tooltip'\nimport Chip from '@/components/ui/Chip'\nimport { getAddressList } from '@/lib/locations'\nimport { type jobPostSchema } from '@/types/latest/job_posting_service_latest'\n\ntype JobPost = z.infer<typeof jobPostSchema>\n\nexport type JobLocationProps = {\n jobPost: JobPost\n}\n\nexport function JobLocation({ jobPost }: JobLocationProps) {\n const locations = getAddressList(jobPost)\n if (!locations || locations.length === 0) return null\n\n const primaryOffice = locations[0]\n const extendedLocations = locations.slice(1).map((address) => address)\n\n return (\n <div className=\"flex items-center gap-2\" data-testid=\"job-location-element\">\n <MapPin size={16} />\n <span className=\"text-sm font-thin\">{primaryOffice}</span>\n {extendedLocations.length > 0 && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger>\n <Chip\n className=\"font-bold\"\n size={'small'}\n variant={'jobLocation'}\n data-testid=\"job-location-tooltip\"\n >\n + {extendedLocations.length} more\n </Chip>\n </TooltipTrigger>\n <TooltipContent\n className=\"border-1 rounded-md border border-grey-5 bg-white p-2\"\n data-testid=\"job-location-tooltip-content\"\n >\n {extendedLocations.map((location) => (\n <div key={location} className=\"text-nowrap text-sm\">\n {location}\n </div>\n ))}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n )\n}\n","'use client'\n\nimport * as TooltipPrimitive from '@radix-ui/react-tooltip'\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nconst TooltipProvider = TooltipPrimitive.Provider\n\nconst Tooltip = TooltipPrimitive.Root\n\nconst TooltipTrigger = TooltipPrimitive.Trigger\n\nconst TooltipContent = React.forwardRef<\n React.ElementRef<typeof TooltipPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n <TooltipPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n 'z-50 overflow-hidden rounded-md border border-neutral-200 bg-white px-3 py-1.5 text-sm text-neutral-950 shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:border-neutral-800 dark:bg-neutral-950 dark:text-neutral-50',\n className\n )}\n {...props}\n />\n))\nTooltipContent.displayName = TooltipPrimitive.Content.displayName\n\nexport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger }\n","import { type ClassValue, clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","import { cva, type VariantProps } from 'cva'\nimport React from 'react'\nimport { twMerge } from 'tailwind-merge'\n\ninterface ChipProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof chipVariants> {}\n\nconst Chip = ({ className, variant, size, ...props }: ChipProps) => (\n <div className={twMerge(chipVariants({ variant, size, className }))} {...props} />\n)\n\nconst chipVariants = cva(['flex', 'items-center', 'rounded-3xl', 'border', 'w-fit'], {\n variants: {\n variant: {\n neutral: ['text-grey-80', 'border-grey-10'],\n primary: ['text-purple-100', 'border-purple-20'],\n danger: ['text-pumpkin-100', 'border-pumpkin-20'],\n jobLocation: ['text-grey-80', 'border-grey-10', 'bg-grey-5'],\n onboarding: ['text-green-100', 'bg-green-10', 'cursor-pointer'],\n onboardingSelected: ['text-white', 'bg-green-90', 'cursor-pointer'],\n },\n size: {\n small: ['text-sm', 'leading-5', 'px-2', 'py-1', 'gap-1.5'],\n medium: ['text-base', 'leading-6', 'px-3', 'py-2', 'gap-2'],\n },\n },\n defaultVariants: {\n variant: 'neutral',\n size: 'medium',\n },\n})\n\nexport default Chip\n","import { type z } from 'zod'\n\nimport { type JobPostModel } from '@/types/data/job_posting_service_latest'\nimport { type PostalAddressModel } from '@/types/data/shared_pickle_output_latest'\nimport { type jobPostSchema } from '@/types/latest/job_posting_service_latest'\n\ntype JobPost = z.infer<typeof jobPostSchema>\n\nexport function formattedAddress(\n address: PostalAddressModel | undefined,\n isRemote: boolean = false\n): string | null {\n if (!address) return null\n const { addressLocality, addressRegion, addressCountry } = address\n const remoteMessage = isRemote ? ' | Remote' : ''\n if (addressLocality && addressRegion)\n return `${addressLocality}, ${addressRegion + remoteMessage}`\n if (addressRegion && addressCountry) return `${addressRegion}, ${addressCountry + remoteMessage}`\n if (addressRegion) return `${addressRegion + remoteMessage}`\n if (addressCountry) return `${addressCountry + remoteMessage}`\n return null\n}\n\nexport function getAddressList(jobPost: JobPost): string[] {\n const locations: string[] = []\n if (jobPost.jobLocation) {\n const address = formattedAddress(jobPost.jobLocation, jobPost.isRemote)\n if (address) locations.push(address)\n }\n if (jobPost.applicableOffices && jobPost.applicableOffices.length > 0) {\n jobPost.applicableOffices.map((office) => {\n const address = formattedAddress(office?.geoLocation?.address, jobPost.isRemote)\n if (address && !locations.includes(address)) locations.push(address)\n })\n }\n if (jobPost.applicantLocationRequirements && jobPost.applicantLocationRequirements.length > 0) {\n jobPost.applicantLocationRequirements.map((place) => {\n const address = formattedAddress(place?.address, jobPost.isRemote)\n if (address && !locations.includes(address)) locations.push(address)\n })\n }\n return locations\n}\n\nexport function formattedJobLocation(job: JobPostModel) {\n const address = job.jobLocation && formattedAddress(job.jobLocation)\n const remote = job.isRemote ? 'Remote' : ''\n\n return [address, remote].filter(Boolean).join(' | ')\n}\n"],"mappings":"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","names":["import_tailwind_merge","import_jsx_runtime","import_jsx_runtime"]}
@@ -1,9 +1,11 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { z } from 'zod';
3
+ import { a as jobPostSchema } from '../../job_posting_service_latest-DdgK8Nnz.cjs';
2
4
 
3
- type JobLocationProps = Readonly<{
4
- mainLocation: string;
5
- extendedLocations?: string[];
6
- }>;
7
- declare function JobLocation({ mainLocation, extendedLocations }: JobLocationProps): react_jsx_runtime.JSX.Element;
5
+ type JobPost = z.infer<typeof jobPostSchema>;
6
+ type JobLocationProps = {
7
+ jobPost: JobPost;
8
+ };
9
+ declare function JobLocation({ jobPost }: JobLocationProps): react_jsx_runtime.JSX.Element | null;
8
10
 
9
- export { JobLocation as default };
11
+ export { JobLocation, type JobLocationProps };
@@ -1,9 +1,11 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
+ import { z } from 'zod';
3
+ import { a as jobPostSchema } from '../../job_posting_service_latest-DdgK8Nnz.js';
2
4
 
3
- type JobLocationProps = Readonly<{
4
- mainLocation: string;
5
- extendedLocations?: string[];
6
- }>;
7
- declare function JobLocation({ mainLocation, extendedLocations }: JobLocationProps): react_jsx_runtime.JSX.Element;
5
+ type JobPost = z.infer<typeof jobPostSchema>;
6
+ type JobLocationProps = {
7
+ jobPost: JobPost;
8
+ };
9
+ declare function JobLocation({ jobPost }: JobLocationProps): react_jsx_runtime.JSX.Element | null;
8
10
 
9
- export { JobLocation as default };
11
+ export { JobLocation, type JobLocationProps };
@@ -31,24 +31,103 @@ var TooltipContent = React.forwardRef(({ className, sideOffset = 4, ...props },
31
31
  ));
32
32
  TooltipContent.displayName = TooltipPrimitive.Content.displayName;
33
33
 
34
+ // src/components/ui/Chip.tsx
35
+ import { cva } from "cva";
36
+ import { twMerge as twMerge2 } from "tailwind-merge";
37
+ import { jsx as jsx2 } from "react/jsx-runtime";
38
+ var Chip = ({ className, variant, size, ...props }) => /* @__PURE__ */ jsx2("div", { className: twMerge2(chipVariants({ variant, size, className })), ...props });
39
+ var chipVariants = cva(["flex", "items-center", "rounded-3xl", "border", "w-fit"], {
40
+ variants: {
41
+ variant: {
42
+ neutral: ["text-grey-80", "border-grey-10"],
43
+ primary: ["text-purple-100", "border-purple-20"],
44
+ danger: ["text-pumpkin-100", "border-pumpkin-20"],
45
+ jobLocation: ["text-grey-80", "border-grey-10", "bg-grey-5"],
46
+ onboarding: ["text-green-100", "bg-green-10", "cursor-pointer"],
47
+ onboardingSelected: ["text-white", "bg-green-90", "cursor-pointer"]
48
+ },
49
+ size: {
50
+ small: ["text-sm", "leading-5", "px-2", "py-1", "gap-1.5"],
51
+ medium: ["text-base", "leading-6", "px-3", "py-2", "gap-2"]
52
+ }
53
+ },
54
+ defaultVariants: {
55
+ variant: "neutral",
56
+ size: "medium"
57
+ }
58
+ });
59
+ var Chip_default = Chip;
60
+
61
+ // src/lib/locations.ts
62
+ function formattedAddress(address, isRemote = false) {
63
+ if (!address) return null;
64
+ const { addressLocality, addressRegion, addressCountry } = address;
65
+ const remoteMessage = isRemote ? " | Remote" : "";
66
+ if (addressLocality && addressRegion)
67
+ return `${addressLocality}, ${addressRegion + remoteMessage}`;
68
+ if (addressRegion && addressCountry) return `${addressRegion}, ${addressCountry + remoteMessage}`;
69
+ if (addressRegion) return `${addressRegion + remoteMessage}`;
70
+ if (addressCountry) return `${addressCountry + remoteMessage}`;
71
+ return null;
72
+ }
73
+ function getAddressList(jobPost) {
74
+ const locations = [];
75
+ if (jobPost.jobLocation) {
76
+ const address = formattedAddress(jobPost.jobLocation, jobPost.isRemote);
77
+ if (address) locations.push(address);
78
+ }
79
+ if (jobPost.applicableOffices && jobPost.applicableOffices.length > 0) {
80
+ jobPost.applicableOffices.map((office) => {
81
+ const address = formattedAddress(office?.geoLocation?.address, jobPost.isRemote);
82
+ if (address && !locations.includes(address)) locations.push(address);
83
+ });
84
+ }
85
+ if (jobPost.applicantLocationRequirements && jobPost.applicantLocationRequirements.length > 0) {
86
+ jobPost.applicantLocationRequirements.map((place) => {
87
+ const address = formattedAddress(place?.address, jobPost.isRemote);
88
+ if (address && !locations.includes(address)) locations.push(address);
89
+ });
90
+ }
91
+ return locations;
92
+ }
93
+
34
94
  // src/components/jobCard/JobLocation.tsx
35
- import { jsx as jsx2, jsxs } from "react/jsx-runtime";
36
- function JobLocation({ mainLocation, extendedLocations }) {
37
- return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", "data-testid": "job-card-location", children: [
38
- /* @__PURE__ */ jsx2(MapPin, { size: 16 }),
39
- /* @__PURE__ */ jsx2("span", { className: "text-sm font-thin", children: mainLocation }),
40
- extendedLocations && /* @__PURE__ */ jsx2(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
41
- /* @__PURE__ */ jsx2(TooltipTrigger, { children: /* @__PURE__ */ jsxs("div", { className: "length-text group rounded-full bg-grey-5 px-2 py-1 text-sm font-bold text-gray-700 group-hover:cursor-pointer", children: [
42
- "+ ",
43
- extendedLocations.length,
44
- " more"
45
- ] }) }),
46
- /* @__PURE__ */ jsx2(TooltipContent, { className: "border-1 rounded-md border border-grey-5 bg-white p-2", children: extendedLocations.map((location) => /* @__PURE__ */ jsx2("div", { className: "text-nowrap text-sm", children: location }, location)) })
95
+ import { jsx as jsx3, jsxs } from "react/jsx-runtime";
96
+ function JobLocation({ jobPost }) {
97
+ const locations = getAddressList(jobPost);
98
+ if (!locations || locations.length === 0) return null;
99
+ const primaryOffice = locations[0];
100
+ const extendedLocations = locations.slice(1).map((address) => address);
101
+ return /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-2", "data-testid": "job-location-element", children: [
102
+ /* @__PURE__ */ jsx3(MapPin, { size: 16 }),
103
+ /* @__PURE__ */ jsx3("span", { className: "text-sm font-thin", children: primaryOffice }),
104
+ extendedLocations.length > 0 && /* @__PURE__ */ jsx3(TooltipProvider, { children: /* @__PURE__ */ jsxs(Tooltip, { children: [
105
+ /* @__PURE__ */ jsx3(TooltipTrigger, { children: /* @__PURE__ */ jsxs(
106
+ Chip_default,
107
+ {
108
+ className: "font-bold",
109
+ size: "small",
110
+ variant: "jobLocation",
111
+ "data-testid": "job-location-tooltip",
112
+ children: [
113
+ "+ ",
114
+ extendedLocations.length,
115
+ " more"
116
+ ]
117
+ }
118
+ ) }),
119
+ /* @__PURE__ */ jsx3(
120
+ TooltipContent,
121
+ {
122
+ className: "border-1 rounded-md border border-grey-5 bg-white p-2",
123
+ "data-testid": "job-location-tooltip-content",
124
+ children: extendedLocations.map((location) => /* @__PURE__ */ jsx3("div", { className: "text-nowrap text-sm", children: location }, location))
125
+ }
126
+ )
47
127
  ] }) })
48
128
  ] });
49
129
  }
50
- var JobLocation_default = JobLocation;
51
130
  export {
52
- JobLocation_default as default
131
+ JobLocation
53
132
  };
54
133
  //# sourceMappingURL=JobLocation.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/jobCard/JobLocation.tsx","../../../src/components/primitives/tooltip.tsx","../../../src/lib/utils.ts"],"sourcesContent":["import { MapPin } from 'lucide-react'\n\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '@/components/primitives/tooltip'\n\ntype JobLocationProps = Readonly<{\n mainLocation: string\n extendedLocations?: string[]\n}>\n\nfunction JobLocation({ mainLocation, extendedLocations }: JobLocationProps) {\n return (\n <div className=\"flex items-center gap-2\" data-testid=\"job-card-location\">\n <MapPin size={16} />\n <span className=\"text-sm font-thin\">{mainLocation}</span>\n {extendedLocations && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger>\n <div className=\"length-text group rounded-full bg-grey-5 px-2 py-1 text-sm font-bold text-gray-700 group-hover:cursor-pointer\">\n + {extendedLocations.length} more\n </div>\n </TooltipTrigger>\n <TooltipContent className=\"border-1 rounded-md border border-grey-5 bg-white p-2\">\n {extendedLocations.map((location) => (\n <div key={location} className=\"text-nowrap text-sm\">\n {location}\n </div>\n ))}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n )\n}\n\nexport default JobLocation\n","'use client'\n\nimport * as TooltipPrimitive from '@radix-ui/react-tooltip'\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nconst TooltipProvider = TooltipPrimitive.Provider\n\nconst Tooltip = TooltipPrimitive.Root\n\nconst TooltipTrigger = TooltipPrimitive.Trigger\n\nconst TooltipContent = React.forwardRef<\n React.ElementRef<typeof TooltipPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n <TooltipPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n 'z-50 overflow-hidden rounded-md border border-neutral-200 bg-white px-3 py-1.5 text-sm text-neutral-950 shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:border-neutral-800 dark:bg-neutral-950 dark:text-neutral-50',\n className\n )}\n {...props}\n />\n))\nTooltipContent.displayName = TooltipPrimitive.Content.displayName\n\nexport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger }\n","import { type ClassValue, clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n"],"mappings":";AAAA,SAAS,cAAc;;;ACEvB,YAAY,sBAAsB;AAClC,YAAY,WAAW;;;ACHvB,SAA0B,YAAY;AACtC,SAAS,eAAe;AAEjB,SAAS,MAAM,QAAsB;AAC1C,SAAO,QAAQ,KAAK,MAAM,CAAC;AAC7B;;;ADYE;AAVF,IAAM,kBAAmC;AAEzC,IAAM,UAA2B;AAEjC,IAAM,iBAAkC;AAExC,IAAM,iBAAuB,iBAG3B,CAAC,EAAE,WAAW,aAAa,GAAG,GAAG,MAAM,GAAG,QAC1C;AAAA,EAAkB;AAAA,EAAjB;AAAA,IACC;AAAA,IACA;AAAA,IACA,WAAW;AAAA,MACT;AAAA,MACA;AAAA,IACF;AAAA,IACC,GAAG;AAAA;AACN,CACD;AACD,eAAe,cAA+B,yBAAQ;;;ADVhD,gBAAAA,MAMQ,YANR;AAHN,SAAS,YAAY,EAAE,cAAc,kBAAkB,GAAqB;AAC1E,SACE,qBAAC,SAAI,WAAU,2BAA0B,eAAY,qBACnD;AAAA,oBAAAA,KAAC,UAAO,MAAM,IAAI;AAAA,IAClB,gBAAAA,KAAC,UAAK,WAAU,qBAAqB,wBAAa;AAAA,IACjD,qBACC,gBAAAA,KAAC,mBACC,+BAAC,WACC;AAAA,sBAAAA,KAAC,kBACC,+BAAC,SAAI,WAAU,iHAAgH;AAAA;AAAA,QAC1H,kBAAkB;AAAA,QAAO;AAAA,SAC9B,GACF;AAAA,MACA,gBAAAA,KAAC,kBAAe,WAAU,yDACvB,4BAAkB,IAAI,CAAC,aACtB,gBAAAA,KAAC,SAAmB,WAAU,uBAC3B,sBADO,QAEV,CACD,GACH;AAAA,OACF,GACF;AAAA,KAEJ;AAEJ;AAEA,IAAO,sBAAQ;","names":["jsx"]}
1
+ {"version":3,"sources":["../../../src/components/jobCard/JobLocation.tsx","../../../src/components/primitives/tooltip.tsx","../../../src/lib/utils.ts","../../../src/components/ui/Chip.tsx","../../../src/lib/locations.ts"],"sourcesContent":["import { MapPin } from 'lucide-react'\nimport { type z } from 'zod'\n\nimport {\n Tooltip,\n TooltipContent,\n TooltipProvider,\n TooltipTrigger,\n} from '@/components/primitives/tooltip'\nimport Chip from '@/components/ui/Chip'\nimport { getAddressList } from '@/lib/locations'\nimport { type jobPostSchema } from '@/types/latest/job_posting_service_latest'\n\ntype JobPost = z.infer<typeof jobPostSchema>\n\nexport type JobLocationProps = {\n jobPost: JobPost\n}\n\nexport function JobLocation({ jobPost }: JobLocationProps) {\n const locations = getAddressList(jobPost)\n if (!locations || locations.length === 0) return null\n\n const primaryOffice = locations[0]\n const extendedLocations = locations.slice(1).map((address) => address)\n\n return (\n <div className=\"flex items-center gap-2\" data-testid=\"job-location-element\">\n <MapPin size={16} />\n <span className=\"text-sm font-thin\">{primaryOffice}</span>\n {extendedLocations.length > 0 && (\n <TooltipProvider>\n <Tooltip>\n <TooltipTrigger>\n <Chip\n className=\"font-bold\"\n size={'small'}\n variant={'jobLocation'}\n data-testid=\"job-location-tooltip\"\n >\n + {extendedLocations.length} more\n </Chip>\n </TooltipTrigger>\n <TooltipContent\n className=\"border-1 rounded-md border border-grey-5 bg-white p-2\"\n data-testid=\"job-location-tooltip-content\"\n >\n {extendedLocations.map((location) => (\n <div key={location} className=\"text-nowrap text-sm\">\n {location}\n </div>\n ))}\n </TooltipContent>\n </Tooltip>\n </TooltipProvider>\n )}\n </div>\n )\n}\n","'use client'\n\nimport * as TooltipPrimitive from '@radix-ui/react-tooltip'\nimport * as React from 'react'\n\nimport { cn } from '@/lib/utils'\n\nconst TooltipProvider = TooltipPrimitive.Provider\n\nconst Tooltip = TooltipPrimitive.Root\n\nconst TooltipTrigger = TooltipPrimitive.Trigger\n\nconst TooltipContent = React.forwardRef<\n React.ElementRef<typeof TooltipPrimitive.Content>,\n React.ComponentPropsWithoutRef<typeof TooltipPrimitive.Content>\n>(({ className, sideOffset = 4, ...props }, ref) => (\n <TooltipPrimitive.Content\n ref={ref}\n sideOffset={sideOffset}\n className={cn(\n 'z-50 overflow-hidden rounded-md border border-neutral-200 bg-white px-3 py-1.5 text-sm text-neutral-950 shadow-md animate-in fade-in-0 zoom-in-95 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 dark:border-neutral-800 dark:bg-neutral-950 dark:text-neutral-50',\n className\n )}\n {...props}\n />\n))\nTooltipContent.displayName = TooltipPrimitive.Content.displayName\n\nexport { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger }\n","import { type ClassValue, clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","import { cva, type VariantProps } from 'cva'\nimport React from 'react'\nimport { twMerge } from 'tailwind-merge'\n\ninterface ChipProps\n extends React.HTMLAttributes<HTMLDivElement>,\n VariantProps<typeof chipVariants> {}\n\nconst Chip = ({ className, variant, size, ...props }: ChipProps) => (\n <div className={twMerge(chipVariants({ variant, size, className }))} {...props} />\n)\n\nconst chipVariants = cva(['flex', 'items-center', 'rounded-3xl', 'border', 'w-fit'], {\n variants: {\n variant: {\n neutral: ['text-grey-80', 'border-grey-10'],\n primary: ['text-purple-100', 'border-purple-20'],\n danger: ['text-pumpkin-100', 'border-pumpkin-20'],\n jobLocation: ['text-grey-80', 'border-grey-10', 'bg-grey-5'],\n onboarding: ['text-green-100', 'bg-green-10', 'cursor-pointer'],\n onboardingSelected: ['text-white', 'bg-green-90', 'cursor-pointer'],\n },\n size: {\n small: ['text-sm', 'leading-5', 'px-2', 'py-1', 'gap-1.5'],\n medium: ['text-base', 'leading-6', 'px-3', 'py-2', 'gap-2'],\n },\n },\n defaultVariants: {\n variant: 'neutral',\n size: 'medium',\n },\n})\n\nexport default Chip\n","import { type z } from 'zod'\n\nimport { type JobPostModel } from '@/types/data/job_posting_service_latest'\nimport { type PostalAddressModel } from '@/types/data/shared_pickle_output_latest'\nimport { type jobPostSchema } from '@/types/latest/job_posting_service_latest'\n\ntype JobPost = z.infer<typeof jobPostSchema>\n\nexport function formattedAddress(\n address: PostalAddressModel | undefined,\n isRemote: boolean = false\n): string | null {\n if (!address) return null\n const { addressLocality, addressRegion, addressCountry } = address\n const remoteMessage = isRemote ? ' | Remote' : ''\n if (addressLocality && addressRegion)\n return `${addressLocality}, ${addressRegion + remoteMessage}`\n if (addressRegion && addressCountry) return `${addressRegion}, ${addressCountry + remoteMessage}`\n if (addressRegion) return `${addressRegion + remoteMessage}`\n if (addressCountry) return `${addressCountry + remoteMessage}`\n return null\n}\n\nexport function getAddressList(jobPost: JobPost): string[] {\n const locations: string[] = []\n if (jobPost.jobLocation) {\n const address = formattedAddress(jobPost.jobLocation, jobPost.isRemote)\n if (address) locations.push(address)\n }\n if (jobPost.applicableOffices && jobPost.applicableOffices.length > 0) {\n jobPost.applicableOffices.map((office) => {\n const address = formattedAddress(office?.geoLocation?.address, jobPost.isRemote)\n if (address && !locations.includes(address)) locations.push(address)\n })\n }\n if (jobPost.applicantLocationRequirements && jobPost.applicantLocationRequirements.length > 0) {\n jobPost.applicantLocationRequirements.map((place) => {\n const address = formattedAddress(place?.address, jobPost.isRemote)\n if (address && !locations.includes(address)) locations.push(address)\n })\n }\n return locations\n}\n\nexport function formattedJobLocation(job: JobPostModel) {\n const address = job.jobLocation && formattedAddress(job.jobLocation)\n const remote = job.isRemote ? 'Remote' : ''\n\n return [address, remote].filter(Boolean).join(' | ')\n}\n"],"mappings":"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","names":["twMerge","jsx","jsx"]}
@@ -162,6 +162,7 @@ var import_jsx_runtime2 = require("react/jsx-runtime");
162
162
  function ReadMore({ text, ...props }) {
163
163
  const [isExpanded, setIsExpanded] = (0, import_react2.useState)(false);
164
164
  const [maxWords, setMaxWords] = (0, import_react2.useState)(160);
165
+ const isOverMaxWords = text.split(" ").length > maxWords;
165
166
  (0, import_react2.useEffect)(() => {
166
167
  const updateMaxWords = () => {
167
168
  const windowWidth = window.innerWidth;
@@ -176,6 +177,7 @@ function ReadMore({ text, ...props }) {
176
177
  return () => window.removeEventListener("resize", updateMaxWords);
177
178
  }, []);
178
179
  function createReadMoreText(text2, maxWords2, isExpanded2) {
180
+ if (!isOverMaxWords) return text2;
179
181
  const words = text2.split(" ");
180
182
  const snippet2 = isExpanded2 ? text2 : words.slice(0, maxWords2).join(" ");
181
183
  const readMoreText = isExpanded2 ? "" : "...";
@@ -185,7 +187,7 @@ function ReadMore({ text, ...props }) {
185
187
  const snippet = createReadMoreText(text, maxWords, isExpanded);
186
188
  return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { ...props, children: [
187
189
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { "data-testid": "read-more-text", className: "prose lg:prose-lg", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_react_markdown.default, { children: snippet }) }),
188
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
190
+ isOverMaxWords && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
189
191
  Button,
190
192
  {
191
193
  type: "button",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/jobPost/JobDescription.tsx","../../../src/components/ui/ReadMore.tsx","../../../src/components/ui/Button.tsx","../../../src/lib/utils.ts"],"sourcesContent":["import { ReadMore } from '@/components/ui/ReadMore'\n\nexport type JobDescriptionProps = {\n description?: string\n}\n\nexport function JobDescription({ description }: JobDescriptionProps) {\n if (!description) return null\n\n return (\n <div className=\"flex w-full flex-col gap-2\">\n <h3 className=\"text-xl font-bold\">Job Description</h3>\n <ReadMore text={description} />\n </div>\n )\n}\n","'use client'\n\nimport { type ComponentProps, useEffect, useState } from 'react'\nimport Markdown from 'react-markdown'\n\nimport { Button } from '@/components/ui/Button'\n\nexport type ReadMoreProps = ComponentProps<'div'> & {\n text: string\n}\n\nexport function ReadMore({ text, ...props }: Readonly<ReadMoreProps>) {\n const [isExpanded, setIsExpanded] = useState(false)\n const [maxWords, setMaxWords] = useState(160)\n\n useEffect(() => {\n const updateMaxWords = () => {\n const windowWidth = window.innerWidth\n if (windowWidth <= 768) {\n setMaxWords(50)\n } else {\n setMaxWords(160)\n }\n }\n\n updateMaxWords()\n window.addEventListener('resize', updateMaxWords)\n\n return () => window.removeEventListener('resize', updateMaxWords)\n }, [])\n\n function createReadMoreText(text: string, maxWords: number, isExpanded: boolean): string {\n const words = text.split(' ')\n\n const snippet = isExpanded ? text : words.slice(0, maxWords).join(' ')\n const readMoreText = isExpanded ? '' : '...'\n return `${snippet} ${readMoreText}`\n }\n\n const toggleText = () => setIsExpanded(!isExpanded)\n\n const snippet = createReadMoreText(text, maxWords, isExpanded)\n\n return (\n <div {...props}>\n <div data-testid=\"read-more-text\" className=\"prose lg:prose-lg\">\n <Markdown>{snippet}</Markdown>\n </div>\n <Button\n type=\"button\"\n className=\"mt-2 flex items-center justify-center\"\n variant=\"link\"\n onClick={toggleText}\n >\n <p className=\"text-sm font-bold underline underline-offset-2\">\n Read {isExpanded ? 'less' : 'more'}\n </p>\n </Button>\n </div>\n )\n}\n","import { Slot } from '@radix-ui/react-slot'\nimport { cva, type VariantProps } from 'cva'\nimport React, { forwardRef } from 'react'\n\nimport { cn } from '@/lib/utils'\n\n/**\n * Props for the Button component.\n * @interface ButtonProps\n * @extends {React.ButtonHTMLAttributes<HTMLButtonElement>}\n * @extends {VariantProps<typeof buttonVariants>}\n */\ninterface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n /**\n * When true, the component will render its children directly without wrapping them in a button element.\n * Useful when you want to use the button styles on a different element.\n * @default false\n */\n asChild?: boolean\n}\n\n/**\n * A versatile button component that supports multiple variants and sizes.\n *\n * @component\n * @example\n * ```tsx\n * // Default button\n * <Button>Click me</Button>\n *\n * // Primary variant with large size\n * <Button variant=\"primary\" size=\"lg\">Large Button</Button>\n *\n * // As a link\n * <Button asChild>\n * <a href=\"/somewhere\">Go somewhere</a>\n * </Button>\n * ```\n */\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, type = 'button', ...props }, ref) => {\n const Component = asChild ? Slot : 'button'\n\n return (\n <Component\n className={cn(buttonVariants({ variant, size, className }))}\n type={type}\n ref={ref}\n {...props}\n />\n )\n }\n)\nButton.displayName = 'Button'\n\n/**\n * Variant definitions for the Button component using class-variance-authority.\n * Provides consistent styling across different button variations.\n */\nexport const buttonVariants = cva(\n [\n 'flex',\n 'items-center',\n 'justify-center',\n 'gap-2',\n 'rounded-full',\n 'font-bold',\n 'outline-2',\n 'outline-offset-2',\n 'outline-dashed',\n 'outline-transparent',\n ],\n {\n variants: {\n variant: {\n neutral: [\n 'bg-black',\n 'text-white',\n 'hover:bg-grey-90',\n 'active:bg-grey-80',\n 'focus:outline-purple-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n primary: [\n 'bg-pickle-100',\n 'text-black',\n 'hover:bg-pickle-80',\n 'active:bg-pickle-60',\n 'focus:outline-purple-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n secondary: [\n 'bg-green-80',\n 'text-white',\n 'hover:bg-green-90',\n 'active:bg-green-100',\n 'focus:outline-pickle-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n transparent: [\n 'text-white',\n 'hover:bg-green-80',\n 'active:bg-green-100',\n 'focus:outline-pickle-100',\n 'disabled:text-grey-40',\n ],\n link: [\n 'leading-tight',\n 'text-black',\n 'underline',\n 'hover:text-purple-100',\n 'focus:text-black',\n 'focus:outline-purple-100',\n 'active:text-purple-80',\n ],\n },\n size: {\n small: ['h-10', 'text-sm', 'px-4', 'py-2'],\n medium: ['h-12', 'text-base', 'px-6', 'py-3'],\n large: ['h-14', 'text-lg', 'px-8', 'py-4'],\n },\n },\n defaultVariants: {\n variant: 'neutral',\n size: 'medium',\n },\n compoundVariants: [\n {\n variant: 'link',\n size: 'small',\n class: ['h-3', 'text-xs', 'p-0'],\n },\n {\n variant: 'link',\n size: 'medium',\n class: ['h-4', 'text-sm', 'p-0'],\n },\n {\n variant: 'link',\n size: 'large',\n class: ['h-6', 'text-base', 'p-0'],\n },\n ],\n }\n)\n","import { type ClassValue, clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n"],"mappings":"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","names":["import_react","import_jsx_runtime","text","maxWords","isExpanded","snippet","Markdown","import_jsx_runtime"]}
1
+ {"version":3,"sources":["../../../src/components/jobPost/JobDescription.tsx","../../../src/components/ui/ReadMore.tsx","../../../src/components/ui/Button.tsx","../../../src/lib/utils.ts"],"sourcesContent":["import { ReadMore } from '@/components/ui/ReadMore'\n\nexport type JobDescriptionProps = {\n description?: string\n}\n\nexport function JobDescription({ description }: JobDescriptionProps) {\n if (!description) return null\n\n return (\n <div className=\"flex w-full flex-col gap-2\">\n <h3 className=\"text-xl font-bold\">Job Description</h3>\n <ReadMore text={description} />\n </div>\n )\n}\n","'use client'\n\nimport { type ComponentProps, useEffect, useState } from 'react'\nimport Markdown from 'react-markdown'\n\nimport { Button } from '@/components/ui/Button'\n\nexport type ReadMoreProps = ComponentProps<'div'> & {\n text: string\n}\n\nexport function ReadMore({ text, ...props }: Readonly<ReadMoreProps>) {\n const [isExpanded, setIsExpanded] = useState(false)\n const [maxWords, setMaxWords] = useState(160)\n\n const isOverMaxWords = text.split(' ').length > maxWords\n\n useEffect(() => {\n const updateMaxWords = () => {\n const windowWidth = window.innerWidth\n if (windowWidth <= 768) {\n setMaxWords(50)\n } else {\n setMaxWords(160)\n }\n }\n\n updateMaxWords()\n window.addEventListener('resize', updateMaxWords)\n\n return () => window.removeEventListener('resize', updateMaxWords)\n }, [])\n\n function createReadMoreText(text: string, maxWords: number, isExpanded: boolean): string {\n if (!isOverMaxWords) return text\n\n const words = text.split(' ')\n const snippet = isExpanded ? text : words.slice(0, maxWords).join(' ')\n const readMoreText = isExpanded ? '' : '...'\n return `${snippet} ${readMoreText}`\n }\n\n const toggleText = () => setIsExpanded(!isExpanded)\n\n const snippet = createReadMoreText(text, maxWords, isExpanded)\n\n return (\n <div {...props}>\n <div data-testid=\"read-more-text\" className=\"prose lg:prose-lg\">\n <Markdown>{snippet}</Markdown>\n </div>\n {isOverMaxWords && (\n <Button\n type=\"button\"\n className=\"mt-2 flex items-center justify-center\"\n variant=\"link\"\n onClick={toggleText}\n >\n <p className=\"text-sm font-bold underline underline-offset-2\">\n Read {isExpanded ? 'less' : 'more'}\n </p>\n </Button>\n )}\n </div>\n )\n}\n","import { Slot } from '@radix-ui/react-slot'\nimport { cva, type VariantProps } from 'cva'\nimport React, { forwardRef } from 'react'\n\nimport { cn } from '@/lib/utils'\n\n/**\n * Props for the Button component.\n * @interface ButtonProps\n * @extends {React.ButtonHTMLAttributes<HTMLButtonElement>}\n * @extends {VariantProps<typeof buttonVariants>}\n */\ninterface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n /**\n * When true, the component will render its children directly without wrapping them in a button element.\n * Useful when you want to use the button styles on a different element.\n * @default false\n */\n asChild?: boolean\n}\n\n/**\n * A versatile button component that supports multiple variants and sizes.\n *\n * @component\n * @example\n * ```tsx\n * // Default button\n * <Button>Click me</Button>\n *\n * // Primary variant with large size\n * <Button variant=\"primary\" size=\"lg\">Large Button</Button>\n *\n * // As a link\n * <Button asChild>\n * <a href=\"/somewhere\">Go somewhere</a>\n * </Button>\n * ```\n */\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, type = 'button', ...props }, ref) => {\n const Component = asChild ? Slot : 'button'\n\n return (\n <Component\n className={cn(buttonVariants({ variant, size, className }))}\n type={type}\n ref={ref}\n {...props}\n />\n )\n }\n)\nButton.displayName = 'Button'\n\n/**\n * Variant definitions for the Button component using class-variance-authority.\n * Provides consistent styling across different button variations.\n */\nexport const buttonVariants = cva(\n [\n 'flex',\n 'items-center',\n 'justify-center',\n 'gap-2',\n 'rounded-full',\n 'font-bold',\n 'outline-2',\n 'outline-offset-2',\n 'outline-dashed',\n 'outline-transparent',\n ],\n {\n variants: {\n variant: {\n neutral: [\n 'bg-black',\n 'text-white',\n 'hover:bg-grey-90',\n 'active:bg-grey-80',\n 'focus:outline-purple-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n primary: [\n 'bg-pickle-100',\n 'text-black',\n 'hover:bg-pickle-80',\n 'active:bg-pickle-60',\n 'focus:outline-purple-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n secondary: [\n 'bg-green-80',\n 'text-white',\n 'hover:bg-green-90',\n 'active:bg-green-100',\n 'focus:outline-pickle-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n transparent: [\n 'text-white',\n 'hover:bg-green-80',\n 'active:bg-green-100',\n 'focus:outline-pickle-100',\n 'disabled:text-grey-40',\n ],\n link: [\n 'leading-tight',\n 'text-black',\n 'underline',\n 'hover:text-purple-100',\n 'focus:text-black',\n 'focus:outline-purple-100',\n 'active:text-purple-80',\n ],\n },\n size: {\n small: ['h-10', 'text-sm', 'px-4', 'py-2'],\n medium: ['h-12', 'text-base', 'px-6', 'py-3'],\n large: ['h-14', 'text-lg', 'px-8', 'py-4'],\n },\n },\n defaultVariants: {\n variant: 'neutral',\n size: 'medium',\n },\n compoundVariants: [\n {\n variant: 'link',\n size: 'small',\n class: ['h-3', 'text-xs', 'p-0'],\n },\n {\n variant: 'link',\n size: 'medium',\n class: ['h-4', 'text-sm', 'p-0'],\n },\n {\n variant: 'link',\n size: 'large',\n class: ['h-6', 'text-base', 'p-0'],\n },\n ],\n }\n)\n","import { type ClassValue, clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n"],"mappings":"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","names":["import_react","import_jsx_runtime","text","maxWords","isExpanded","snippet","Markdown","import_jsx_runtime"]}
@@ -126,6 +126,7 @@ import { jsx as jsx2, jsxs } from "react/jsx-runtime";
126
126
  function ReadMore({ text, ...props }) {
127
127
  const [isExpanded, setIsExpanded] = useState(false);
128
128
  const [maxWords, setMaxWords] = useState(160);
129
+ const isOverMaxWords = text.split(" ").length > maxWords;
129
130
  useEffect(() => {
130
131
  const updateMaxWords = () => {
131
132
  const windowWidth = window.innerWidth;
@@ -140,6 +141,7 @@ function ReadMore({ text, ...props }) {
140
141
  return () => window.removeEventListener("resize", updateMaxWords);
141
142
  }, []);
142
143
  function createReadMoreText(text2, maxWords2, isExpanded2) {
144
+ if (!isOverMaxWords) return text2;
143
145
  const words = text2.split(" ");
144
146
  const snippet2 = isExpanded2 ? text2 : words.slice(0, maxWords2).join(" ");
145
147
  const readMoreText = isExpanded2 ? "" : "...";
@@ -149,7 +151,7 @@ function ReadMore({ text, ...props }) {
149
151
  const snippet = createReadMoreText(text, maxWords, isExpanded);
150
152
  return /* @__PURE__ */ jsxs("div", { ...props, children: [
151
153
  /* @__PURE__ */ jsx2("div", { "data-testid": "read-more-text", className: "prose lg:prose-lg", children: /* @__PURE__ */ jsx2(Markdown, { children: snippet }) }),
152
- /* @__PURE__ */ jsx2(
154
+ isOverMaxWords && /* @__PURE__ */ jsx2(
153
155
  Button,
154
156
  {
155
157
  type: "button",
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/components/ui/ReadMore.tsx","../../../src/components/ui/Button.tsx","../../../src/lib/utils.ts","../../../src/components/jobPost/JobDescription.tsx"],"sourcesContent":["'use client'\n\nimport { type ComponentProps, useEffect, useState } from 'react'\nimport Markdown from 'react-markdown'\n\nimport { Button } from '@/components/ui/Button'\n\nexport type ReadMoreProps = ComponentProps<'div'> & {\n text: string\n}\n\nexport function ReadMore({ text, ...props }: Readonly<ReadMoreProps>) {\n const [isExpanded, setIsExpanded] = useState(false)\n const [maxWords, setMaxWords] = useState(160)\n\n useEffect(() => {\n const updateMaxWords = () => {\n const windowWidth = window.innerWidth\n if (windowWidth <= 768) {\n setMaxWords(50)\n } else {\n setMaxWords(160)\n }\n }\n\n updateMaxWords()\n window.addEventListener('resize', updateMaxWords)\n\n return () => window.removeEventListener('resize', updateMaxWords)\n }, [])\n\n function createReadMoreText(text: string, maxWords: number, isExpanded: boolean): string {\n const words = text.split(' ')\n\n const snippet = isExpanded ? text : words.slice(0, maxWords).join(' ')\n const readMoreText = isExpanded ? '' : '...'\n return `${snippet} ${readMoreText}`\n }\n\n const toggleText = () => setIsExpanded(!isExpanded)\n\n const snippet = createReadMoreText(text, maxWords, isExpanded)\n\n return (\n <div {...props}>\n <div data-testid=\"read-more-text\" className=\"prose lg:prose-lg\">\n <Markdown>{snippet}</Markdown>\n </div>\n <Button\n type=\"button\"\n className=\"mt-2 flex items-center justify-center\"\n variant=\"link\"\n onClick={toggleText}\n >\n <p className=\"text-sm font-bold underline underline-offset-2\">\n Read {isExpanded ? 'less' : 'more'}\n </p>\n </Button>\n </div>\n )\n}\n","import { Slot } from '@radix-ui/react-slot'\nimport { cva, type VariantProps } from 'cva'\nimport React, { forwardRef } from 'react'\n\nimport { cn } from '@/lib/utils'\n\n/**\n * Props for the Button component.\n * @interface ButtonProps\n * @extends {React.ButtonHTMLAttributes<HTMLButtonElement>}\n * @extends {VariantProps<typeof buttonVariants>}\n */\ninterface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n /**\n * When true, the component will render its children directly without wrapping them in a button element.\n * Useful when you want to use the button styles on a different element.\n * @default false\n */\n asChild?: boolean\n}\n\n/**\n * A versatile button component that supports multiple variants and sizes.\n *\n * @component\n * @example\n * ```tsx\n * // Default button\n * <Button>Click me</Button>\n *\n * // Primary variant with large size\n * <Button variant=\"primary\" size=\"lg\">Large Button</Button>\n *\n * // As a link\n * <Button asChild>\n * <a href=\"/somewhere\">Go somewhere</a>\n * </Button>\n * ```\n */\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, type = 'button', ...props }, ref) => {\n const Component = asChild ? Slot : 'button'\n\n return (\n <Component\n className={cn(buttonVariants({ variant, size, className }))}\n type={type}\n ref={ref}\n {...props}\n />\n )\n }\n)\nButton.displayName = 'Button'\n\n/**\n * Variant definitions for the Button component using class-variance-authority.\n * Provides consistent styling across different button variations.\n */\nexport const buttonVariants = cva(\n [\n 'flex',\n 'items-center',\n 'justify-center',\n 'gap-2',\n 'rounded-full',\n 'font-bold',\n 'outline-2',\n 'outline-offset-2',\n 'outline-dashed',\n 'outline-transparent',\n ],\n {\n variants: {\n variant: {\n neutral: [\n 'bg-black',\n 'text-white',\n 'hover:bg-grey-90',\n 'active:bg-grey-80',\n 'focus:outline-purple-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n primary: [\n 'bg-pickle-100',\n 'text-black',\n 'hover:bg-pickle-80',\n 'active:bg-pickle-60',\n 'focus:outline-purple-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n secondary: [\n 'bg-green-80',\n 'text-white',\n 'hover:bg-green-90',\n 'active:bg-green-100',\n 'focus:outline-pickle-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n transparent: [\n 'text-white',\n 'hover:bg-green-80',\n 'active:bg-green-100',\n 'focus:outline-pickle-100',\n 'disabled:text-grey-40',\n ],\n link: [\n 'leading-tight',\n 'text-black',\n 'underline',\n 'hover:text-purple-100',\n 'focus:text-black',\n 'focus:outline-purple-100',\n 'active:text-purple-80',\n ],\n },\n size: {\n small: ['h-10', 'text-sm', 'px-4', 'py-2'],\n medium: ['h-12', 'text-base', 'px-6', 'py-3'],\n large: ['h-14', 'text-lg', 'px-8', 'py-4'],\n },\n },\n defaultVariants: {\n variant: 'neutral',\n size: 'medium',\n },\n compoundVariants: [\n {\n variant: 'link',\n size: 'small',\n class: ['h-3', 'text-xs', 'p-0'],\n },\n {\n variant: 'link',\n size: 'medium',\n class: ['h-4', 'text-sm', 'p-0'],\n },\n {\n variant: 'link',\n size: 'large',\n class: ['h-6', 'text-base', 'p-0'],\n },\n ],\n }\n)\n","import { type ClassValue, clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","import { ReadMore } from '@/components/ui/ReadMore'\n\nexport type JobDescriptionProps = {\n description?: string\n}\n\nexport function JobDescription({ description }: JobDescriptionProps) {\n if (!description) return null\n\n return (\n <div className=\"flex w-full flex-col gap-2\">\n <h3 className=\"text-xl font-bold\">Job Description</h3>\n <ReadMore text={description} />\n </div>\n )\n}\n"],"mappings":"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","names":["jsx","text","maxWords","isExpanded","snippet","jsx","jsxs"]}
1
+ {"version":3,"sources":["../../../src/components/ui/ReadMore.tsx","../../../src/components/ui/Button.tsx","../../../src/lib/utils.ts","../../../src/components/jobPost/JobDescription.tsx"],"sourcesContent":["'use client'\n\nimport { type ComponentProps, useEffect, useState } from 'react'\nimport Markdown from 'react-markdown'\n\nimport { Button } from '@/components/ui/Button'\n\nexport type ReadMoreProps = ComponentProps<'div'> & {\n text: string\n}\n\nexport function ReadMore({ text, ...props }: Readonly<ReadMoreProps>) {\n const [isExpanded, setIsExpanded] = useState(false)\n const [maxWords, setMaxWords] = useState(160)\n\n const isOverMaxWords = text.split(' ').length > maxWords\n\n useEffect(() => {\n const updateMaxWords = () => {\n const windowWidth = window.innerWidth\n if (windowWidth <= 768) {\n setMaxWords(50)\n } else {\n setMaxWords(160)\n }\n }\n\n updateMaxWords()\n window.addEventListener('resize', updateMaxWords)\n\n return () => window.removeEventListener('resize', updateMaxWords)\n }, [])\n\n function createReadMoreText(text: string, maxWords: number, isExpanded: boolean): string {\n if (!isOverMaxWords) return text\n\n const words = text.split(' ')\n const snippet = isExpanded ? text : words.slice(0, maxWords).join(' ')\n const readMoreText = isExpanded ? '' : '...'\n return `${snippet} ${readMoreText}`\n }\n\n const toggleText = () => setIsExpanded(!isExpanded)\n\n const snippet = createReadMoreText(text, maxWords, isExpanded)\n\n return (\n <div {...props}>\n <div data-testid=\"read-more-text\" className=\"prose lg:prose-lg\">\n <Markdown>{snippet}</Markdown>\n </div>\n {isOverMaxWords && (\n <Button\n type=\"button\"\n className=\"mt-2 flex items-center justify-center\"\n variant=\"link\"\n onClick={toggleText}\n >\n <p className=\"text-sm font-bold underline underline-offset-2\">\n Read {isExpanded ? 'less' : 'more'}\n </p>\n </Button>\n )}\n </div>\n )\n}\n","import { Slot } from '@radix-ui/react-slot'\nimport { cva, type VariantProps } from 'cva'\nimport React, { forwardRef } from 'react'\n\nimport { cn } from '@/lib/utils'\n\n/**\n * Props for the Button component.\n * @interface ButtonProps\n * @extends {React.ButtonHTMLAttributes<HTMLButtonElement>}\n * @extends {VariantProps<typeof buttonVariants>}\n */\ninterface ButtonProps\n extends React.ButtonHTMLAttributes<HTMLButtonElement>,\n VariantProps<typeof buttonVariants> {\n /**\n * When true, the component will render its children directly without wrapping them in a button element.\n * Useful when you want to use the button styles on a different element.\n * @default false\n */\n asChild?: boolean\n}\n\n/**\n * A versatile button component that supports multiple variants and sizes.\n *\n * @component\n * @example\n * ```tsx\n * // Default button\n * <Button>Click me</Button>\n *\n * // Primary variant with large size\n * <Button variant=\"primary\" size=\"lg\">Large Button</Button>\n *\n * // As a link\n * <Button asChild>\n * <a href=\"/somewhere\">Go somewhere</a>\n * </Button>\n * ```\n */\nexport const Button = forwardRef<HTMLButtonElement, ButtonProps>(\n ({ className, variant, size, asChild = false, type = 'button', ...props }, ref) => {\n const Component = asChild ? Slot : 'button'\n\n return (\n <Component\n className={cn(buttonVariants({ variant, size, className }))}\n type={type}\n ref={ref}\n {...props}\n />\n )\n }\n)\nButton.displayName = 'Button'\n\n/**\n * Variant definitions for the Button component using class-variance-authority.\n * Provides consistent styling across different button variations.\n */\nexport const buttonVariants = cva(\n [\n 'flex',\n 'items-center',\n 'justify-center',\n 'gap-2',\n 'rounded-full',\n 'font-bold',\n 'outline-2',\n 'outline-offset-2',\n 'outline-dashed',\n 'outline-transparent',\n ],\n {\n variants: {\n variant: {\n neutral: [\n 'bg-black',\n 'text-white',\n 'hover:bg-grey-90',\n 'active:bg-grey-80',\n 'focus:outline-purple-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n primary: [\n 'bg-pickle-100',\n 'text-black',\n 'hover:bg-pickle-80',\n 'active:bg-pickle-60',\n 'focus:outline-purple-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n secondary: [\n 'bg-green-80',\n 'text-white',\n 'hover:bg-green-90',\n 'active:bg-green-100',\n 'focus:outline-pickle-100',\n 'disabled:text-grey-40',\n 'disabled:bg-grey-10',\n ],\n transparent: [\n 'text-white',\n 'hover:bg-green-80',\n 'active:bg-green-100',\n 'focus:outline-pickle-100',\n 'disabled:text-grey-40',\n ],\n link: [\n 'leading-tight',\n 'text-black',\n 'underline',\n 'hover:text-purple-100',\n 'focus:text-black',\n 'focus:outline-purple-100',\n 'active:text-purple-80',\n ],\n },\n size: {\n small: ['h-10', 'text-sm', 'px-4', 'py-2'],\n medium: ['h-12', 'text-base', 'px-6', 'py-3'],\n large: ['h-14', 'text-lg', 'px-8', 'py-4'],\n },\n },\n defaultVariants: {\n variant: 'neutral',\n size: 'medium',\n },\n compoundVariants: [\n {\n variant: 'link',\n size: 'small',\n class: ['h-3', 'text-xs', 'p-0'],\n },\n {\n variant: 'link',\n size: 'medium',\n class: ['h-4', 'text-sm', 'p-0'],\n },\n {\n variant: 'link',\n size: 'large',\n class: ['h-6', 'text-base', 'p-0'],\n },\n ],\n }\n)\n","import { type ClassValue, clsx } from 'clsx'\nimport { twMerge } from 'tailwind-merge'\n\nexport function cn(...inputs: ClassValue[]) {\n return twMerge(clsx(inputs))\n}\n","import { ReadMore } from '@/components/ui/ReadMore'\n\nexport type JobDescriptionProps = {\n description?: string\n}\n\nexport function JobDescription({ description }: JobDescriptionProps) {\n if (!description) return null\n\n return (\n <div className=\"flex w-full flex-col gap-2\">\n <h3 className=\"text-xl font-bold\">Job Description</h3>\n <ReadMore text={description} />\n </div>\n )\n}\n"],"mappings":"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","names":["jsx","text","maxWords","isExpanded","snippet","jsx","jsxs"]}
@@ -249,6 +249,7 @@ var chipVariants = (0, import_cva3.cva)(["flex", "items-center", "rounded-3xl",
249
249
  neutral: ["text-grey-80", "border-grey-10"],
250
250
  primary: ["text-purple-100", "border-purple-20"],
251
251
  danger: ["text-pumpkin-100", "border-pumpkin-20"],
252
+ jobLocation: ["text-grey-80", "border-grey-10", "bg-grey-5"],
252
253
  onboarding: ["text-green-100", "bg-green-10", "cursor-pointer"],
253
254
  onboardingSelected: ["text-white", "bg-green-90", "cursor-pointer"]
254
255
  },