Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4,284 changes: 4,058 additions & 226 deletions fullstack/task/.pnp.cjs

Large diffs are not rendered by default.

Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1 change: 1 addition & 0 deletions fullstack/task/packages/client/.env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
VITE_SERVER_URL=http://127.0.0.1:4001
5 changes: 5 additions & 0 deletions fullstack/task/packages/client/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
### Graphql Codegen

To generate graphql types and hooks, run following command, from client root:

`yarn graphql-codegen`
18 changes: 18 additions & 0 deletions fullstack/task/packages/client/codegen.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { CodegenConfig } from '@graphql-codegen/cli';
import 'dotenv/config';

const config: CodegenConfig = {
schema: `${process.env.VITE_SERVER_URL}/graphql`,
documents: ['src/**/*.gql'],
generates: {
'./src/__generated__/graphql.tsx': {
plugins: ['typescript', 'typescript-operations', 'typescript-react-apollo'],
config: {
withHooks: true,
},
},
},
ignoreNoDocuments: true,
};

export default config;
8 changes: 8 additions & 0 deletions fullstack/task/packages/client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
"version": "1.0.0",
"dependencies": {
"@apollo/client": "3.7.10",
"ag-grid-community": "^33.3.2",
"ag-grid-react": "^33.3.2",
"dotenv": "^16.5.0",
"graphql": "16.6.0",
"graphql-tag": "2.12.6",
"graphql-ws": "5.12.0",
Expand All @@ -17,6 +20,11 @@
"@babel/core": "7.23.0",
"@dishboard/eslint-config": "1.0.0",
"@dishboard/jest-config": "1.0.0",
"@graphql-codegen/cli": "^5.0.7",
"@graphql-codegen/client-preset": "^4.8.2",
"@graphql-codegen/typescript": "^4.1.6",
"@graphql-codegen/typescript-operations": "^4.6.1",
"@graphql-codegen/typescript-react-apollo": "^4.3.3",
"@types/jest": "28.1.8",
"@types/react": "18.0.17",
"@types/react-dom": "18.0.6",
Expand Down
4 changes: 3 additions & 1 deletion fullstack/task/packages/client/src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { ExchangeRateTable } from './components/ExchangeRateTable/ExchangeRateTable';

function App() {
return <p>TODO</p>;
return <ExchangeRateTable />;
}

export default App;
110 changes: 110 additions & 0 deletions fullstack/task/packages/client/src/__generated__/graphql.tsx

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { AgGridReact } from 'ag-grid-react';
import { useMemo } from 'react';
import { timeDiffToMinutes } from '../../utils/timeDiffToMinutes';
import { useExchangeRateQuery } from '../../__generated__/graphql';

export const ExchangeRateTable = () => {
const { loading, data, error } = useExchangeRateQuery();

const ratesWithTimeDiff = useMemo(() => {
if (!data) {
return [];
}

const date = new Date();

return data.exchangeRates.map((item) => ({
...item,
fetched: timeDiffToMinutes(date, new Date(item.createdAtUtc)),
}));
}, [data?.exchangeRates]);

if (loading) {
return <div>loading...</div>;
}

if (error) {
return <div>oops! something went wrong</div>;
}

if (!data) {
return <div>No data found</div>;
}

return (
<div style={{ width: '100%', height: '500px' }}>
<AgGridReact
rowData={ratesWithTimeDiff}
columnDefs={[
{ field: 'country' },
{ field: 'currency' },
{ field: 'currencyCode' },
{ field: 'rate' },
{ field: 'fetched' },
]}
defaultColDef={{ flex: 1 }}
/>
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
query ExchangeRate {
exchangeRates {
currency
createdAtUtc
rate
country
currencyCode
}
}
5 changes: 4 additions & 1 deletion fullstack/task/packages/client/src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,12 @@ import React from 'react';
import ReactDOM from 'react-dom/client';
import { ApolloClient, ApolloProvider, InMemoryCache } from '@apollo/client';
import App from './App';
import { AllCommunityModule, ModuleRegistry } from 'ag-grid-community';

ModuleRegistry.registerModules([AllCommunityModule]);

const client = new ApolloClient({
uri: 'http://localhost:4000/graphql',
uri: `${import.meta.env.VITE_SERVER_URL}/graphql`,
cache: new InMemoryCache(),
});

Expand Down
11 changes: 11 additions & 0 deletions fullstack/task/packages/client/src/utils/timeDiffToMinutes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
export const timeDiffToMinutes = (now: Date, compareTo: Date): string => {
const diff = now.getTime() - compareTo.getTime();

const minutesDiff = Math.floor(diff / 1000 / 60);

if (minutesDiff <= 0) {
return '< minute ago';
}

return `${minutesDiff} minutes ago`;
};
8 changes: 8 additions & 0 deletions fullstack/task/packages/client/src/vite-env.d.ts
Original file line number Diff line number Diff line change
@@ -1 +1,9 @@
/// <reference types="vite/client" />

interface ImportMetaEnv {
readonly VITE_SERVER_URL: string;
}

interface ImportMeta {
readonly env: ImportMetaEnv;
}
2 changes: 1 addition & 1 deletion fullstack/task/packages/client/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,6 @@

"baseUrl": "./"
},
"include": ["src"],
"include": ["src", "codegen.ts"],
"references": [{ "path": "./tsconfig.node.json" }]
}
2 changes: 1 addition & 1 deletion fullstack/task/packages/client/tsconfig.node.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@
"moduleResolution": "Node",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
"include": ["vite.config.ts", "codegen.ts"]
}
2 changes: 2 additions & 0 deletions fullstack/task/packages/server/.env
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ GQL_PLAYGROUND=true
GQL_INTROSPECTION=true

PORT=4001

CNB_API_URL=https://api.cnb.cz/cnbapi
12 changes: 8 additions & 4 deletions fullstack/task/packages/server/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,14 @@ Run `docker login`.

### 4. Create and start the database

- If this is your first-time setup - run `yarn server db-create` (from the root workspace `fullstack/task`). This will create (and overwrite!) a docker container for the database.
- Otherwise, run the docker container that was created during the first-time setup.
- If this is your first-time setup - run `yarn server db-create` (from the root workspace `fullstack/task`). This will create (and overwrite!) a docker container for the database.
- Otherwise, run the docker container that was created during the first-time setup.

### 5. Start the server
### 5. Boot up a Redis instance

Run `docker-compose up -d` from the root of server.

### 6. Start the server

Run `yarn server start` from the root workspace.

Expand All @@ -41,6 +45,6 @@ First, generate the migration. Make sure to use a descriptive name, like in a co
yarn server migration -c generate --name migration-name
```

This will create a file describing all the changes to the database, s.t. it can be replicated or reverted easily.
This will create a file describing all the changes to the database, s.t. it can be replicated or reverted easily.

All pending migrations are ran automatically when the server starts.
6 changes: 6 additions & 0 deletions fullstack/task/packages/server/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
services:
redis:
image: redis:latest
container_name: redis
ports:
- '6379:6379'
3 changes: 2 additions & 1 deletion fullstack/task/packages/server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"@tuya/tuya-connector-nodejs": "2.1.2",
"apollo-server-core": "3.11.1",
"apollo-server-express": "3.10.2",
"axios": "1.3.4",
"axios": "^1.10.0",
"bcrypt": "5.1.0",
"class-transformer": "0.5.1",
"class-validator": "0.13.2",
Expand All @@ -36,6 +36,7 @@
"graphql": "16.6.0",
"graphql-subscriptions": "2.0.0",
"graphql-ws": "5.12.0",
"ioredis": "^5.6.1",
"mqtt": "4.3.7",
"passport": "0.6.0",
"passport-jwt": "4.0.1",
Expand Down
20 changes: 6 additions & 14 deletions fullstack/task/packages/server/schema.gql
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@
# THIS FILE WAS AUTOMATICALLY GENERATED (DO NOT MODIFY)
# ------------------------------------------------------

type Example {
type ExchangeRate {
id: ID!
createdAtUtc: DateTime!
updatedAtUtc: DateTime
deleteDateUtc: DateTime
version: Int!
name: String!
value: String!
country: String!
currency: String!
currencyCode: String!
rate: Float!
}

"""
Expand All @@ -18,15 +20,5 @@ A date-time string at UTC, such as 2019-12-03T09:54:33Z, compliant with the date
scalar DateTime

type Query {
exchangeRates: String!
exampleByName(name: String!): Example
}

type Mutation {
createExample(data: CreateExampleInputType!): Example!
}

input CreateExampleInputType {
name: String!
value: String!
exchangeRates: [ExchangeRate!]!
}
4 changes: 2 additions & 2 deletions fullstack/task/packages/server/src/app.module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ import { ConfigModule } from '@nestjs/config';
import { GraphQLModule } from '@nestjs/graphql';
import { TypeOrmModule } from '@nestjs/typeorm';
import { graphqlConfig, typeormConfig } from './config';
import { modules } from './entity-modules';
import { ExchangeRateModule } from './services/exchange-rate/exchange-rate.module';
import { RedisService } from './redis/redis.service';

@Module({
imports: [
Expand All @@ -14,8 +14,8 @@ import { ExchangeRateModule } from './services/exchange-rate/exchange-rate.modul
TypeOrmModule.forRoot(typeormConfig),
GraphQLModule.forRoot(graphqlConfig),
ExchangeRateModule,
...modules,
],
controllers: [],
providers: [RedisService],
})
export class AppModule {}
Loading