Skip to content

Commit

Permalink
feat/font-and-url-changes (#13)
Browse files Browse the repository at this point in the history
* feat: GeistVariable font upload

Signed-off-by: michalrozekariane <[email protected]>

* fix: url changed to be only localhost

Signed-off-by: michalrozekariane <[email protected]>

* feat: onBlur tokenName fetch action added

Signed-off-by: michalrozekariane <[email protected]>

* fix: copy text

Signed-off-by: michalrozekariane <[email protected]>

---------

Signed-off-by: michalrozekariane <[email protected]>
  • Loading branch information
michalrozekariane authored Apr 11, 2024
1 parent 15c9694 commit 834cee6
Show file tree
Hide file tree
Showing 9 changed files with 104 additions and 22 deletions.
Binary file added public/fonts/GeistVariableVF.woff2
Binary file not shown.
1 change: 0 additions & 1 deletion src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,6 @@ const App = () => {
<div className="container mx-auto">
<h1 className="mt-20 scroll-m-20 text-center text-4xl font-extrabold tracking-tight lg:text-5xl">{dictionary.title}</h1>
<p className="text-center leading-7 [&:not(:first-child)]:mt-6">{dictionary.description}</p>

<div className="mb-20 mt-5">
<HoldersForm
setTokenId={setTokenId}
Expand Down
23 changes: 21 additions & 2 deletions src/components/HoldersForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ import { zodResolver } from '@hookform/resolvers/zod';
import { Textarea } from '@/components/ui/textarea';
import { parseCSV } from '@/utils/parseCSV';
import { Progress } from '@/components/ui/progress';
import { fetchTokenName } from '@/utils/fetchTokenName';
import { isValidTokenId } from '@/utils/isValidTokenId';

type HoldersFormProps = {
setTokenId: (_tokenId: string) => void;
Expand All @@ -41,6 +43,7 @@ type HoldersFormProps = {
export const HoldersForm = ({ setTokenId, setAccountIds, setShouldFetch, isFetching, fetchedAccountsBalance }: HoldersFormProps) => {
const [accountIdsLength, setAccountIdsLength] = useState(0);
const [progress, setProgress] = useState(0);
const [tokenName, setTokenName] = useState<string>('');
const form = useForm<z.infer<typeof formSchema>>({
resolver: zodResolver(formSchema),
defaultValues: {
Expand All @@ -56,6 +59,12 @@ export const HoldersForm = ({ setTokenId, setAccountIds, setShouldFetch, isFetch
setShouldFetch(true);
};

const handleTokenBlur = async (tokenId: string) => {
if (!isValidTokenId(tokenId)) return;
const tokenName = await fetchTokenName(tokenId, 'mainnet');
setTokenName(tokenName);
};

const calculatePercentage = (current: number, total: number) => (current / total) * 100;

useEffect(() => {
Expand All @@ -75,14 +84,24 @@ export const HoldersForm = ({ setTokenId, setAccountIds, setShouldFetch, isFetch
<FormItem>
<FormLabel>{dictionary.tokenId}</FormLabel>
<FormControl>
<Input data-testid="tokenId" placeholder={dictionary.exampleTokenId} {...field} />
<>
<Input
data-testid="tokenId"
placeholder={dictionary.exampleTokenId}
{...field}
onBlur={(event) => {
field.onBlur();
void handleTokenBlur(event.target.value);
}}
/>
{tokenName && <p className="text-sm text-muted-foreground">{tokenName}</p>}
</>
</FormControl>
<FormMessage />
</FormItem>
)}
/>
</div>

<div className="w-full sm:w-1/3">
<FormField
control={form.control}
Expand Down
43 changes: 25 additions & 18 deletions src/styles/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -20,75 +20,82 @@
@tailwind base;
@tailwind components;
@tailwind utilities;

@layer base {
@font-face {
font-family: 'Geist-Variable';
src: url(/fonts/GeistVariableVF.woff2) format('woff2');
}

:root {
@apply font-geistVariable;
--background: 0 0% 100%;
--foreground: 222.2 84% 4.9%;

--card: 0 0% 100%;
--card-foreground: 222.2 84% 4.9%;

--popover: 0 0% 100%;
--popover-foreground: 222.2 84% 4.9%;

--primary: 222.2 47.4% 11.2%;
--primary-foreground: 210 40% 98%;

--secondary: 210 40% 96.1%;
--secondary-foreground: 222.2 47.4% 11.2%;

--muted: 210 40% 96.1%;
--muted-foreground: 215.4 16.3% 46.9%;

--accent: 210 40% 96.1%;
--accent-foreground: 222.2 47.4% 11.2%;

--destructive: 0 84.2% 60.2%;
--destructive-foreground: 210 40% 98%;

--border: 214.3 31.8% 91.4%;
--input: 214.3 31.8% 91.4%;
--ring: 222.2 84% 4.9%;

--radius: 0.5rem;
}

.dark {
--background: 222.2 84% 4.9%;
--foreground: 210 40% 98%;

--card: 222.2 84% 4.9%;
--card-foreground: 210 40% 98%;

--popover: 222.2 84% 4.9%;
--popover-foreground: 210 40% 98%;

--primary: 210 40% 98%;
--primary-foreground: 222.2 47.4% 11.2%;

--secondary: 217.2 32.6% 17.5%;
--secondary-foreground: 210 40% 98%;

--muted: 217.2 32.6% 17.5%;
--muted-foreground: 215 20.2% 65.1%;

--accent: 217.2 32.6% 17.5%;
--accent-foreground: 210 40% 98%;

--destructive: 0 62.8% 30.6%;
--destructive-foreground: 210 40% 98%;

--border: 217.2 32.6% 17.5%;
--input: 217.2 32.6% 17.5%;
--ring: 212.7 26.8% 83.9%;
}
}

@layer base {
* {
@apply border-border;
}

body {
@apply bg-background text-foreground;
}
Expand Down
2 changes: 2 additions & 0 deletions src/utils/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,5 @@
*
*/
export const defaultNetwork = 'mainnet';

export const nodeUrl = 'https://mainnet-public.mirrornode.hedera.com';
30 changes: 30 additions & 0 deletions src/utils/fetchTokenName.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*-
*
* Hedera Airdrop List Builder
*
* Copyright (C) 2024 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
import { getMirrorNodeUrlForNetwork } from '@/utils/getMirrorNodeURLForNetwork';

export const fetchTokenName = async (tokenId: string, network: string) => {
const response = await fetch(`${getMirrorNodeUrlForNetwork(network)}/api/v1/tokens/${tokenId}`, {
method: 'GET',
headers: {},
});

const { name } = await response.json();
return name;
};
23 changes: 23 additions & 0 deletions src/utils/isValidTokenId.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*-
*
* Hedera Airdrop List Builder
*
* Copyright (C) 2024 Hedera Hashgraph, LLC
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
export const isValidTokenId = (tokenId: string): boolean => {
const regex = /^\d\.\d\.\d*$/;
return regex.test(tokenId);
};
3 changes: 3 additions & 0 deletions tailwind.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ module.exports = {
},
},
extend: {
fontFamily: {
geistVariable: ['Geist-Variable', 'sans-serif'],
},
colors: {
border: 'hsl(var(--border))',
input: 'hsl(var(--input))',
Expand Down
1 change: 0 additions & 1 deletion vite.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import * as path from 'path';
// https://vitejs.dev/config/
export default defineConfig({
plugins: [react()],
base: '/airdrop-list-builder/',
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
Expand Down

0 comments on commit 834cee6

Please sign in to comment.