Skip to content

Commit

Permalink
Merge branch 'main' of github.com:EKOKEtoken/marketplace-dapp
Browse files Browse the repository at this point in the history
  • Loading branch information
chiararovis committed Oct 4, 2024
2 parents f4e154c + a9ef9b8 commit d73e450
Show file tree
Hide file tree
Showing 9 changed files with 476 additions and 161 deletions.
10 changes: 10 additions & 0 deletions sitemap.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,14 @@
<lastmod>2024-08-30</lastmod>
<priority>1.00</priority>
</url>
<url>
<loc>https://dapp.ekoketoken.com/marketplace</loc>
<lastmod>2024-08-30</lastmod>
<priority>1.00</priority>
</url>
<url>
<loc>https://dapp.ekoketoken.com/timeline</loc>
<lastmod>2024-08-30</lastmod>
<priority>1.00</priority>
</url>
</urlset>
5 changes: 5 additions & 0 deletions src/js/components/App/Routes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 = () => (
<>
Expand All @@ -18,6 +19,10 @@ const AppRouter = () => (
path={Route.url(Route.MARKETPLACE)}
element={<Marketplace />}
/>
<RouterRoute
path={`${Route.url(Route.MARKETPLACE_CONTRACT)}/:id`}
element={<ContractPage />}
/>
<RouterRoute path={Route.url(Route.TIMELINE)} element={<Timeline />} />
<RouterRoute
path={Route.url(Route.USER_STORIES)}
Expand Down
43 changes: 43 additions & 0 deletions src/js/components/App/pages/Marketplace/pages/Contract.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
import * as React from 'react';
import { useParams } from 'react-router-dom';

import { Contract } from '../../../../../data/contract';
import { mockedContracts } from '../../../../../data/mock/mocked_real_estate';
import Container from '../../../../reusable/Container';
import RealEstateCard from './Contract/RealEstateCard';
import DemoAlert from '../DemoAlert';
import TokensList from './Contract/TokensList';

const ContractPage = () => {
const { id } = useParams<{ id: string }>();
const [contract, setContract] = React.useState<Contract>();

React.useEffect(() => {
const assocContract = mockedContracts().find(
(contract) => contract.id.toString() === id,
);
if (assocContract) {
setContract(assocContract);
}
}, [id]);

if (!contract) {
return null;
}

return (
<Container.Container>
<DemoAlert />
<Container.FlexResponsiveRow className="gap-4 w-full sm:flex-col-reverse">
<Container.Container className="w-2/6 sm:w-full">
<TokensList contract={contract} />
</Container.Container>
<Container.Container className="flex-1">
<RealEstateCard contract={contract} />
</Container.Container>
</Container.FlexResponsiveRow>
</Container.Container>
);
};

export default ContractPage;
Original file line number Diff line number Diff line change
@@ -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 (
<Container.Card>
<Container.FlexCols className="gap-4">
<Container.FlexResponsiveRow className="gap-4">
<Container.Container>
<img
src={contract.realEstate.image}
alt={contract.realEstate.name}
className="w-full sm:object-cover sm:h-[300px] rounded-lg"
width={300}
height={300}
/>
</Container.Container>
<Container.FlexCols className="gap-2">
<Heading.H1L>{contract.realEstate.name}</Heading.H1L>
<Container.Container className="text-sm text-gray-500">
<Icon.DollarSign
size={16}
className="text-gray-500 mr-2 inline"
/>
{contract.realEstate.price.toLocaleString('en-US', {
style: 'currency',
currency: 'USD',
})}
</Container.Container>
<Container.Container className="text-sm text-gray-500">
<Icon.MapPin size={16} className="inline mr-2" />
{contract.realEstate.address}
</Container.Container>
<Container.Container className="text-sm text-gray-500">
<Icon.Box size={16} className="text-gray-500 mr-2 inline" />
{Math.floor(Math.random() * 6) + 1} Rooms -{' '}
{Math.floor(Math.random() * 2) + 1} Bathrooms
</Container.Container>
</Container.FlexCols>
</Container.FlexResponsiveRow>
<Container.Container>
<span className="text-text">Mortgage payment progress</span>
<ProgressBar
progress={Math.round(installments * Math.random())}
max={installments}
/>
</Container.Container>
<Paragraph.Leading>{contract.realEstate.description}</Paragraph.Leading>
</Container.FlexCols>
</Container.Card>
);
};

export default RealEstateCard;
Original file line number Diff line number Diff line change
@@ -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 (
<Container.Card className="px-0 py-0 pt-4">
<Heading.H2 className="px-4">Tokens for sale</Heading.H2>
<Container.FlexCols>
{tokens.map((token) => (
<TokenItem key={token.id} {...token} />
))}
</Container.FlexCols>
</Container.Card>
);
};

export default TokensList;
Original file line number Diff line number Diff line change
@@ -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) => (
<Container.Container className="border-y border-gray-300 px-6 py-4">
<Container.FlexRow className="justify-between items-center gap-4">
<Container.Container>
<Heading.H3>Token #{id}</Heading.H3>
<span className="text-sm text-gray-500">
<Icon.DollarSign size={16} className="text-gray-500 mr-2 inline" />
{value.toLocaleString('en-US', {
style: 'currency',
currency: 'USD',
})}
</span>
</Container.Container>
<Container.Container>
<Button.Primary disabled>Buy Token</Button.Primary>
</Container.Container>
</Container.FlexRow>
</Container.Container>
);

export default TokenItem;
Loading

0 comments on commit d73e450

Please sign in to comment.