mirror of
https://github.com/iib0011/omni-tools.git
synced 2025-11-08 17:46:45 +05:30
Merge 9f98824e8b into f3c5946e0d
This commit is contained in:
commit
fe2172cd08
33 changed files with 735 additions and 2 deletions
40
@types/units-converter.d.ts
vendored
Normal file
40
@types/units-converter.d.ts
vendored
Normal file
|
|
@ -0,0 +1,40 @@
|
|||
declare module 'units-converter' {
|
||||
export type UnitDescription = {
|
||||
unit: string;
|
||||
system: string;
|
||||
singular: string;
|
||||
plural: string;
|
||||
};
|
||||
export type Converter = (value?: number) => {
|
||||
from: (unit: string) => {
|
||||
to: (unit: string) => {
|
||||
value: number;
|
||||
unit: string;
|
||||
system: string;
|
||||
singular: string;
|
||||
plural: string;
|
||||
};
|
||||
toBest: (opts?: { exclude?: string[] }) => {
|
||||
value: number;
|
||||
unit: string;
|
||||
system: string;
|
||||
singular: string;
|
||||
plural: string;
|
||||
};
|
||||
possibilities: () => string[];
|
||||
};
|
||||
list: () => UnitDescription[];
|
||||
describe: (unit: string) => UnitDescription;
|
||||
};
|
||||
export const length: Converter;
|
||||
export const mass: Converter;
|
||||
export const volume: Converter;
|
||||
export const area: Converter;
|
||||
export const current: Converter;
|
||||
export const power: Converter;
|
||||
export const energy: Converter;
|
||||
export const digital: Converter;
|
||||
export const temperature: Converter;
|
||||
export const speed: Converter;
|
||||
export const voltage: Converter;
|
||||
}
|
||||
14
package-lock.json
generated
14
package-lock.json
generated
|
|
@ -20,6 +20,7 @@
|
|||
"@mui/material": "^5.15.20",
|
||||
"@playwright/test": "^1.45.0",
|
||||
"@simplepdf/react-embed-pdf": "^1.9.0",
|
||||
"@types/convert-units": "^2.3.12",
|
||||
"@types/ffmpeg": "^1.0.7",
|
||||
"@types/js-quantities": "^1.6.6",
|
||||
"@types/lodash": "^4.17.5",
|
||||
|
|
@ -67,6 +68,7 @@
|
|||
"styled-components": "^6.1.19",
|
||||
"tesseract.js": "^6.0.0",
|
||||
"type-fest": "^4.35.0",
|
||||
"units-converter": "^1.0.3",
|
||||
"use-deep-compare-effect": "^1.8.1",
|
||||
"yup": "^1.4.0"
|
||||
},
|
||||
|
|
@ -3408,6 +3410,12 @@
|
|||
"@types/node": "*"
|
||||
}
|
||||
},
|
||||
"node_modules/@types/convert-units": {
|
||||
"version": "2.3.12",
|
||||
"resolved": "https://registry.npmjs.org/@types/convert-units/-/convert-units-2.3.12.tgz",
|
||||
"integrity": "sha512-4EaowCOJMy8Cb2nB8XSN61U82VV4qFsFYY2WhKIwXy936aBTp2yWKvMpTCt1g76MDmd+DmVi9YxKSYVrfCQ/yw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@types/estree": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.8.tgz",
|
||||
|
|
@ -13271,6 +13279,12 @@
|
|||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/units-converter": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/units-converter/-/units-converter-1.0.3.tgz",
|
||||
"integrity": "sha512-tcAwnZxH8NUx0T/eltQ2CUZ21jJxLRHF7dkPoYDFdX+W+VHxbvb/aH5xXBa0Cdp1tpyFI6rju+Jnpj9seuudqg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/update-browserslist-db": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.1.3.tgz",
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@
|
|||
"@mui/material": "^5.15.20",
|
||||
"@playwright/test": "^1.45.0",
|
||||
"@simplepdf/react-embed-pdf": "^1.9.0",
|
||||
"@types/convert-units": "^2.3.12",
|
||||
"@types/ffmpeg": "^1.0.7",
|
||||
"@types/js-quantities": "^1.6.6",
|
||||
"@types/lodash": "^4.17.5",
|
||||
|
|
@ -86,6 +87,7 @@
|
|||
"styled-components": "^6.1.19",
|
||||
"tesseract.js": "^6.0.0",
|
||||
"type-fest": "^4.35.0",
|
||||
"units-converter": "^1.0.3",
|
||||
"use-deep-compare-effect": "^1.8.1",
|
||||
"yup": "^1.4.0"
|
||||
},
|
||||
|
|
|
|||
0
public/locales/en/conversion.json
Normal file
0
public/locales/en/conversion.json
Normal file
0
public/locales/en/measurement.json
Normal file
0
public/locales/en/measurement.json
Normal file
|
|
@ -42,6 +42,10 @@
|
|||
"description": "Tools for working with lists – sort, reverse, randomize lists, find unique and duplicate list items, change list item separators, and much more.",
|
||||
"title": "List Tools"
|
||||
},
|
||||
"conversion": {
|
||||
"description": "Comprehensive tools for converting between all major and niche units: length, area, volume, mass, temperature, speed, digital storage, energy, voltage, current, power, and more. Instantly switch between metric, imperial, and scientific units for science, engineering, daily life..",
|
||||
"title": "Conversion Tools"
|
||||
},
|
||||
"number": {
|
||||
"description": "Tools for working with numbers – generate number sequences, convert numbers to words and words to numbers, sort, round, factor numbers, and much more.",
|
||||
"title": "Number Tools"
|
||||
|
|
@ -251,5 +255,60 @@
|
|||
"userTypes": {
|
||||
"developers": "Developers",
|
||||
"generalUsers": "General users"
|
||||
},
|
||||
"lengthConverter": {
|
||||
"title": "Length Converter",
|
||||
"description": "Convert between metric, imperial, and US customary units of length and distance. Instantly switch between meters, kilometers, miles, yards, feet, inches, and more. Useful for science, engineering, travel, and everyday tasks. Enable Expert mode to unlock all available units.",
|
||||
"shortDescription": "Convert length and distance units"
|
||||
},
|
||||
"areaConverter": {
|
||||
"title": "Area Converter",
|
||||
"description": "Easily convert between square meters, acres, hectares, square feet, and other area units. Supports metric and imperial systems. Perfect for land measurement, real estate, and construction projects. Enable Expert mode to unlock all available units.",
|
||||
"shortDescription": "Convert area units"
|
||||
},
|
||||
"volumeConverter": {
|
||||
"title": "Volume Converter",
|
||||
"description": "Convert between liters, milliliters, gallons, quarts, pints, cups, and more. Handles both metric and US/UK imperial volume units. Great for cooking, science, and industrial applications. Enable Expert mode to unlock all available units.",
|
||||
"shortDescription": "Convert volume and capacity units"
|
||||
},
|
||||
"massConverter": {
|
||||
"title": "Mass Converter",
|
||||
"description": "Switch between grams, kilograms, tons, pounds, ounces, and other mass and weight units. Supports metric, imperial, and US customary systems. Ideal for science, nutrition, and shipping. Enable Expert mode to unlock all available units.",
|
||||
"shortDescription": "Convert mass and weight units"
|
||||
},
|
||||
"temperatureConverter": {
|
||||
"title": "Temperature Converter",
|
||||
"description": "Convert between Celsius, Fahrenheit, Kelvin, and Rankine. Instantly switch temperature units for science, cooking, weather, and engineering. Enable Expert mode to unlock all available units.",
|
||||
"shortDescription": "Convert temperature units"
|
||||
},
|
||||
"speedConverter": {
|
||||
"title": "Speed Converter",
|
||||
"description": "Convert between meters per second, kilometers per hour, miles per hour, knots, and more. Useful for physics, travel, automotive, and sports. Enable Expert mode to unlock all available units.",
|
||||
"shortDescription": "Convert speed units"
|
||||
},
|
||||
"digitalConverter": {
|
||||
"title": "Digital Storage Converter",
|
||||
"description": "Convert between bits, bytes, kilobytes, megabytes, gigabytes, terabytes, and more. Instantly switch digital storage units for computing, IT, and data management. Enable Expert mode to unlock all available units.",
|
||||
"shortDescription": "Convert digital storage units"
|
||||
},
|
||||
"energyConverter": {
|
||||
"title": "Energy Converter",
|
||||
"description": "Convert between joules, calories, kilowatt-hours, electronvolts, BTUs, and more. Useful for physics, engineering, nutrition, and energy management. Enable Expert mode to unlock all available units.",
|
||||
"shortDescription": "Convert energy units"
|
||||
},
|
||||
"voltageConverter": {
|
||||
"title": "Voltage Converter",
|
||||
"description": "Convert between volts, millivolts, kilovolts, and more. Instantly switch voltage units for electronics, engineering, and physics. Enable Expert mode to unlock all available units.",
|
||||
"shortDescription": "Convert voltage units"
|
||||
},
|
||||
"currentConverter": {
|
||||
"title": "Current Converter",
|
||||
"description": "Convert between amperes, milliamperes, kiloamperes, and more. Instantly switch current units for electronics, engineering, and physics. Enable Expert mode to unlock all available units.",
|
||||
"shortDescription": "Convert electric current units"
|
||||
},
|
||||
"powerConverter": {
|
||||
"title": "Power Converter",
|
||||
"description": "Convert between watts, kilowatts, megawatts, horsepower, and more. Instantly switch power units for electronics, engineering, and physics. Enable Expert mode to unlock all available units.",
|
||||
"shortDescription": "Convert power units"
|
||||
}
|
||||
}
|
||||
|
|
|
|||
0
src/pages/tools/ToolPage.tsx
Normal file
0
src/pages/tools/ToolPage.tsx
Normal file
205
src/pages/tools/conversion/GenericConverter.tsx
Normal file
205
src/pages/tools/conversion/GenericConverter.tsx
Normal file
|
|
@ -0,0 +1,205 @@
|
|||
import React, { useState, useMemo, useEffect } from 'react';
|
||||
import {
|
||||
Box,
|
||||
TextField,
|
||||
MenuItem,
|
||||
Grid,
|
||||
Typography,
|
||||
InputAdornment,
|
||||
IconButton,
|
||||
Tooltip,
|
||||
FormControlLabel,
|
||||
Switch
|
||||
} from '@mui/material';
|
||||
import ContentCopyIcon from '@mui/icons-material/ContentCopy';
|
||||
|
||||
export interface UnitDescription {
|
||||
unit: string;
|
||||
singular: string;
|
||||
plural: string;
|
||||
system?: string;
|
||||
}
|
||||
|
||||
interface GenericConverterProps {
|
||||
converter: (value?: number) => any;
|
||||
classicUnits: string[];
|
||||
defaultFrom: string;
|
||||
defaultTo: string;
|
||||
title: string;
|
||||
hasExpert?: boolean;
|
||||
}
|
||||
|
||||
const GenericConverter: React.FC<GenericConverterProps> = ({
|
||||
converter,
|
||||
classicUnits,
|
||||
defaultFrom,
|
||||
defaultTo,
|
||||
title,
|
||||
hasExpert = true
|
||||
}) => {
|
||||
const converterInstance = useMemo(() => converter(), [converter]);
|
||||
const allUnits = useMemo(
|
||||
() => converterInstance.list() as UnitDescription[],
|
||||
[converterInstance]
|
||||
);
|
||||
const [expert, setExpert] = useState(false);
|
||||
const showExpert = hasExpert && allUnits.length > 5;
|
||||
const units = useMemo(
|
||||
() =>
|
||||
showExpert && expert
|
||||
? allUnits
|
||||
: showExpert
|
||||
? allUnits.filter((u: UnitDescription) =>
|
||||
classicUnits.includes(u.unit)
|
||||
)
|
||||
: allUnits,
|
||||
[allUnits, expert, showExpert, classicUnits]
|
||||
);
|
||||
const [fromUnit, setFromUnit] = useState<string>(defaultFrom);
|
||||
const [toUnit, setToUnit] = useState<string>(defaultTo);
|
||||
const [fromValue, setFromValue] = useState('1');
|
||||
const [toValue, setToValue] = useState('');
|
||||
const [inputError, setInputError] = useState('');
|
||||
const [copied, setCopied] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
if (!fromUnit || !units.some((u: UnitDescription) => u.unit === fromUnit)) {
|
||||
setFromUnit(units[0]?.unit || '');
|
||||
}
|
||||
if (
|
||||
!toUnit ||
|
||||
!units.some((u: UnitDescription) => u.unit === toUnit) ||
|
||||
toUnit === fromUnit
|
||||
) {
|
||||
const next =
|
||||
units.find((u: UnitDescription) => u.unit !== fromUnit)?.unit ||
|
||||
units[0]?.unit ||
|
||||
'';
|
||||
setToUnit(next);
|
||||
}
|
||||
}, [units, fromUnit, toUnit]);
|
||||
|
||||
useEffect(() => {
|
||||
if (!fromValue || isNaN(Number(fromValue))) {
|
||||
setToValue('');
|
||||
setInputError(fromValue ? 'Enter a valid number' : '');
|
||||
return;
|
||||
}
|
||||
if (!fromUnit || !toUnit) {
|
||||
setToValue('');
|
||||
setInputError('');
|
||||
return;
|
||||
}
|
||||
try {
|
||||
const result = converterInstance
|
||||
.from(fromUnit)
|
||||
.to(toUnit, Number(fromValue));
|
||||
setToValue(result.value.toString());
|
||||
setInputError('');
|
||||
} catch {
|
||||
setToValue('');
|
||||
setInputError('Conversion not possible');
|
||||
}
|
||||
}, [fromValue, fromUnit, toUnit, converterInstance]);
|
||||
|
||||
const handleCopy = async () => {
|
||||
if (toValue) {
|
||||
await navigator.clipboard.writeText(toValue);
|
||||
setCopied(true);
|
||||
setTimeout(() => setCopied(false), 1200);
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Box>
|
||||
<Typography variant="h5" mb={2}>
|
||||
{title}
|
||||
</Typography>
|
||||
{showExpert && (
|
||||
<FormControlLabel
|
||||
control={
|
||||
<Switch
|
||||
checked={expert}
|
||||
onChange={(e) => setExpert(e.target.checked)}
|
||||
color="primary"
|
||||
/>
|
||||
}
|
||||
label="Expert mode (show all units)"
|
||||
sx={{ mb: 2 }}
|
||||
/>
|
||||
)}
|
||||
<Grid container spacing={2} alignItems="center">
|
||||
<Grid item xs={5}>
|
||||
<TextField
|
||||
fullWidth
|
||||
label="Value"
|
||||
value={fromValue}
|
||||
onChange={(e) => setFromValue(e.target.value)}
|
||||
type="number"
|
||||
error={!!inputError}
|
||||
helperText={inputError}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={3}>
|
||||
<TextField
|
||||
select
|
||||
fullWidth
|
||||
label="From"
|
||||
value={fromUnit}
|
||||
onChange={(e) => setFromUnit(e.target.value as string)}
|
||||
disabled={units.length === 0}
|
||||
>
|
||||
{units.map((u: UnitDescription) => (
|
||||
<MenuItem key={u.unit} value={u.unit}>
|
||||
{u.singular}
|
||||
</MenuItem>
|
||||
))}
|
||||
</TextField>
|
||||
</Grid>
|
||||
<Grid item xs={5}>
|
||||
<TextField
|
||||
fullWidth
|
||||
label="Result"
|
||||
value={toValue}
|
||||
InputProps={{
|
||||
readOnly: true,
|
||||
endAdornment: (
|
||||
<InputAdornment position="end">
|
||||
<Tooltip title={copied ? 'Copied!' : 'Copy'}>
|
||||
<span>
|
||||
<IconButton
|
||||
onClick={handleCopy}
|
||||
disabled={!toValue}
|
||||
size="small"
|
||||
>
|
||||
<ContentCopyIcon fontSize="small" />
|
||||
</IconButton>
|
||||
</span>
|
||||
</Tooltip>
|
||||
</InputAdornment>
|
||||
)
|
||||
}}
|
||||
/>
|
||||
</Grid>
|
||||
<Grid item xs={3}>
|
||||
<TextField
|
||||
select
|
||||
fullWidth
|
||||
label="To"
|
||||
value={toUnit}
|
||||
onChange={(e) => setToUnit(e.target.value as string)}
|
||||
disabled={units.length === 0}
|
||||
>
|
||||
{units.map((u: UnitDescription) => (
|
||||
<MenuItem key={u.unit} value={u.unit}>
|
||||
{u.singular}
|
||||
</MenuItem>
|
||||
))}
|
||||
</TextField>
|
||||
</Grid>
|
||||
</Grid>
|
||||
</Box>
|
||||
);
|
||||
};
|
||||
|
||||
export default GenericConverter;
|
||||
15
src/pages/tools/conversion/area-converter-meta.ts
Normal file
15
src/pages/tools/conversion/area-converter-meta.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { defineTool } from '@tools/defineTool';
|
||||
import { lazy } from 'react';
|
||||
|
||||
export const tool = defineTool('conversion', {
|
||||
path: 'area-converter',
|
||||
icon: 'mdi:ruler-square',
|
||||
keywords: ['area', 'convert', 'square meter', 'acre', 'hectare'],
|
||||
component: lazy(() => import('./area-converter')),
|
||||
i18n: {
|
||||
name: 'translation:areaConverter.title',
|
||||
description: 'translation:areaConverter.description',
|
||||
shortDescription: 'translation:areaConverter.shortDescription',
|
||||
userTypes: ['generalUsers']
|
||||
}
|
||||
});
|
||||
16
src/pages/tools/conversion/area-converter.tsx
Normal file
16
src/pages/tools/conversion/area-converter.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { area } from 'units-converter';
|
||||
import GenericConverter from './GenericConverter';
|
||||
|
||||
const CLASSIC_UNITS = ['m2', 'km2', 'cm2', 'ha', 'ac', 'ft2', 'yd2'];
|
||||
|
||||
export default function AreaConverter() {
|
||||
return (
|
||||
<GenericConverter
|
||||
converter={area}
|
||||
classicUnits={CLASSIC_UNITS}
|
||||
defaultFrom="m2"
|
||||
defaultTo="km2"
|
||||
title="Area Converter"
|
||||
/>
|
||||
);
|
||||
}
|
||||
15
src/pages/tools/conversion/current-converter-meta.ts
Normal file
15
src/pages/tools/conversion/current-converter-meta.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { defineTool } from '@tools/defineTool';
|
||||
import { lazy } from 'react';
|
||||
|
||||
export const tool = defineTool('conversion', {
|
||||
path: 'current-converter',
|
||||
icon: 'mdi:current-ac',
|
||||
keywords: ['current', 'ampere', 'milliampere', 'kiloampere', 'convert'],
|
||||
component: lazy(() => import('./current-converter')),
|
||||
i18n: {
|
||||
name: 'translation:currentConverter.title',
|
||||
description: 'translation:currentConverter.description',
|
||||
shortDescription: 'translation:currentConverter.shortDescription',
|
||||
userTypes: ['generalUsers']
|
||||
}
|
||||
});
|
||||
16
src/pages/tools/conversion/current-converter.tsx
Normal file
16
src/pages/tools/conversion/current-converter.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { current } from 'units-converter';
|
||||
import GenericConverter from './GenericConverter';
|
||||
|
||||
const CLASSIC_UNITS = ['A', 'mA', 'kA'];
|
||||
|
||||
export default function CurrentConverter() {
|
||||
return (
|
||||
<GenericConverter
|
||||
converter={current}
|
||||
classicUnits={CLASSIC_UNITS}
|
||||
defaultFrom="A"
|
||||
defaultTo="mA"
|
||||
title="Current Converter"
|
||||
/>
|
||||
);
|
||||
}
|
||||
24
src/pages/tools/conversion/digital-converter-meta.ts
Normal file
24
src/pages/tools/conversion/digital-converter-meta.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import { defineTool } from '@tools/defineTool';
|
||||
import { lazy } from 'react';
|
||||
|
||||
export const tool = defineTool('conversion', {
|
||||
path: 'digital-converter',
|
||||
icon: 'mdi:database',
|
||||
keywords: [
|
||||
'digital',
|
||||
'data',
|
||||
'bit',
|
||||
'byte',
|
||||
'kilobyte',
|
||||
'megabyte',
|
||||
'gigabyte',
|
||||
'convert'
|
||||
],
|
||||
component: lazy(() => import('./digital-converter')),
|
||||
i18n: {
|
||||
name: 'translation:digitalConverter.title',
|
||||
description: 'translation:digitalConverter.description',
|
||||
shortDescription: 'translation:digitalConverter.shortDescription',
|
||||
userTypes: ['generalUsers']
|
||||
}
|
||||
});
|
||||
27
src/pages/tools/conversion/digital-converter.tsx
Normal file
27
src/pages/tools/conversion/digital-converter.tsx
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
import { digital } from 'units-converter';
|
||||
import GenericConverter from './GenericConverter';
|
||||
|
||||
const CLASSIC_UNITS = [
|
||||
'B',
|
||||
'KB',
|
||||
'MB',
|
||||
'GB',
|
||||
'TB',
|
||||
'b',
|
||||
'Kb',
|
||||
'Mb',
|
||||
'Gb',
|
||||
'Tb'
|
||||
];
|
||||
|
||||
export default function DigitalConverter() {
|
||||
return (
|
||||
<GenericConverter
|
||||
converter={digital}
|
||||
classicUnits={CLASSIC_UNITS}
|
||||
defaultFrom="MB"
|
||||
defaultTo="GB"
|
||||
title="Digital Storage Converter"
|
||||
/>
|
||||
);
|
||||
}
|
||||
15
src/pages/tools/conversion/energy-converter-meta.ts
Normal file
15
src/pages/tools/conversion/energy-converter-meta.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { defineTool } from '@tools/defineTool';
|
||||
import { lazy } from 'react';
|
||||
|
||||
export const tool = defineTool('conversion', {
|
||||
path: 'energy-converter',
|
||||
icon: 'mdi:solar-power',
|
||||
keywords: ['energy', 'joule', 'calorie', 'kilowatt-hour', 'btu', 'convert'],
|
||||
component: lazy(() => import('./energy-converter')),
|
||||
i18n: {
|
||||
name: 'translation:energyConverter.title',
|
||||
description: 'translation:energyConverter.description',
|
||||
shortDescription: 'translation:energyConverter.shortDescription',
|
||||
userTypes: ['generalUsers']
|
||||
}
|
||||
});
|
||||
16
src/pages/tools/conversion/energy-converter.tsx
Normal file
16
src/pages/tools/conversion/energy-converter.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { energy } from 'units-converter';
|
||||
import GenericConverter from './GenericConverter';
|
||||
|
||||
const CLASSIC_UNITS = ['J', 'Wh', 'kWh', 'cal', 'kcal'];
|
||||
|
||||
export default function EnergyConverter() {
|
||||
return (
|
||||
<GenericConverter
|
||||
converter={energy}
|
||||
classicUnits={CLASSIC_UNITS}
|
||||
defaultFrom="J"
|
||||
defaultTo="kWh"
|
||||
title="Energy Converter"
|
||||
/>
|
||||
);
|
||||
}
|
||||
26
src/pages/tools/conversion/index.ts
Normal file
26
src/pages/tools/conversion/index.ts
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
import { tool as lengthConverterTool } from './length-converter-meta';
|
||||
import { tool as areaConverterTool } from './area-converter-meta';
|
||||
import { tool as volumeConverterTool } from './volume-converter-meta';
|
||||
import { tool as massConverterTool } from './mass-converter-meta';
|
||||
import { tool as temperatureConverterTool } from './temperature-converter-meta';
|
||||
import { tool as speedConverterTool } from './speed-converter-meta';
|
||||
import { tool as digitalConverterTool } from './digital-converter-meta';
|
||||
import { tool as energyConverterTool } from './energy-converter-meta';
|
||||
import { tool as voltageConverterTool } from './voltage-converter-meta';
|
||||
import { tool as currentConverterTool } from './current-converter-meta';
|
||||
import { tool as powerConverterTool } from './power-converter-meta';
|
||||
|
||||
// Conversion tools section entry point
|
||||
export const conversionTools = [
|
||||
lengthConverterTool,
|
||||
areaConverterTool,
|
||||
volumeConverterTool,
|
||||
massConverterTool,
|
||||
temperatureConverterTool,
|
||||
speedConverterTool,
|
||||
digitalConverterTool,
|
||||
energyConverterTool,
|
||||
voltageConverterTool,
|
||||
currentConverterTool,
|
||||
powerConverterTool
|
||||
];
|
||||
24
src/pages/tools/conversion/length-converter-meta.ts
Normal file
24
src/pages/tools/conversion/length-converter-meta.ts
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
import { defineTool } from '@tools/defineTool';
|
||||
import { lazy } from 'react';
|
||||
|
||||
export const tool = defineTool('conversion', {
|
||||
path: 'length-converter',
|
||||
icon: 'mdi:ruler',
|
||||
keywords: [
|
||||
'length',
|
||||
'distance',
|
||||
'convert',
|
||||
'meter',
|
||||
'mile',
|
||||
'yard',
|
||||
'foot',
|
||||
'inch'
|
||||
],
|
||||
component: lazy(() => import('./length-converter')),
|
||||
i18n: {
|
||||
name: 'translation:lengthConverter.title',
|
||||
description: 'translation:lengthConverter.description',
|
||||
shortDescription: 'translation:lengthConverter.shortDescription',
|
||||
userTypes: ['generalUsers']
|
||||
}
|
||||
});
|
||||
16
src/pages/tools/conversion/length-converter.tsx
Normal file
16
src/pages/tools/conversion/length-converter.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { length } from 'units-converter';
|
||||
import GenericConverter from './GenericConverter';
|
||||
|
||||
const CLASSIC_UNITS = ['m', 'km', 'cm', 'mm', 'mi', 'yd', 'ft', 'in'];
|
||||
|
||||
export default function LengthConverter() {
|
||||
return (
|
||||
<GenericConverter
|
||||
converter={length}
|
||||
classicUnits={CLASSIC_UNITS}
|
||||
defaultFrom="m"
|
||||
defaultTo="km"
|
||||
title="Length Converter"
|
||||
/>
|
||||
);
|
||||
}
|
||||
15
src/pages/tools/conversion/mass-converter-meta.ts
Normal file
15
src/pages/tools/conversion/mass-converter-meta.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { defineTool } from '@tools/defineTool';
|
||||
import { lazy } from 'react';
|
||||
|
||||
export const tool = defineTool('conversion', {
|
||||
path: 'mass-converter',
|
||||
icon: 'mdi:weight',
|
||||
keywords: ['mass', 'weight', 'convert', 'gram', 'kilogram', 'pound', 'ounce'],
|
||||
component: lazy(() => import('./mass-converter')),
|
||||
i18n: {
|
||||
name: 'translation:massConverter.title',
|
||||
description: 'translation:massConverter.description',
|
||||
shortDescription: 'translation:massConverter.shortDescription',
|
||||
userTypes: ['generalUsers']
|
||||
}
|
||||
});
|
||||
16
src/pages/tools/conversion/mass-converter.tsx
Normal file
16
src/pages/tools/conversion/mass-converter.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { mass } from 'units-converter';
|
||||
import GenericConverter from './GenericConverter';
|
||||
|
||||
const CLASSIC_UNITS = ['kg', 'g', 'mg', 'lb', 'oz', 'st', 'ton', 't'];
|
||||
|
||||
export default function MassConverter() {
|
||||
return (
|
||||
<GenericConverter
|
||||
converter={mass}
|
||||
classicUnits={CLASSIC_UNITS}
|
||||
defaultFrom="kg"
|
||||
defaultTo="g"
|
||||
title="Mass Converter"
|
||||
/>
|
||||
);
|
||||
}
|
||||
15
src/pages/tools/conversion/power-converter-meta.ts
Normal file
15
src/pages/tools/conversion/power-converter-meta.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { defineTool } from '@tools/defineTool';
|
||||
import { lazy } from 'react';
|
||||
|
||||
export const tool = defineTool('conversion', {
|
||||
path: 'power-converter',
|
||||
icon: 'mdi:power-plug',
|
||||
keywords: ['power', 'watt', 'kilowatt', 'megawatt', 'horsepower', 'convert'],
|
||||
component: lazy(() => import('./power-converter')),
|
||||
i18n: {
|
||||
name: 'translation:powerConverter.title',
|
||||
description: 'translation:powerConverter.description',
|
||||
shortDescription: 'translation:powerConverter.shortDescription',
|
||||
userTypes: ['generalUsers']
|
||||
}
|
||||
});
|
||||
16
src/pages/tools/conversion/power-converter.tsx
Normal file
16
src/pages/tools/conversion/power-converter.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { power } from 'units-converter';
|
||||
import GenericConverter from './GenericConverter';
|
||||
|
||||
const CLASSIC_UNITS = ['W', 'kW', 'MW', 'GW', 'mW'];
|
||||
|
||||
export default function PowerConverter() {
|
||||
return (
|
||||
<GenericConverter
|
||||
converter={power}
|
||||
classicUnits={CLASSIC_UNITS}
|
||||
defaultFrom="W"
|
||||
defaultTo="kW"
|
||||
title="Power Converter"
|
||||
/>
|
||||
);
|
||||
}
|
||||
15
src/pages/tools/conversion/speed-converter-meta.ts
Normal file
15
src/pages/tools/conversion/speed-converter-meta.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { defineTool } from '@tools/defineTool';
|
||||
import { lazy } from 'react';
|
||||
|
||||
export const tool = defineTool('conversion', {
|
||||
path: 'speed-converter',
|
||||
icon: 'mdi:speedometer',
|
||||
keywords: ['speed', 'km/h', 'm/s', 'mph', 'knots', 'convert'],
|
||||
component: lazy(() => import('./speed-converter')),
|
||||
i18n: {
|
||||
name: 'translation:speedConverter.title',
|
||||
description: 'translation:speedConverter.description',
|
||||
shortDescription: 'translation:speedConverter.shortDescription',
|
||||
userTypes: ['generalUsers']
|
||||
}
|
||||
});
|
||||
16
src/pages/tools/conversion/speed-converter.tsx
Normal file
16
src/pages/tools/conversion/speed-converter.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { speed } from 'units-converter';
|
||||
import GenericConverter from './GenericConverter';
|
||||
|
||||
const CLASSIC_UNITS = ['km/h', 'm/s', 'mph', 'knot', 'ft/s'];
|
||||
|
||||
export default function SpeedConverter() {
|
||||
return (
|
||||
<GenericConverter
|
||||
converter={speed}
|
||||
classicUnits={CLASSIC_UNITS}
|
||||
defaultFrom="km/h"
|
||||
defaultTo="mph"
|
||||
title="Speed Converter"
|
||||
/>
|
||||
);
|
||||
}
|
||||
22
src/pages/tools/conversion/temperature-converter-meta.ts
Normal file
22
src/pages/tools/conversion/temperature-converter-meta.ts
Normal file
|
|
@ -0,0 +1,22 @@
|
|||
import { defineTool } from '@tools/defineTool';
|
||||
import { lazy } from 'react';
|
||||
|
||||
export const tool = defineTool('conversion', {
|
||||
path: 'temperature-converter',
|
||||
icon: 'mdi:thermometer',
|
||||
keywords: [
|
||||
'temperature',
|
||||
'celsius',
|
||||
'fahrenheit',
|
||||
'kelvin',
|
||||
'rankine',
|
||||
'convert'
|
||||
],
|
||||
component: lazy(() => import('./temperature-converter')),
|
||||
i18n: {
|
||||
name: 'translation:temperatureConverter.title',
|
||||
description: 'translation:temperatureConverter.description',
|
||||
shortDescription: 'translation:temperatureConverter.shortDescription',
|
||||
userTypes: ['generalUsers']
|
||||
}
|
||||
});
|
||||
16
src/pages/tools/conversion/temperature-converter.tsx
Normal file
16
src/pages/tools/conversion/temperature-converter.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { temperature } from 'units-converter';
|
||||
import GenericConverter from './GenericConverter';
|
||||
|
||||
const CLASSIC_UNITS = ['C', 'F', 'K', 'R'];
|
||||
|
||||
export default function TemperatureConverter() {
|
||||
return (
|
||||
<GenericConverter
|
||||
converter={temperature}
|
||||
classicUnits={CLASSIC_UNITS}
|
||||
defaultFrom="C"
|
||||
defaultTo="F"
|
||||
title="Temperature Converter"
|
||||
/>
|
||||
);
|
||||
}
|
||||
15
src/pages/tools/conversion/voltage-converter-meta.ts
Normal file
15
src/pages/tools/conversion/voltage-converter-meta.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { defineTool } from '@tools/defineTool';
|
||||
import { lazy } from 'react';
|
||||
|
||||
export const tool = defineTool('conversion', {
|
||||
path: 'voltage-converter',
|
||||
icon: 'mdi:flash',
|
||||
keywords: ['voltage', 'volt', 'millivolt', 'kilovolt', 'convert'],
|
||||
component: lazy(() => import('./voltage-converter')),
|
||||
i18n: {
|
||||
name: 'translation:voltageConverter.title',
|
||||
description: 'translation:voltageConverter.description',
|
||||
shortDescription: 'translation:voltageConverter.shortDescription',
|
||||
userTypes: ['generalUsers']
|
||||
}
|
||||
});
|
||||
16
src/pages/tools/conversion/voltage-converter.tsx
Normal file
16
src/pages/tools/conversion/voltage-converter.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { voltage } from 'units-converter';
|
||||
import GenericConverter from './GenericConverter';
|
||||
|
||||
const CLASSIC_UNITS = ['V', 'mV', 'kV'];
|
||||
|
||||
export default function VoltageConverter() {
|
||||
return (
|
||||
<GenericConverter
|
||||
converter={voltage}
|
||||
classicUnits={CLASSIC_UNITS}
|
||||
defaultFrom="V"
|
||||
defaultTo="kV"
|
||||
title="Voltage Converter"
|
||||
/>
|
||||
);
|
||||
}
|
||||
15
src/pages/tools/conversion/volume-converter-meta.ts
Normal file
15
src/pages/tools/conversion/volume-converter-meta.ts
Normal file
|
|
@ -0,0 +1,15 @@
|
|||
import { defineTool } from '@tools/defineTool';
|
||||
import { lazy } from 'react';
|
||||
|
||||
export const tool = defineTool('conversion', {
|
||||
path: 'volume-converter',
|
||||
icon: 'mdi:cup-water',
|
||||
keywords: ['volume', 'capacity', 'convert', 'liter', 'gallon', 'pint', 'cup'],
|
||||
component: lazy(() => import('./volume-converter')),
|
||||
i18n: {
|
||||
name: 'translation:volumeConverter.title',
|
||||
description: 'translation:volumeConverter.description',
|
||||
shortDescription: 'translation:volumeConverter.shortDescription',
|
||||
userTypes: ['generalUsers']
|
||||
}
|
||||
});
|
||||
16
src/pages/tools/conversion/volume-converter.tsx
Normal file
16
src/pages/tools/conversion/volume-converter.tsx
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
import { volume } from 'units-converter';
|
||||
import GenericConverter from './GenericConverter';
|
||||
|
||||
const CLASSIC_UNITS = ['L', 'm3', 'mL', 'cL', 'gal', 'qt', 'pt', 'cup', 'floz'];
|
||||
|
||||
export default function VolumeConverter() {
|
||||
return (
|
||||
<GenericConverter
|
||||
converter={volume}
|
||||
classicUnits={CLASSIC_UNITS}
|
||||
defaultFrom="L"
|
||||
defaultTo="m3"
|
||||
title="Volume Converter"
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
|
@ -33,7 +33,8 @@ export type ToolCategory =
|
|||
| 'video'
|
||||
| 'pdf'
|
||||
| 'audio'
|
||||
| 'xml';
|
||||
| 'xml'
|
||||
| 'conversion';
|
||||
|
||||
export interface DefinedTool {
|
||||
type: ToolCategory;
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ import { pdfTools } from '../pages/tools/pdf';
|
|||
import { xmlTools } from '../pages/tools/xml';
|
||||
import { TFunction } from 'i18next';
|
||||
import { FullI18nKey, I18nNamespaces } from '../i18n';
|
||||
import { conversionTools } from '../pages/tools/conversion';
|
||||
|
||||
const toolCategoriesOrder: ToolCategory[] = [
|
||||
'image-generic',
|
||||
|
|
@ -27,6 +28,7 @@ const toolCategoriesOrder: ToolCategory[] = [
|
|||
'list',
|
||||
'csv',
|
||||
'number',
|
||||
'conversion', // <-- Renamed measurement to conversion
|
||||
'png',
|
||||
'time',
|
||||
'xml',
|
||||
|
|
@ -43,7 +45,8 @@ export const tools: DefinedTool[] = [
|
|||
...numberTools,
|
||||
...timeTools,
|
||||
...audioTools,
|
||||
...xmlTools
|
||||
...xmlTools,
|
||||
...conversionTools
|
||||
];
|
||||
const categoriesConfig: {
|
||||
type: ToolCategory;
|
||||
|
|
@ -134,6 +137,12 @@ const categoriesConfig: {
|
|||
icon: 'mdi-light:xml',
|
||||
value: 'translation:categories.xml.description',
|
||||
title: 'translation:categories.xml.title'
|
||||
},
|
||||
{
|
||||
type: 'conversion',
|
||||
icon: 'material-symbols-light:conversion-path',
|
||||
value: 'translation:categories.conversion.description',
|
||||
title: 'translation:categories.conversion.title'
|
||||
}
|
||||
];
|
||||
const CATEGORIES_USER_TYPES_MAPPINGS: Partial<Record<ToolCategory, UserType>> =
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue