Skip to content

Commit 23df82e

Browse files
authored
feat: job edit (#4907)
1 parent 1a4b733 commit 23df82e

20 files changed

Lines changed: 1319 additions & 200 deletions

File tree

packages/shared/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@
102102
"dependencies": {
103103
"@growthbook/growthbook": "https://gitpkg.now.sh/dailydotdev/growthbook/packages/sdk-js?e354fcf41b2b3f67590294a0e2cdfb56044d7a1e",
104104
"@growthbook/growthbook-react": "^0.17.0",
105+
"@hookform/resolvers": "5.2.2",
105106
"@kickass-coderz/react": "^0.0.4",
106107
"@marsidev/react-turnstile": "^1.1.0",
107108
"@paddle/paddle-js": "1.4.0",
@@ -118,6 +119,7 @@
118119
"lottie-react": "^2.4.1",
119120
"node-fetch": "^2.6.6",
120121
"parsecurrency": "^1.1.1",
122+
"react-hook-form": "7.54.2",
121123
"react-markdown": "^8.0.7",
122124
"react-onesignal": "^3.0.1",
123125
"react-syntax-highlighter": "^15.5.0",
@@ -126,7 +128,8 @@
126128
"tippy.js": "^6.3.7",
127129
"uuid": "^8.3.2",
128130
"web-vitals": "^3.5.0",
129-
"webextension-polyfill": "^0.12.0"
131+
"webextension-polyfill": "^0.12.0",
132+
"zod": "4.1.8"
130133
},
131134
"sideEffects": [
132135
"*.css"

packages/shared/src/components/accordion/index.tsx

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ interface AccordionProps {
1212
className?: {
1313
button?: string;
1414
};
15+
disabled?: boolean;
1516
}
1617

1718
export function Accordion({
@@ -20,12 +21,19 @@ export function Accordion({
2021
onClick,
2122
initiallyOpen = false,
2223
className,
24+
disabled = false,
2325
}: AccordionProps): ReactElement {
2426
const [isOpen, setIsOpen] = useState(initiallyOpen);
2527
const id = useId();
2628
const contentId = `accordion-content-${id}`;
2729

30+
const isOpenAndEnabled = isOpen && !disabled;
31+
2832
const handleClick: MouseEventHandler<HTMLButtonElement> = (e) => {
33+
if (disabled) {
34+
return;
35+
}
36+
2937
onClick?.(e);
3038

3139
setIsOpen((prev) => !prev);
@@ -35,9 +43,10 @@ export function Accordion({
3543
<div className="flex w-full flex-col">
3644
<Button
3745
aria-controls={contentId}
38-
aria-expanded={isOpen}
46+
aria-expanded={isOpenAndEnabled}
3947
className={classNames(
4048
'flex w-full flex-row gap-4 !px-0 text-left',
49+
disabled && '!cursor-default',
4150
className?.button,
4251
)}
4352
type="button"
@@ -46,22 +55,24 @@ export function Accordion({
4655
<div className="min-w-0 flex-1">{title}</div>
4756
<ArrowIcon
4857
className={classNames('transition-transform ease-in-out', {
49-
'rotate-180': !isOpen,
58+
'rotate-180': !isOpenAndEnabled,
5059
})}
5160
/>
5261
</Button>
5362
<div
54-
aria-hidden={!isOpen}
63+
aria-hidden={!isOpenAndEnabled}
5564
className={classNames(
5665
'flex h-full min-h-0 w-full flex-col overflow-y-hidden break-words transition-[max-height,margin] duration-300 ease-in-out',
57-
isOpen ? 'mt-3 max-h-full' : 'max-h-0',
66+
isOpenAndEnabled ? 'mt-3 max-h-full' : 'max-h-0',
5867
)}
5968
id={contentId}
6069
>
6170
<div
6271
className={classNames(
6372
'transition-transform duration-150 ease-in-out',
64-
isOpen ? 'translate-y-0 opacity-100' : '-translate-y-2 opacity-0',
73+
isOpenAndEnabled
74+
? 'translate-y-0 opacity-100'
75+
: '-translate-y-2 opacity-0',
6576
)}
6677
>
6778
{children}

packages/shared/src/components/fields/Textarea.tsx

Lines changed: 38 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import classNames from 'classnames';
2-
import type { ReactElement } from 'react';
3-
import React from 'react';
2+
import React, { forwardRef } from 'react';
3+
import type { ForwardedRef, ReactElement } from 'react';
44
import styles from './TextField.module.css';
55
import useInputFieldFunctions from '../../hooks/useInputFieldFunctions';
66
import type { BaseFieldProps, FieldClassName } from './BaseFieldContainer';
@@ -10,28 +10,31 @@ import BaseFieldContainer, {
1010
InnerLabel,
1111
} from './BaseFieldContainer';
1212

13-
function Textarea({
14-
hint,
15-
inputId,
16-
saveHintSpace,
17-
label,
18-
value,
19-
valueChanged,
20-
valid,
21-
validityChanged,
22-
className = {},
23-
placeholder,
24-
readOnly,
25-
isLocked,
26-
disabled,
27-
name,
28-
maxLength = 100,
29-
rows,
30-
fieldType = 'primary',
31-
...props
32-
}: BaseFieldProps<HTMLTextAreaElement> & {
33-
className?: FieldClassName;
34-
}): ReactElement {
13+
function Textarea(
14+
{
15+
hint,
16+
inputId,
17+
saveHintSpace,
18+
label,
19+
value,
20+
valueChanged,
21+
valid,
22+
validityChanged,
23+
className = {},
24+
placeholder,
25+
readOnly,
26+
isLocked,
27+
disabled,
28+
name,
29+
maxLength = 100,
30+
rows,
31+
fieldType = 'primary',
32+
...props
33+
}: BaseFieldProps<HTMLTextAreaElement> & {
34+
className?: FieldClassName;
35+
},
36+
ref: ForwardedRef<HTMLTextAreaElement>,
37+
): ReactElement {
3538
const {
3639
validInput,
3740
focused,
@@ -103,7 +106,16 @@ function Textarea({
103106
})}
104107
name={name}
105108
id={inputId}
106-
ref={inputRef}
109+
ref={(element) => {
110+
inputRef.current = element;
111+
112+
if (typeof ref === 'function') {
113+
ref(element);
114+
} else if (ref) {
115+
// eslint-disable-next-line no-param-reassign
116+
ref.current = element;
117+
}
118+
}}
107119
onFocus={onFocus}
108120
onBlur={onBlur}
109121
onInput={onInput}
@@ -129,4 +141,4 @@ function Textarea({
129141
);
130142
}
131143

132-
export default Textarea;
144+
export default forwardRef(Textarea);

packages/shared/src/components/modals/common.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -328,6 +328,12 @@ const SquadNotificationSettingsModal = dynamic(
328328
),
329329
);
330330

331+
const OpportunityEditModal = dynamic(() =>
332+
import(
333+
/* webpackChunkName: "opportunityEditModal" */ '../opportunity/OpportunityEditModal/OpportunityEditModal'
334+
).then((mod) => mod.OpportunityEditModal),
335+
);
336+
331337
export const modals = {
332338
[LazyModal.SquadMember]: SquadMemberModal,
333339
[LazyModal.UpvotedPopup]: UpvotedPopupModal,
@@ -382,6 +388,7 @@ export const modals = {
382388
[LazyModal.OrganizationManageSeats]: OrganizationManageSeatsModal,
383389
[LazyModal.ActionSuccess]: ActionSuccessModal,
384390
[LazyModal.SquadNotificationSettings]: SquadNotificationSettingsModal,
391+
[LazyModal.OpportunityEdit]: OpportunityEditModal,
385392
};
386393

387394
type GetComponentProps<T> = T extends

packages/shared/src/components/modals/common/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ export enum LazyModal {
7878
OrganizationManageSeats = 'organizationManageSeats',
7979
ActionSuccess = 'actionSuccess',
8080
SquadNotificationSettings = 'squadNotificationSettings',
81+
OpportunityEdit = 'opportunityEdit',
8182
}
8283

8384
export type ModalTabItem = {
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import React from 'react';
2+
import classNames from 'classnames';
3+
import type { AllowedTags, ButtonProps } from '../buttons/Button';
4+
import {
5+
Button,
6+
ButtonIconPosition,
7+
ButtonSize,
8+
ButtonVariant,
9+
} from '../buttons/Button';
10+
import { EditIcon } from '../icons';
11+
import { useOpportunityEditContext } from './OpportunityEditContext';
12+
13+
export type OpportunityEditButtonProps = {
14+
className?: string;
15+
children?: React.ReactNode;
16+
} & ButtonProps<AllowedTags>;
17+
18+
export const OpportunityEditButton = ({
19+
className,
20+
children = 'Edit',
21+
icon = <EditIcon />,
22+
iconPosition = ButtonIconPosition.Left,
23+
variant = ButtonVariant.Float,
24+
size = ButtonSize.Small,
25+
...rest
26+
}: OpportunityEditButtonProps) => {
27+
const { canEdit } = useOpportunityEditContext();
28+
29+
if (!canEdit) {
30+
return null;
31+
}
32+
33+
return (
34+
<Button
35+
className={classNames('z-tooltip', className)}
36+
type="button"
37+
{...rest}
38+
icon={icon}
39+
iconPosition={iconPosition}
40+
variant={variant}
41+
size={size}
42+
>
43+
{children}
44+
</Button>
45+
);
46+
};
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { createContextProvider } from '@kickass-coderz/react';
2+
import type { ReactNode } from 'react';
3+
4+
export type OpportunityEditContextProps = {
5+
children: ReactNode;
6+
canEdit: boolean;
7+
};
8+
9+
const [OpportunityEditProvider, useOpportunityEditContext] =
10+
createContextProvider((props: OpportunityEditContextProps) => {
11+
const { canEdit } = props;
12+
13+
return {
14+
canEdit,
15+
};
16+
});
17+
18+
export { OpportunityEditProvider, useOpportunityEditContext };

0 commit comments

Comments
 (0)