Skip to content

Commit

Permalink
Merge pull request #1 from divance-cryptos/add-exchanges-page
Browse files Browse the repository at this point in the history
1 - Add exchanges page
  • Loading branch information
miohtama authored Sep 24, 2021
2 parents 692d180 + 1b1086a commit cc217f7
Show file tree
Hide file tree
Showing 12 changed files with 19,121 additions and 888 deletions.
19,562 changes: 18,678 additions & 884 deletions package-lock.json

Large diffs are not rendered by default.

33 changes: 30 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,33 @@
"check": "svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "prettier --check --plugin-search-dir=. . && eslint --ignore-path .gitignore .",
"format": "prettier --write --plugin-search-dir=. ."
"format": "prettier --write --plugin-search-dir=. .",
"test": "jest",
"test:watch": "npm test -- --watch"
},
"jest": {
"transform": {
"^.+\\.svelte$": [
"svelte-jester",
{
"preprocess": true
}
],
"^.+\\.ts$": "ts-jest",
"^.+\\.js$": "babel-jest"
},
"moduleFileExtensions": [
"js",
"ts",
"svelte"
]
},
"devDependencies": {
"@babel/preset-env": "^7.15.6",
"@sveltejs/adapter-node": "^1.0.0-next.36",
"@sveltejs/adapter-static": "^1.0.0-next.13",
"@sveltejs/kit": "next",
"@testing-library/jest-dom": "^5.14.1",
"@types/cookie": "^0.4.0",
"@typescript-eslint/eslint-plugin": "^4.19.0",
"@typescript-eslint/parser": "^4.19.0",
Expand All @@ -24,10 +45,16 @@
"prettier-plugin-svelte": "^2.2.0",
"svelte": "^3.42.5",
"svelte-check": "^2.0.0",
"svelte-preprocess": "^4.0.0",
"svelte-preprocess": "^4.9.4",
"svelte-time": "^0.4.0",
"tslib": "^2.0.0",
"typescript": "^4.0.0"
"typescript": "^4.0.0",
"@testing-library/svelte": "^3.0.0",
"@types/jest": "^26.0.14",
"babel-jest": "^26.5.2",
"jest": "^26.5.2",
"svelte-jester": "^1.1.5",
"ts-jest": "^26.4.1"
},
"type": "module",
"dependencies": {
Expand Down
16 changes: 16 additions & 0 deletions src/__tests__/routes/exchanges.test.ts
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();
})
})

77 changes: 77 additions & 0 deletions src/lib/form/Form.svelte
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}



21 changes: 21 additions & 0 deletions src/lib/form/Input.svelte
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" />
24 changes: 24 additions & 0 deletions src/lib/form/InputEmail.svelte
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>
4 changes: 4 additions & 0 deletions src/lib/header/Navbar.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,10 @@
<a rel="external" class="nav-link" href="/datasets">Datasets</a>
</li>

<!-- <li class="nav-item">
<a rel="external" class="nav-link" href="/exchanges">Exchanges</a>
</li> -->

<li class="nav-item">
<a rel="external" class="nav-link" href="https://tradingstrategy.ai/docs/index.html">Documentation</a>
</li>
Expand Down
25 changes: 25 additions & 0 deletions src/lib/helpers/utils.ts
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();
}
105 changes: 105 additions & 0 deletions src/lib/table/Table.svelte
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>
49 changes: 49 additions & 0 deletions src/routes/credentials.svelte
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>
Loading

0 comments on commit cc217f7

Please sign in to comment.