diff --git a/sitemap.xml b/sitemap.xml index 0f3a66a..171b043 100644 --- a/sitemap.xml +++ b/sitemap.xml @@ -11,4 +11,14 @@ 2024-08-30 1.00 + + https://dapp.ekoketoken.com/marketplace + 2024-08-30 + 1.00 + + + https://dapp.ekoketoken.com/timeline + 2024-08-30 + 1.00 + diff --git a/src/js/components/App/Routes.tsx b/src/js/components/App/Routes.tsx index 4f3a023..f841985 100644 --- a/src/js/components/App/Routes.tsx +++ b/src/js/components/App/Routes.tsx @@ -7,6 +7,7 @@ import Timeline from './pages/Timeline'; import UserStories from './pages/UserStories'; import SeoEngine from '../SeoEngine'; import Marketplace from './pages/Marketplace'; +import ContractPage from './pages/Marketplace/pages/Contract'; const AppRouter = () => ( <> @@ -18,6 +19,10 @@ const AppRouter = () => ( path={Route.url(Route.MARKETPLACE)} element={} /> + } + /> } /> { + const { id } = useParams<{ id: string }>(); + const [contract, setContract] = React.useState(); + + React.useEffect(() => { + const assocContract = mockedContracts().find( + (contract) => contract.id.toString() === id, + ); + if (assocContract) { + setContract(assocContract); + } + }, [id]); + + if (!contract) { + return null; + } + + return ( + + + + + + + + + + + + ); +}; + +export default ContractPage; diff --git a/src/js/components/App/pages/Marketplace/pages/Contract/RealEstateCard.tsx b/src/js/components/App/pages/Marketplace/pages/Contract/RealEstateCard.tsx new file mode 100644 index 0000000..ad148e0 --- /dev/null +++ b/src/js/components/App/pages/Marketplace/pages/Contract/RealEstateCard.tsx @@ -0,0 +1,68 @@ +import * as React from 'react'; +import * as Icon from 'react-feather'; + +import { Contract } from '../../../../../../data/contract'; +import Container from '../../../../../reusable/Container'; +import Heading from '../../../../../reusable/Heading'; +import Paragraph from '../../../../../reusable/Paragraph'; +import ProgressBar from '../../../../../reusable/ProgressBar'; + +const INSTALLMENT_VALUE = 100; + +interface Props { + contract: Contract; +} + +const RealEstateCard = ({ contract }: Props) => { + const installments = contract.realEstate.price / INSTALLMENT_VALUE; + + return ( + + + + + {contract.realEstate.name} + + + {contract.realEstate.name} + + + {contract.realEstate.price.toLocaleString('en-US', { + style: 'currency', + currency: 'USD', + })} + + + + {contract.realEstate.address} + + + + {Math.floor(Math.random() * 6) + 1} Rooms -{' '} + {Math.floor(Math.random() * 2) + 1} Bathrooms + + + + + Mortgage payment progress + + + {contract.realEstate.description} + + + ); +}; + +export default RealEstateCard; diff --git a/src/js/components/App/pages/Marketplace/pages/Contract/TokensList.tsx b/src/js/components/App/pages/Marketplace/pages/Contract/TokensList.tsx new file mode 100644 index 0000000..cb8e19d --- /dev/null +++ b/src/js/components/App/pages/Marketplace/pages/Contract/TokensList.tsx @@ -0,0 +1,33 @@ +import * as React from 'react'; + +import { Contract } from '../../../../../../data/contract'; +import Container from '../../../../../reusable/Container'; +import Heading from '../../../../../reusable/Heading'; +import TokenItem from './TokensList/TokenItem'; + +interface Props { + contract: Contract; +} + +const INSTALLMENT_VALUE = 100; + +const TokensList = ({ contract }: Props) => { + const tokenValue = contract.realEstate.price / INSTALLMENT_VALUE; + const tokens = Array.from({ length: 10 }, (_, i) => ({ + id: i, + value: tokenValue, + })); + + return ( + + Tokens for sale + + {tokens.map((token) => ( + + ))} + + + ); +}; + +export default TokensList; diff --git a/src/js/components/App/pages/Marketplace/pages/Contract/TokensList/TokenItem.tsx b/src/js/components/App/pages/Marketplace/pages/Contract/TokensList/TokenItem.tsx new file mode 100644 index 0000000..a65adfe --- /dev/null +++ b/src/js/components/App/pages/Marketplace/pages/Contract/TokensList/TokenItem.tsx @@ -0,0 +1,33 @@ +import * as React from 'react'; +import * as Icon from 'react-feather'; + +import Container from '../../../../../../reusable/Container'; +import Heading from '../../../../../../reusable/Heading'; +import Button from '../../../../../../reusable/Button'; + +interface Props { + id: number; + value: number; +} + +const TokenItem = ({ id, value }: Props) => ( + + + + Token #{id} + + + {value.toLocaleString('en-US', { + style: 'currency', + currency: 'USD', + })} + + + + Buy Token + + + +); + +export default TokenItem; diff --git a/src/js/components/App/pages/Timeline/TimelineSvg.tsx b/src/js/components/App/pages/Timeline/TimelineSvg.tsx index 9200be5..1c7f3ca 100644 --- a/src/js/components/App/pages/Timeline/TimelineSvg.tsx +++ b/src/js/components/App/pages/Timeline/TimelineSvg.tsx @@ -37,163 +37,163 @@ const Timeline = () => { > - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + { height={899.999994} fillOpacity={1} /> - + { fillRule="nonzero" /> - + { fillRule="nonzero" /> - + { fillOpacity={1} fillRule="nonzero" /> - + { fillOpacity={1} fillRule="nonzero" /> - + { fillOpacity={1} fillRule="nonzero" /> - + { fillOpacity={1} fillRule="nonzero" /> - + { fillOpacity={1} fillRule="nonzero" /> - - + + { - - + + { - - + + { - - + + { - - + + { - - + + { - + { - + { fillRule="nonzero" /> - + { fillOpacity={1} fillRule="evenodd" /> - + { fillRule="evenodd" /> - + { fillOpacity={1} fillRule="evenodd" /> - + { - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + - + @@ -2078,120 +2078,198 @@ const Timeline = () => { - + - + - + - + - + - + - + - + - + + + + + + + + + + + + + + + + + + + + - + - + - + - + - + - + - + + + + + + + + - + - + + + + + + + + + + + + + + + - + - + - + + + + + + - + - + + + + + + + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -5759,7 +5837,7 @@ const Timeline = () => { fillOpacity={1} fillRule="evenodd" /> - + { fillRule="evenodd" /> - + ) => ( ); +const H1L = (props: React.HTMLProps) => ( +

+ {props.children} +

+); + const H2 = (props: React.HTMLProps) => (

) => ( export default { H1, + H1L, H2, H3, H4, diff --git a/src/js/components/reusable/ProgressBar.tsx b/src/js/components/reusable/ProgressBar.tsx new file mode 100644 index 0000000..7720556 --- /dev/null +++ b/src/js/components/reusable/ProgressBar.tsx @@ -0,0 +1,33 @@ +import * as React from 'react'; + +interface Props { + progress: number; + max: number; + percentage?: boolean; +} + +const ProgressBar = (props: Props) => { + const percentage = Math.round((props.progress * 100) / props.max); + let label = `${props.progress}/${props.max}`; + if (props.percentage) { + label = `${percentage.toString()}%`; + } + + const className = `${ + props.progress > 0 ? 'bg-brand' : '' + } text-lg font-medium text-blue-100 text-center p-0.5 leading-none rounded-full`; + + const fillerStyles = { + width: `${percentage}%`, + }; + + return ( +
+
+ {label} +
+
+ ); +}; + +export default ProgressBar;