diff --git a/.eslintrc.json b/.eslintrc.json
index 61cc8d2b..6a4aa2e6 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -101,6 +101,8 @@
"!src/apps/deposit/**",
"!src/apps/leaderboard/",
"!src/apps/leaderboard/**",
+ "!src/apps/blitz/",
+ "!src/apps/blitz/**",
"public/" // Ignore public folder
],
"settings": {
diff --git a/src/apps/blitz/components/RandomAvatar/RandomAvatar.tsx b/src/apps/blitz/components/RandomAvatar/RandomAvatar.tsx
new file mode 100644
index 00000000..4244fa95
--- /dev/null
+++ b/src/apps/blitz/components/RandomAvatar/RandomAvatar.tsx
@@ -0,0 +1,50 @@
+import Avatar from 'boring-avatars';
+
+// types
+import { AvatarVariantType } from '../../../../types';
+
+type RandomAvatarProps = {
+ name: string;
+ variant?: string;
+ isRandomVariant?: boolean;
+};
+
+const RandomAvatar = ({
+ name,
+ variant,
+ isRandomVariant,
+}: RandomAvatarProps) => {
+ const variants: AvatarVariantType[] = [
+ 'marble',
+ 'beam',
+ 'pixel',
+ 'sunset',
+ 'ring',
+ 'bauhaus',
+ ];
+
+ const randomVariant: AvatarVariantType =
+ variants[Math.floor(Math.random() * variants.length)];
+
+ const avatarVariant = () => {
+ if (isRandomVariant && !variant) {
+ return randomVariant;
+ }
+ if (variant) {
+ return variant as AvatarVariantType;
+ }
+ return 'marble';
+ };
+
+ return (
+
+ );
+};
+
+export default RandomAvatar;
diff --git a/src/apps/blitz/components/TimeClock/TimeClock.tsx b/src/apps/blitz/components/TimeClock/TimeClock.tsx
new file mode 100644
index 00000000..56a4e7aa
--- /dev/null
+++ b/src/apps/blitz/components/TimeClock/TimeClock.tsx
@@ -0,0 +1,84 @@
+/* eslint-disable react/no-unstable-nested-components */
+import { differenceInMinutes, differenceInSeconds, isPast } from 'date-fns';
+import { useEffect, useState } from 'react';
+
+const DUMMY_END_DATE = new Date(2025, 1, 5, 18, 10, 0); // Move outside component
+
+type TimeClockProps = { classname?: string };
+
+const TimeClock = ({ classname }: TimeClockProps) => {
+ const [isDesktop, setIsDesktop] = useState(window.innerWidth > 1023);
+
+ const calculateTimeLeft = () => {
+ const now = new Date();
+ const minutes = Math.max(0, differenceInMinutes(DUMMY_END_DATE, now));
+ const seconds = Math.max(0, differenceInSeconds(DUMMY_END_DATE, now) % 60);
+ return { minutes, seconds };
+ };
+
+ const [timeRemaining, setTimeRemaining] = useState(calculateTimeLeft);
+
+ useEffect(() => {
+ const interval = setInterval(() => {
+ setTimeRemaining(calculateTimeLeft());
+ }, 1000);
+
+ return () => clearInterval(interval);
+ }, []);
+
+ useEffect(() => {
+ const handleResize = () => {
+ setIsDesktop(window.innerWidth > 1023);
+ };
+
+ window.addEventListener('resize', handleResize);
+
+ return () => {
+ window.removeEventListener('resize', handleResize);
+ };
+ }, []);
+
+ const formattedMinutes = timeRemaining.minutes.toString().padStart(2, '0');
+ const formattedSeconds = timeRemaining.seconds.toString().padStart(2, '0');
+
+ const timeMap = Array.from(formattedMinutes + formattedSeconds);
+
+ const DigitComponent = ({ time }: { time: string }) => {
+ return (
+
+
+
+ {isPast(DUMMY_END_DATE) ? 0 : time}
+
+
+
+ );
+ };
+
+ return (
+
+
+
+
+
+
+
+ {isDesktop ? 'minutes' : 'min'}
+
+
+
+
+
+
+
+
+ {isDesktop ? 'seconds' : 'sec'}
+
+
+
+ );
+};
+
+export default TimeClock;
diff --git a/src/apps/blitz/components/TokenPriceTime/TokenPriceTime.tsx b/src/apps/blitz/components/TokenPriceTime/TokenPriceTime.tsx
new file mode 100644
index 00000000..32a15ee9
--- /dev/null
+++ b/src/apps/blitz/components/TokenPriceTime/TokenPriceTime.tsx
@@ -0,0 +1,37 @@
+import TokenPotIcon from '../../images/token_pot_icon.svg';
+import TimeClock from '../TimeClock/TimeClock';
+import TokenPriceUpdate from '../TokenPriceUpdate/TokenPriceUpdate';
+import Body from '../Typography/Body';
+
+const TokenPriceTime = () => {
+ const DUMMY_TOKEN_PRICE = '120,582.08';
+ const DUMMY_TOKEN_AMOUNT = 3515;
+ const DUMMY_TOKEN_SYMBOL = 'RBTC';
+ const DUMMY_TOKEN_WON_CLAIMABLE = 562;
+
+ return (
+
+
+
+
+
+ ${DUMMY_TOKEN_PRICE}
+
+
+
+
+
+

+
+ {DUMMY_TOKEN_AMOUNT} {DUMMY_TOKEN_SYMBOL} in the Pot!
+
+
+
+ {DUMMY_TOKEN_WON_CLAIMABLE} {DUMMY_TOKEN_SYMBOL} Won{' '}
+
Claim Now!
+
+
+ );
+};
+
+export default TokenPriceTime;
diff --git a/src/apps/blitz/components/TokenPriceUpdate/TokenPriceUpdate.tsx b/src/apps/blitz/components/TokenPriceUpdate/TokenPriceUpdate.tsx
new file mode 100644
index 00000000..0c9444a4
--- /dev/null
+++ b/src/apps/blitz/components/TokenPriceUpdate/TokenPriceUpdate.tsx
@@ -0,0 +1,24 @@
+import RandomToken from '../../images/randomToken.png';
+
+type TokenPriceUpdateProps = { classname?: string };
+
+const TokenPriceUpdate = ({ classname }: TokenPriceUpdateProps) => {
+ const DUMMY_TIME = '3:15pm';
+ return (
+
+

+
+ Token price at{' '}
+ {DUMMY_TIME}
+
+
+ );
+};
+
+export default TokenPriceUpdate;
diff --git a/src/apps/blitz/components/Typography/Body.tsx b/src/apps/blitz/components/Typography/Body.tsx
new file mode 100644
index 00000000..f510eb65
--- /dev/null
+++ b/src/apps/blitz/components/Typography/Body.tsx
@@ -0,0 +1,12 @@
+import { ReactNode } from 'react';
+
+type BodyProps = {
+ children: ReactNode;
+ className?: string;
+};
+
+const Body = ({ children, className }: BodyProps) => {
+ return {children}
;
+};
+
+export default Body;
diff --git a/src/apps/blitz/components/Typography/BodySmall.tsx b/src/apps/blitz/components/Typography/BodySmall.tsx
new file mode 100644
index 00000000..4c2105e5
--- /dev/null
+++ b/src/apps/blitz/components/Typography/BodySmall.tsx
@@ -0,0 +1,12 @@
+import { ReactNode } from 'react';
+
+type BodySmallProps = {
+ children: ReactNode;
+ className?: string;
+};
+
+const BodySmall = ({ children, className }: BodySmallProps) => {
+ return {children}
;
+};
+
+export default BodySmall;
diff --git a/src/apps/blitz/components/Typography/tests/Body.test.tsx b/src/apps/blitz/components/Typography/tests/Body.test.tsx
new file mode 100644
index 00000000..f12dfbee
--- /dev/null
+++ b/src/apps/blitz/components/Typography/tests/Body.test.tsx
@@ -0,0 +1,30 @@
+import renderer, { ReactTestRendererJSON } from 'react-test-renderer';
+
+// components
+import Body from '../Body';
+
+describe('', () => {
+ it('renders correctly', () => {
+ const tree = renderer
+ .create(
+ <>
+
Some regular text.
+ Some red text
+ Some text with font size 23px
+ >
+ )
+ .toJSON();
+
+ expect(tree).toMatchSnapshot();
+
+ const treeElements = tree as ReactTestRendererJSON[];
+
+ expect(treeElements[0].children?.length).toBe(1);
+ expect(treeElements[0].children?.[0]).toBe('Some regular text.');
+ expect(treeElements[0].type).toBe('p');
+ expect(treeElements[0].props.className).toContain('text-base');
+ expect(treeElements[0].props.className).toContain('font-medium');
+ expect(treeElements[1].props.className).toContain('text-red-500');
+ expect(treeElements[2].props.className).toContain('text-[23px]');
+ });
+});
diff --git a/src/apps/blitz/components/Typography/tests/BodySmall.test.tsx b/src/apps/blitz/components/Typography/tests/BodySmall.test.tsx
new file mode 100644
index 00000000..5cdee9ca
--- /dev/null
+++ b/src/apps/blitz/components/Typography/tests/BodySmall.test.tsx
@@ -0,0 +1,32 @@
+import renderer, { ReactTestRendererJSON } from 'react-test-renderer';
+
+// components
+import BodySmall from '../BodySmall';
+
+describe('', () => {
+ it('renders correctly', () => {
+ const tree = renderer
+ .create(
+ <>
+ Some small text.
+ Some red small text
+
+ Some small text with font size 7px
+
+ >
+ )
+ .toJSON();
+
+ expect(tree).toMatchSnapshot();
+
+ const treeElements = tree as ReactTestRendererJSON[];
+
+ expect(treeElements[0].children?.length).toBe(1);
+ expect(treeElements[0].children?.[0]).toBe('Some small text.');
+ expect(treeElements[0].type).toBe('p');
+ expect(treeElements[0].props.className).toContain('text-sm');
+ expect(treeElements[0].props.className).toContain('font-medium');
+ expect(treeElements[1].props.className).toContain('text-red-500');
+ expect(treeElements[2].props.className).toContain('text-[7px]');
+ });
+});
diff --git a/src/apps/blitz/components/Typography/tests/__snapshots__/Body.test.tsx.snap b/src/apps/blitz/components/Typography/tests/__snapshots__/Body.test.tsx.snap
new file mode 100644
index 00000000..27f96970
--- /dev/null
+++ b/src/apps/blitz/components/Typography/tests/__snapshots__/Body.test.tsx.snap
@@ -0,0 +1,21 @@
+// Jest Snapshot v1, https://goo.gl/fbAQLP
+
+exports[`