Skip to content

Commit fbcfdbc

Browse files
committed
Merge branch 'feat/currency-converter' into chore/all-my-stuffs
# Conflicts: # components.d.ts # package.json # pnpm-lock.yaml # src/tools/index.ts
2 parents 1da0846 + b241003 commit fbcfdbc

File tree

6 files changed

+140
-0
lines changed

6 files changed

+140
-0
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@
6767
"crypto-js": "^4.1.1",
6868
"csstoxpath": "^2.0.0",
6969
"curlconverter": "^4.10.1",
70+
"currency-codes-ts": "^3.0.0",
71+
"currency-exchanger-js": "^1.0.4",
7072
"date-fns": "^2.29.3",
7173
"dompurify": "^3.0.6",
7274
"email-bounce-parser-browser": "^1.1",
Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
<script setup lang="ts">
2+
import { code, countries, country } from 'currency-codes-ts';
3+
import converter from 'currency-exchanger-js';
4+
import moneysData from './moneys.json';
5+
import { useQueryParamOrStorage } from '@/composable/queryParams';
6+
7+
const allCurrencies = Object.entries(moneysData).map(([k, v]) => ({ value: k, label: v || k }));
8+
const otherCurrencies = useQueryParamOrStorage<{ name: string }[]>({ name: 'to', storageName: 'currency-conv:others', defaultValue: [{ name: 'usd' }] });
9+
const currentCurrency = useQueryParamOrStorage<string>({ name: 'from', storageName: 'currency-conv:cur', defaultValue: 'eur' });
10+
const amount = ref(1);
11+
const currentDatetime = ref(Date.now());
12+
13+
const convertedCurrencies = computedAsync<Record<string, number>>(async () => {
14+
const currentCurrencyValue = currentCurrency.value;
15+
const currentDatetimeValue = currentDatetime.value;
16+
const amountValue = amount.value;
17+
const otherCurrenciesValues = otherCurrencies.value;
18+
19+
let result = {};
20+
for (const targetCurrency of otherCurrenciesValues) {
21+
const value = await converter.convertOnDate(amountValue, currentCurrencyValue, targetCurrency.name, new Date(currentDatetimeValue));
22+
result = { ...result, [targetCurrency.name]: value };
23+
}
24+
return result;
25+
});
26+
27+
const countryToCurrenciesInput = ref('France');
28+
const allCountries = countries();
29+
const countryToCurrenciesOutput = computed(() => country(countryToCurrenciesInput.value));
30+
31+
const currencyToCountriesInput = ref('eur');
32+
const currencyToCountriesOutput = computed(() => code(currencyToCountriesInput.value));
33+
</script>
34+
35+
<template>
36+
<div>
37+
<c-card title="Currency Converter" mb-2>
38+
<c-select
39+
v-model:value="currentCurrency"
40+
label="From"
41+
label-position="left"
42+
searchable
43+
:options="allCurrencies"
44+
mb-2
45+
/>
46+
<n-form-item label="Amount:" label-placement="left" mb-2>
47+
<n-input-number v-model:value="amount" :min="0" />
48+
</n-form-item>
49+
50+
<n-form-item label="For Date:" label-placement="left" mb-2>
51+
<n-date-picker
52+
v-model:value="currentDatetime"
53+
type="date"
54+
/>
55+
</n-form-item>
56+
57+
<c-card title="Converted currencies">
58+
<n-dynamic-input
59+
v-model:value="otherCurrencies"
60+
show-sort-button
61+
:on-create="() => ({ name: 'eur' })"
62+
>
63+
<template #default="{ value }">
64+
<div flex flex-wrap items-center gap-1>
65+
<n-select
66+
v-model:value="value.name"
67+
filterable
68+
placeholder="Please select a currency"
69+
:options="allCurrencies"
70+
w-full
71+
/>
72+
<input-copyable readonly :value="convertedCurrencies ? convertedCurrencies[value.name] : 0" />
73+
</div>
74+
</template>
75+
</n-dynamic-input>
76+
</c-card>
77+
</c-card>
78+
79+
<c-card title="Country to Currencies" mb-2>
80+
<c-select
81+
v-model:value="countryToCurrenciesInput"
82+
label="Country"
83+
label-position="left"
84+
searchable
85+
:options="allCountries"
86+
/>
87+
88+
<n-divider />
89+
90+
<ul>
91+
<li v-for="(currency, ix) in countryToCurrenciesOutput" :key="ix">
92+
{{ currency.currency }} [{{ currency.code }}/{{ currency.number }} - {{ currency.digits }}digits] (also in: {{ currency.countries?.join(', ') }})
93+
</li>
94+
</ul>
95+
</c-card>
96+
97+
<c-card title="Currencies to Countries" mb-2>
98+
<c-select
99+
v-model:value="currencyToCountriesInput"
100+
label="Currency"
101+
label-position="left"
102+
searchable
103+
:options="allCurrencies"
104+
/>
105+
106+
<n-divider />
107+
108+
<n-p v-if="currencyToCountriesOutput">
109+
{{ currencyToCountriesOutput.currency }} [{{ currencyToCountriesOutput.code }}/{{ currencyToCountriesOutput.number }} - {{ currencyToCountriesOutput.digits }}digits]
110+
</n-p>
111+
112+
<ul v-if="currencyToCountriesOutput">
113+
<li v-for="(countryName, ix) in currencyToCountriesOutput.countries" :key="ix">
114+
{{ countryName }}
115+
</li>
116+
</ul>
117+
</c-card>
118+
</div>
119+
</template>
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
declare module 'currency-exchanger-js'{
2+
export function convertOnDate(value: number,fromCurrency: string,toCurrency: string,inputDate: Date): number;
3+
export function convert(value: number,fromCurrency: string,toCurrency: string): number;
4+
}

src/tools/currency-converter/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { Currency } from '@vicons/tabler';
2+
import { defineTool } from '../tool';
3+
4+
export const tool = defineTool({
5+
name: 'Currency Converter',
6+
path: '/currency-converter',
7+
description: 'Convert currency values using ExchangeRate-API',
8+
keywords: ['currency', 'converter'],
9+
component: () => import('./currency-converter.vue'),
10+
icon: Currency,
11+
createdAt: new Date('2024-08-15'),
12+
});
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{ "1000sats": "", "1inch": "1inch", "aave": "Aave", "ada": "Cardano", "aed": "Emirati Dirham", "afn": "Afghan Afghani", "agix": "SingularityNET", "akt": "Akash Network", "algo": "Algorand", "all": "Albanian Lek", "amd": "Armenian Dram", "amp": "Amp", "ang": "Dutch Guilder", "aoa": "Angolan Kwanza", "ape": "ApeCoin", "apt": "Aptos", "ar": "Arweave", "arb": "Arbitrum", "ars": "Argentine Peso", "atom": "Cosmos", "ats": "Austrian Schilling", "aud": "Australian Dollar", "avax": "Avalanche", "awg": "Aruban or Dutch Guilder", "axs": "Axie Infinity", "azm": "Azerbaijani Manat", "azn": "Azerbaijan Manat", "bake": "BakeryToken", "bam": "Bosnian Convertible Mark", "bat": "Basic Attention Token", "bbd": "Barbadian or Bajan Dollar", "bch": "Bitcoin Cash", "bdt": "Bangladeshi Taka", "bef": "Belgian Franc", "bgn": "Bulgarian Lev", "bhd": "Bahraini Dinar", "bif": "Burundian Franc", "bmd": "Bermudian Dollar", "bnb": "Binance Coin", "bnd": "Bruneian Dollar", "bob": "Bolivian Bolíviano", "brl": "Brazilian Real", "bsd": "Bahamian Dollar", "bsv": "Bitcoin SV", "bsw": "Biswap", "btc": "Bitcoin", "btcb": "Bitcoin BEP2", "btg": "Bitcoin Gold", "btn": "Bhutanese Ngultrum", "btt": "BitTorrent", "busd": "Binance USD", "bwp": "Botswana Pula", "byn": "Belarusian Ruble", "byr": "Belarusian Ruble", "bzd": "Belizean Dollar", "cad": "Canadian Dollar", "cake": "PancakeSwap", "cdf": "Congolese Franc", "celo": "Celo", "cfx": "Conflux", "chf": "Swiss Franc", "chz": "Chiliz", "clp": "Chilean Peso", "cnh": "Chinese Yuan Renminbi Offshore", "cny": "Chinese Yuan Renminbi", "comp": "Compound", "cop": "Colombian Peso", "crc": "Costa Rican Colon", "cro": "Crypto.com Chain", "crv": "Curve DAO Token", "cspr": "Casper", "cuc": "Cuban Convertible Peso", "cup": "Cuban Peso", "cve": "Cape Verdean Escudo", "cvx": "Convex Finance", "cyp": "Cypriot Pound", "czk": "Czech Koruna", "dai": "DAI", "dash": "Digital Cash", "dcr": "Decred", "dem": "German Deutsche Mark", "dfi": "DfiStarter", "djf": "Djiboutian Franc", "dkk": "Danish Krone", "doge": "Dogecoin", "dop": "Dominican Peso", "dot": "Polkadot", "dydx": "dYdX", "dzd": "Algerian Dinar", "eek": "Estonian Kroon", "egld": "Elrond", "egp": "Egyptian Pound", "enj": "Enjin Coin", "eos": "EOS", "ern": "Eritrean Nakfa", "esp": "Spanish Peseta", "etb": "Ethiopian Birr", "etc": "Ethereum Classic", "eth": "Ethereum", "eur": "Euro", "fei": "Fei USD", "fil": "Filecoin", "fim": "Finnish Markka", "fjd": "Fijian Dollar", "fkp": "Falkland Island Pound", "flow": "Flow", "flr": "FLARE", "frax": "Frax", "frf": "French Franc", "ftm": "Fantom", "ftt": "FarmaTrust", "fxs": "Frax Share", "gala": "Gala", "gbp": "British Pound", "gel": "Georgian Lari", "ggp": "Guernsey Pound", "ghc": "Ghanaian Cedi", "ghs": "Ghanaian Cedi", "gip": "Gibraltar Pound", "gmd": "Gambian Dalasi", "gmx": "Goldmaxcoin", "gnf": "Guinean Franc", "gno": "Gnosis", "grd": "Greek Drachma", "grt": "The Graph", "gt": "GateToken", "gtq": "Guatemalan Quetzal", "gusd": "Gemini US Dollar", "gyd": "Guyanese Dollar", "hbar": "Hedera", "hkd": "Hong Kong Dollar", "hnl": "Honduran Lempira", "hnt": "Helium", "hot": "Hydro Protocol", "hrk": "Croatian Kuna", "ht": "Huobi Token", "htg": "Haitian Gourde", "huf": "Hungarian Forint", "icp": "Internet Computer", "idr": "Indonesian Rupiah", "iep": "Irish Pound", "ils": "Israeli Shekel", "imp": "Isle of Man Pound", "imx": "Immutable X", "inj": "Injective", "inr": "Indian Rupee", "iqd": "Iraqi Dinar", "irr": "Iranian Rial", "isk": "Icelandic Krona", "itl": "Italian Lira", "jep": "Jersey Pound", "jmd": "Jamaican Dollar", "jod": "Jordanian Dinar", "jpy": "Japanese Yen", "kas": "", "kava": "Kava", "kcs": "Kucoin", "kda": "Kadena", "kes": "Kenyan Shilling", "kgs": "Kyrgyzstani Som", "khr": "Cambodian Riel", "klay": "Klaytn", "kmf": "Comorian Franc", "knc": "Kyber Network Crystals", "kpw": "North Korean Won", "krw": "South Korean Won", "ksm": "Kusama", "kwd": "Kuwaiti Dinar", "kyd": "Caymanian Dollar", "kzt": "Kazakhstani Tenge", "lak": "Lao Kip", "lbp": "Lebanese Pound", "ldo": "Lido DAO Token", "leo": "LEOcoin", "link": "Chainlink", "lkr": "Sri Lankan Rupee", "lrc": "Loopring", "lrd": "Liberian Dollar", "lsl": "Basotho Loti", "ltc": "Litecoin", "ltl": "Lithuanian Litas", "luf": "Luxembourg Franc", "luna": "Terra", "lunc": "", "lvl": "Latvian Lat", "lyd": "Libyan Dinar", "mad": "Moroccan Dirham", "mana": "Mana Coin Decentraland", "matic": "Polygon", "mbx": "MobieCoin", "mdl": "Moldovan Leu", "mga": "Malagasy Ariary", "mgf": "Malagasy Franc", "mina": "Mina", "mkd": "Macedonian Denar", "mkr": "Maker", "mmk": "Burmese Kyat", "mnt": "Mongolian Tughrik", "mop": "Macau Pataca", "mro": "Mauritanian Ouguiya", "mru": "Mauritanian Ouguiya", "mtl": "Maltese Lira", "mur": "Mauritian Rupee", "mvr": "Maldivian Rufiyaa", "mwk": "Malawian Kwacha", "mxn": "Mexican Peso", "mxv": "", "myr": "Malaysian Ringgit", "mzm": "Mozambican Metical", "mzn": "Mozambican Metical", "nad": "Namibian Dollar", "near": "NEAR Protocol", "neo": "NEO", "nexo": "NEXO", "nft": "NFT", "ngn": "Nigerian Naira", "nio": "Nicaraguan Cordoba", "nlg": "Dutch Guilder", "nok": "Norwegian Krone", "npr": "Nepalese Rupee", "nzd": "New Zealand Dollar", "okb": "Okex", "omr": "Omani Rial", "one": "Menlo One", "op": "Optimism", "ordi": "", "pab": "Panamanian Balboa", "paxg": "PAX Gold", "pen": "Peruvian Sol", "pepe": "", "pgk": "Papua New Guinean Kina", "php": "Philippine Peso", "pkr": "Pakistani Rupee", "pln": "Polish Zloty", "pte": "Portuguese Escudo", "pyg": "Paraguayan Guarani", "qar": "Qatari Riyal", "qnt": "Quant", "qtum": "QTUM", "rol": "Romanian Leu", "ron": "Romanian Leu", "rpl": "Rocket Pool", "rsd": "Serbian Dinar", "rub": "Russian Ruble", "rune": "THORChain (ERC20)", "rvn": "Ravencoin", "rwf": "Rwandan Franc", "sand": "The Sandbox", "sar": "Saudi Arabian Riyal", "sbd": "Solomon Islander Dollar", "scr": "Seychellois Rupee", "sdd": "Sudanese Dinar", "sdg": "Sudanese Pound", "sek": "Swedish Krona", "sgd": "Singapore Dollar", "shib": "Shiba Inu", "shp": "Saint Helenian Pound", "sit": "Slovenian Tolar", "skk": "Slovak Koruna", "sle": "Sierra Leonean Leone", "sll": "Sierra Leonean Leone", "snx": "Synthetix Network", "sol": "Solana", "sos": "Somali Shilling", "spl": "Seborgan Luigino", "srd": "Surinamese Dollar", "srg": "Surinamese Guilder", "std": "Sao Tomean Dobra", "stn": "Sao Tomean Dobra", "stx": "Stacks", "sui": "Sui", "svc": "Salvadoran Colon", "syp": "Syrian Pound", "szl": "Swazi Lilangeni", "thb": "Thai Baht", "theta": "Theta", "tjs": "Tajikistani Somoni", "tmm": "Turkmenistani Manat", "tmt": "Turkmenistani Manat", "tnd": "Tunisian Dinar", "ton": "Tokamak Network", "top": "Tongan Pa'anga", "trl": "Turkish Lira", "trx": "TRON", "try": "Turkish Lira", "ttd": "Trinidadian Dollar", "tusd": "True USD", "tvd": "Tuvaluan Dollar", "twd": "Taiwan New Dollar", "twt": "Trust Wallet Token", "tzs": "Tanzanian Shilling", "uah": "Ukrainian Hryvnia", "ugx": "Ugandan Shilling", "uni": "Uniswap", "usd": "US Dollar", "usdc": "USDC", "usdd": "", "usdp": "USDP Stablecoin", "usdt": "Tether", "uyu": "Uruguayan Peso", "uzs": "Uzbekistani Som", "val": "Vatican City Lira", "veb": "Venezuelan Bolívar", "ved": "", "vef": "Venezuelan Bolívar", "ves": "Venezuelan Bolívar", "vet": "Vechain", "vnd": "Vietnamese Dong", "vuv": "Ni-Vanuatu Vatu", "waves": "Waves", "wemix": "WEMIX", "woo": "WOO Network", "wst": "Samoan Tala", "xaf": "Central African CFA Franc BEAC", "xag": "Silver Ounce", "xau": "Gold Ounce", "xaut": "Tether Gold", "xbt": "", "xcd": "East Caribbean Dollar", "xch": "Chia", "xdc": "XDC Network", "xdr": "IMF Special Drawing Rights", "xec": "Eternal Coin", "xem": "NEM", "xlm": "Stellar Lumen", "xmr": "Monero", "xof": "CFA Franc", "xpd": "Palladium Ounce", "xpf": "CFP Franc", "xpt": "Platinum Ounce", "xrp": "Ripple", "xtz": "Tezos", "yer": "Yemeni Rial", "zar": "South African Rand", "zec": "ZCash", "zil": "Zilliqa", "zmk": "Zambian Kwacha", "zmw": "Zambian Kwacha", "zwd": "Zimbabwean Dollar", "zwg": "", "zwl": "Zimbabwean Dollar" }

src/tools/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { tool as emailNormalizer } from './email-normalizer';
55
import { tool as bounceParser } from './bounce-parser';
66
import { tool as codeHighlighter } from './code-highlighter';
77
import { tool as colorWheel } from './color-wheel';
8+
import { tool as currencyConverter } from './currency-converter';
89

910
import { tool as cssXpathConverter } from './css-xpath-converter';
1011
import { tool as cssSelectorsMemo } from './css-selectors-memo';
@@ -145,6 +146,7 @@ export const toolsByCategory: ToolCategory[] = [
145146
xmlToJson,
146147
jsonToXml,
147148
markdownToHtml,
149+
currencyConverter,
148150
],
149151
},
150152
{

0 commit comments

Comments
 (0)