Skip to content
Closed
Show file tree
Hide file tree
Changes from 16 commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
f4c8aaf
fix: Added Max size for pdf and allowed file size
yasharyasaxena Jun 19, 2025
fb2d12f
Merge branch 'Web-Team-IITI-Gymkhana:main' into main
yasharyasaxena Jun 19, 2025
b2cf60d
Update JobDetails.tsx
JXP25 Jun 19, 2025
6274cfa
fix: added checks and errors for marks and cpi
yasharyasaxena Jun 19, 2025
f215996
Merge branch 'main' of https://github.com/yasharyasaxena/tpc-frontend
yasharyasaxena Jun 19, 2025
29eb63e
Merge branch 'develop' into main
JXP25 Jun 19, 2025
2f15b7c
Update JobDetails.tsx
yasharyasaxena Jun 19, 2025
e1d978c
fix: added rupee symbol before stipends
yasharyasaxena Jun 20, 2025
858f686
Merge branch 'main' of https://github.com/yasharyasaxena/tpc-frontend
yasharyasaxena Jun 20, 2025
b649827
Merge branch 'develop' into main
yasharyasaxena Jun 20, 2025
24447ae
fix: past dates cant be selected for offer letter and joining date
yasharyasaxena Jun 20, 2025
f3e5f13
Merge branch 'main' of https://github.com/yasharyasaxena/tpc-frontend
yasharyasaxena Jun 20, 2025
ffe8e64
Merge branch 'develop' into main
JXP25 Jun 20, 2025
8373984
feat: Currency dropdown menu with custom currency
yasharyasaxena Jun 22, 2025
c18d369
Merge branch 'main' of https://github.com/yasharyasaxena/tpc-frontend
yasharyasaxena Jun 22, 2025
3222524
Merge branch 'main' of https://github.com/yasharyasaxena/tpc-frontend
yasharyasaxena Jun 22, 2025
5d850b3
fix: All currency selections are in sync (same)
yasharyasaxena Jun 22, 2025
a4bd1dc
Merge branch 'develop' into main
JXP25 Jun 22, 2025
3e1070f
Update JobDetails.tsx
JXP25 Jun 22, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
233 changes: 233 additions & 0 deletions src/components/JAF/CurrencySelect.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,233 @@
import { Button, Form, Input, Select, message } from "antd";
import { FC, useState } from "react";

interface CurrencyOption {
value: string;
label: string;
symbol: string;
}

// Default currencies list
const defaultCurrencies: CurrencyOption[] = [
{ value: "INR", label: "INR", symbol: "₹" },
{ value: "USD", label: "USD", symbol: "$" },
{ value: "EUR", label: "EUR", symbol: "€" },
{ value: "GBP", label: "GBP", symbol: "£" },
{ value: "JPY", label: "JPY", symbol: "¥" },
{ value: "CNY", label: "CNY", symbol: "¥" },
];

interface SalaryField {
stipendCurrency?: string;
customCurrencySymbol?: string;
customCurrencyName?: string;
}

interface CurrencySelectProps {
name: string[];
defaultValue?: string;
style?: React.CSSProperties;
values?: {
salaries?: Record<number, SalaryField>;
};
setFieldValue?: (field: string, value: any) => void;
field?: { name: number };
allowCustom?: boolean;
maxSymbolLength?: number;
maxNameLength?: number;
// Add props for shared custom currencies
customCurrencies: CurrencyOption[];
onAddCustomCurrency: (currency: CurrencyOption) => void;
}

const CurrencySelect: FC<CurrencySelectProps> = (props) => {
const {
name,
defaultValue = "INR",
style = { width: 90 },
values,
setFieldValue,
field,
allowCustom = false,
maxSymbolLength = 3,
maxNameLength = 20,
} = props;
// Combine default and custom currencies
const allCurrencies = [...defaultCurrencies, ...props.customCurrencies];
const currentSalary = field && values?.salaries?.[field.name];

const handleCustomCurrencyChange = (
type: "symbol" | "name",
value: string,
) => {
if (!setFieldValue || !field || !values?.salaries) return;

const updatedSalaries = {
...values.salaries,
[field.name]: {
...values.salaries[field.name],
[type === "symbol" ? "customCurrencySymbol" : "customCurrencyName"]:
value,
},
};
setFieldValue("salaries", updatedSalaries);
};
const setCustomCurrency = () => {
if (
!setFieldValue ||
!field ||
!values?.salaries ||
!currentSalary?.customCurrencySymbol
)
return;

// Create new currency object
const newCurrency: CurrencyOption = {
value: currentSalary.customCurrencySymbol,
label: currentSalary.customCurrencyName || "Custom",
symbol: currentSalary.customCurrencySymbol,
};

// Check if currency already exists
const exists = allCurrencies.some(
(c) => c.value === newCurrency.value || c.symbol === newCurrency.symbol,
);

if (exists) {
message.error("This currency symbol or code already exists");
return;
}

// Add custom currency through the parent callback
props.onAddCustomCurrency(newCurrency);

// Update the form value
const updatedSalaries = {
...values.salaries,
[field.name]: {
...values.salaries[field.name],
stipendCurrency: newCurrency.value,
},
};
setFieldValue("salaries", updatedSalaries);

message.success(
`Added new currency: ${newCurrency.symbol} ${newCurrency.label}`,
);
};
const renderOptions = () => {
return allCurrencies.map((currency) => (
<Select.Option key={currency.value} value={currency.value}>
{`${currency.symbol} ${currency.label}`}
</Select.Option>
));
};

const renderCustomOption = () => {
if (!allowCustom) return null;

const symbol = currentSalary?.customCurrencySymbol;
const name = currentSalary?.customCurrencyName;

return (
<Select.Option value="CUSTOM">
{symbol ? `${symbol} ${name || "Custom"}` : "Custom"}
</Select.Option>
);
};

const renderCustomInput = () => {
if (!allowCustom) return null;

return (
<div
style={{
display: "flex",
alignItems: "center",
padding: 8,
borderTop: "1px solid #f0f0f0",
}}
>
<Form.Item
style={{ flex: 1, marginRight: 8, marginBottom: 0 }}
validateStatus={
currentSalary?.customCurrencySymbol?.length > maxSymbolLength
? "error"
: undefined
}
help={
currentSalary?.customCurrencySymbol?.length > maxSymbolLength
? `Symbol must be ${maxSymbolLength} characters or less`
: undefined
}
>
<Input
placeholder="Symbol"
size="small"
maxLength={maxSymbolLength}
value={currentSalary?.customCurrencySymbol || ""}
onChange={(e) =>
handleCustomCurrencyChange("symbol", e.target.value)
}
/>
</Form.Item>
<Form.Item
style={{ flex: 2, marginRight: 8, marginBottom: 0 }}
validateStatus={
currentSalary?.customCurrencyName?.length > maxNameLength
? "error"
: undefined
}
help={
currentSalary?.customCurrencyName?.length > maxNameLength
? `Name must be ${maxNameLength} characters or less`
: undefined
}
>
<Input
placeholder="Currency Name"
size="small"
maxLength={maxNameLength}
value={currentSalary?.customCurrencyName || ""}
onChange={(e) => handleCustomCurrencyChange("name", e.target.value)}
/>
</Form.Item>
<Button
size="small"
type="primary"
disabled={
!currentSalary?.customCurrencySymbol ||
currentSalary.customCurrencySymbol.length > maxSymbolLength ||
(currentSalary.customCurrencyName?.length || 0) > maxNameLength
}
onClick={setCustomCurrency}
>
Add
</Button>
</div>
);
};

return (
<Form.Item name={name} noStyle initialValue={defaultValue}>
<Select
style={style}
dropdownRender={(menu) =>
allowCustom ? (
<>
{menu}
{renderCustomInput()}
</>
) : (
menu
)
}
>
{renderOptions()}
{renderCustomOption()}
</Select>
</Form.Item>
);
};

export default CurrencySelect;
Loading