-
Notifications
You must be signed in to change notification settings - Fork 135
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from divance-cryptos/add-exchanges-page
1 - Add exchanges page
- Loading branch information
Showing
12 changed files
with
19,121 additions
and
888 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import '@testing-library/jest-dom'; | ||
import {render, fireEvent} from '@testing-library/svelte'; | ||
import exchanges from '../../routes/exchanges.svelte'; | ||
|
||
describe('Exchanges Page', () => { | ||
it('shows proper heading when rendered exchanges page', () => { | ||
const {getByText} = render(exchanges, { }); | ||
expect(getByText('Exchanges')).toBeInTheDocument(); | ||
}) | ||
|
||
it('testing that a typo exchange word is not in the page', () => { | ||
const {queryByText} = render(exchanges, { }); | ||
expect(queryByText('Exchanses')).toBeNull(); | ||
}) | ||
}) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,77 @@ | ||
<script lang="ts"> | ||
import Input from "./Input.svelte"; | ||
import InputEmail from "./InputEmail.svelte"; | ||
export let onSubmit; | ||
export let fields; | ||
export let formErrors = {}; | ||
export let submitted: boolean = false; | ||
function isFormValid(data: {[fieldName: string]: any}): boolean { | ||
let isValid: boolean = true; | ||
const isRequiredFieldValid = (value) => { | ||
return value != null && value !== "" | ||
} | ||
data.forEach((field) => { | ||
if (!isRequiredFieldValid(field)) { | ||
formErrors[field] = { ...formErrors[field], ...{ requiredError: true }}; | ||
isValid = false; | ||
} else { | ||
formErrors[field] = { ...formErrors[field], ...{ requiredError: false }}; | ||
} | ||
}); | ||
return isValid; | ||
} | ||
const clientRequest = async (fields) => { | ||
const response = await fetch('https://httpbin.org/post', { | ||
method: 'POST', | ||
body: JSON.stringify(fields) | ||
}); | ||
const json = await response.json() | ||
const result = JSON.stringify(json) | ||
submitted = true; | ||
console.log(result) | ||
} | ||
const fieldsToObject = (fields) => | ||
fields.reduce((p, c) => ({ ...p, [c.name]: c.value }), {}); | ||
const handleSubmit = () => { | ||
if(isFormValid(fields)) { | ||
clientRequest(fields); | ||
onSubmit(fieldsToObject(fields)); | ||
} | ||
} | ||
</script> | ||
|
||
<style> | ||
:global(input, select) { | ||
margin: 5px; | ||
} | ||
</style> | ||
|
||
|
||
{#if !submitted } | ||
<form on:submit|preventDefault={() => handleSubmit()}> | ||
{#each fields as field} | ||
{#if field.type === 'Input'} | ||
<div class="form-group mb-3"> | ||
<Input bind:value={field.value} label={field.label} placeholder={field.placeholder} required={field.required} formErrors={formErrors} /> | ||
</div> | ||
{:else if field.type === 'Email'} | ||
<div class="form-group mb-3"> | ||
<InputEmail bind:value={field.value} label={field.label} placeholder={field.placeholder} required={field.required} formErrors={formErrors}/> | ||
</div> | ||
{/if} | ||
{/each} | ||
<button type="submit" class="btn btn-primary form-group-api-key-item">Submit</button> | ||
</form> | ||
{:else} | ||
<h3>Please check your email you should have received and email with an Api Key</h3> | ||
{/if} | ||
|
||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<script> | ||
export let value; | ||
export let placeholder; | ||
export let label; | ||
export let name; | ||
export let id; | ||
export let required; | ||
export let errors; | ||
const getStyles = () => { | ||
if(name && errors[name]) { | ||
return `is-invalid` | ||
} | ||
return ``; | ||
} | ||
</script> | ||
|
||
<label for={id}> | ||
{#if required }*{/if} {label} | ||
</label> | ||
<input class={`form-control ${getStyles()}`} bind:value {placeholder} {id} {name} {required} type="text" /> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
<script> | ||
export let value; | ||
export let placeholder; | ||
export let label; | ||
export let name; | ||
export let id; | ||
export let required; | ||
export let errors = {}; | ||
</script> | ||
|
||
<label for={id}> | ||
{#if required }*{/if} {label} | ||
</label> | ||
<input class="form-control" bind:value {placeholder} {id} {name} {required} type="email" /> | ||
<small id="emailHelp" class="form-text text-muted">We'll never share your email with anyone else.</small> | ||
{#if errors[name] && errors[name]} | ||
<p class="error-message">Email is required</p> | ||
{/if} | ||
|
||
<style> | ||
.error-message { | ||
color: red; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
export function formatNumber(n) { | ||
if(n <= 1000) { | ||
return (n/1000).toLocaleString("en", {minimumFractionDigits: 3, maximumFractionDigits: 3}) | ||
} else{ | ||
return (n/1000).toLocaleString("en", {minimumFractionDigits: 0, maximumFractionDigits: 0}) | ||
} | ||
} | ||
|
||
export function formatSize(n) { | ||
if(n <= 1024*1024) { | ||
return (n/(1024*1024)).toLocaleString("en", {minimumFractionDigits: 3, maximumFractionDigits: 3}) | ||
} else{ | ||
return (n/(1024*1024)).toLocaleString("en", {minimumFractionDigits: 0, maximumFractionDigits: 0}) | ||
} | ||
} | ||
|
||
export function formatDownloadLink(validApiKey, key, link) { | ||
if(!validApiKey) { | ||
return "javascript:"; | ||
} | ||
|
||
const url = new URL(link); | ||
url.searchParams.set("api-key", key); | ||
return url.toString(); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
<script> | ||
import { onMount } from 'svelte'; | ||
import { formatNumber } from "../helpers/utils"; | ||
export let rows = []; | ||
let page = 0; | ||
let totalPages = []; | ||
let currentPageRows = []; | ||
let itemsPerPage = 50; | ||
let loading = true; | ||
$: currentPageRows = totalPages.length > 0 ? totalPages[page] : []; | ||
const paginate = (items) => { | ||
const pages = Math.ceil(items.length / itemsPerPage); | ||
const paginatedItems = Array.from({ length: pages }, (_, index) => { | ||
const start = index * itemsPerPage; | ||
return items.slice(start, start + itemsPerPage); | ||
}); | ||
totalPages = [...paginatedItems]; | ||
}; | ||
onMount(() => { | ||
paginate(rows); | ||
}); | ||
const setPage = (p) => { | ||
if (p >= 0 && p < totalPages.length) { | ||
page = p; | ||
} | ||
}; | ||
</script> | ||
|
||
<table class="table table-datasets"> | ||
<thead> | ||
<tr> | ||
<th>id</th> | ||
<th>name</th> | ||
<th>USD Volume</th> | ||
</tr> | ||
</thead> | ||
|
||
<tbody> | ||
{#each currentPageRows as row, i} | ||
<tr> | ||
<td>{row.exchange_id}</td> | ||
<td>{row.human_readable_name}</td> | ||
<td>{formatNumber(row.usd_volume_30d)}</td> | ||
</tr> | ||
{:else} | ||
<tr> | ||
<td colspan="100%"> | ||
<h5 class="text-center">There is no data to display here.</h5> | ||
</td> | ||
</tr> | ||
{/each} | ||
</tbody> | ||
</table> | ||
<nav class="pagination"> | ||
<ul> | ||
<li> | ||
<button | ||
type="button" | ||
class="btn btn-primary form-group-api-key-item s-corywHGE_LaK btn-next-prev" | ||
on:click={() => setPage(page - 1)} | ||
> | ||
PREV | ||
</button> | ||
</li> | ||
|
||
{#each totalPages as page, i} | ||
<li> | ||
<button | ||
type="button" | ||
class="btn btn-primary form-group-api-key-item s-corywHGE_LaK btn-page-number" | ||
on:click={() => setPage(i)} | ||
> | ||
{i + 1} | ||
</button> | ||
</li> | ||
{/each} | ||
|
||
<li> | ||
<button | ||
type="button" | ||
class="btn btn-primary form-group-api-key-item s-corywHGE_LaK btn-next-prev" | ||
on:click={() => setPage(page + 1)} | ||
> | ||
NEXT | ||
</button> | ||
</li> | ||
</ul> | ||
</nav> | ||
|
||
<style> | ||
nav > ul { | ||
list-style-type: none; | ||
display: flex; | ||
} | ||
button { | ||
margin-right: 6px; | ||
} | ||
</style> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,49 @@ | ||
<!-- src/App.svelte --> | ||
<script> | ||
import Form from "../lib/form/Form.svelte"; | ||
// Our field representation, let's us easily specify several inputs | ||
let fields = [ | ||
{ | ||
name: "email", | ||
type: "Email", | ||
value: "", | ||
placeholder: "Enter email...", | ||
label: "Email", | ||
required: true | ||
}, | ||
{ | ||
name: "firstName", | ||
type: "Input", | ||
value: "", | ||
placeholder: "Enter first name...", | ||
label: "First name", | ||
required: true | ||
}, | ||
{ | ||
name: "lastName", | ||
type: "Input", | ||
value: "", | ||
placeholder: "Enter last name...", | ||
label: "Last name", | ||
required: true | ||
}, | ||
]; | ||
let result = {}; | ||
</script> | ||
|
||
<div class="container"> | ||
<div class="row"> | ||
<div class="col-8"> | ||
<div class="card bg-primary shadow-soft border-light px-4 py-5"> | ||
<h1>Request your Api Key</h1> | ||
<Form | ||
onSubmit={(body) => { | ||
result = body; | ||
}} | ||
{fields} /> | ||
</div> | ||
</div> | ||
</div> | ||
</div> |
Oops, something went wrong.