diff --git a/app/graphql/types/query_type.rb b/app/graphql/types/query_type.rb
index f83b3c6..71f146f 100644
--- a/app/graphql/types/query_type.rb
+++ b/app/graphql/types/query_type.rb
@@ -28,5 +28,10 @@ module Types
def buy_crypto_orders
Pundit.policy_scope(current_user, BuyCryptoOrder)
end
+
+ field :stake_orders, StakeOrderType.connection_type, null: false
+ def stake_orders
+ Pundit.policy_scope(current_user, StakeOrder)
+ end
end
end
diff --git a/app/graphql/types/stake_order_type.rb b/app/graphql/types/stake_order_type.rb
new file mode 100644
index 0000000..d8a7c89
--- /dev/null
+++ b/app/graphql/types/stake_order_type.rb
@@ -0,0 +1,16 @@
+# frozen_string_literal: true
+module Types
+ class StakeOrderType < Types::BaseObject
+ implements GraphQL::Types::Relay::Node
+ global_id_field :id
+
+ graphql_name "StakeOrder"
+
+ field :id, ID, null: false
+ field :pool_name, String, null: false
+ field :status, ProcessStatusEnum, null: false
+ field :amount, String, null: false
+ field :created_at, GraphQL::Types::ISO8601DateTime, null: false
+ field :updated_at, GraphQL::Types::ISO8601DateTime, null: false
+ end
+end
diff --git a/app/javascript/__generated__/schema.graphql b/app/javascript/__generated__/schema.graphql
index 4c9fca0..da3eee3 100644
--- a/app/javascript/__generated__/schema.graphql
+++ b/app/javascript/__generated__/schema.graphql
@@ -352,6 +352,27 @@ type Query {
"""
last: Int
): SellCryptoOrderConnection!
+ stakeOrders(
+ """
+ Returns the elements in the list that come after the specified cursor.
+ """
+ after: String
+
+ """
+ Returns the elements in the list that come before the specified cursor.
+ """
+ before: String
+
+ """
+ Returns the first _n_ elements from the list.
+ """
+ first: Int
+
+ """
+ Returns the last _n_ elements from the list.
+ """
+ last: Int
+ ): StakeOrderConnection!
}
type RecordInvalid {
@@ -401,6 +422,45 @@ type SellCryptoOrderEdge {
node: SellCryptoOrder!
}
+type StakeOrder implements Node {
+ amount: String!
+ createdAt: ISO8601DateTime!
+ id: ID!
+ poolName: String!
+ status: ProcessStatus!
+ updatedAt: ISO8601DateTime!
+}
+
+"""
+The connection type for StakeOrder.
+"""
+type StakeOrderConnection {
+ """
+ A list of edges.
+ """
+ edges: [StakeOrderEdge!]!
+
+ """
+ Information to aid in pagination.
+ """
+ pageInfo: PageInfo!
+}
+
+"""
+An edge in a connection.
+"""
+type StakeOrderEdge {
+ """
+ A cursor for use in pagination.
+ """
+ cursor: String!
+
+ """
+ The item at the end of the edge.
+ """
+ node: StakeOrder!
+}
+
type User {
email: String!
firstName: String!
diff --git a/app/javascript/src/Routes.tsx b/app/javascript/src/Routes.tsx
index de22071..b0bc950 100644
--- a/app/javascript/src/Routes.tsx
+++ b/app/javascript/src/Routes.tsx
@@ -16,6 +16,9 @@ export const Routes: FC = () => {
+
+
+
);
};
diff --git a/app/javascript/src/assets/vectors/no_data.svg b/app/javascript/src/assets/vectors/no_data.svg
new file mode 100644
index 0000000..acccecd
--- /dev/null
+++ b/app/javascript/src/assets/vectors/no_data.svg
@@ -0,0 +1,246 @@
+
\ No newline at end of file
diff --git a/app/javascript/src/components/Pool.tsx b/app/javascript/src/components/Pool.tsx
index b51a6c8..e16eca1 100644
--- a/app/javascript/src/components/Pool.tsx
+++ b/app/javascript/src/components/Pool.tsx
@@ -58,7 +58,7 @@ export const Pool = ({ pool }: PoolProps) => {
{
diff --git a/app/javascript/src/messages/NoHistory.tsx b/app/javascript/src/messages/NoHistory.tsx
new file mode 100644
index 0000000..c829a13
--- /dev/null
+++ b/app/javascript/src/messages/NoHistory.tsx
@@ -0,0 +1,27 @@
+import type { FC } from "react";
+import React from "react";
+
+import websiteLogin from "../assets/vectors/no_data.svg";
+
+type Props = {
+ historyName: string;
+};
+
+export const NoHistory: FC
= ({ historyName }) => {
+ return (
+
+
+

+
+
+ Você não possui históricos de {historyName}
+
+
+
+
+ );
+};
diff --git a/app/javascript/src/messages/index.ts b/app/javascript/src/messages/index.ts
index ef73d42..68865fd 100644
--- a/app/javascript/src/messages/index.ts
+++ b/app/javascript/src/messages/index.ts
@@ -1,5 +1,7 @@
import { Unauthenticated } from "./Unauthenticated";
+import { NoHistory } from "./NoHistory";
export const Messages = {
Unauthenticated,
+ NoHistory,
};
diff --git a/app/javascript/src/pages/Orders/Exchange/ExchangeHistory/components/CryptoExchangeOrder.tsx b/app/javascript/src/pages/Orders/Exchange/ExchangeHistory/components/CryptoExchangeOrder.tsx
index f8c56bc..a9a64e5 100644
--- a/app/javascript/src/pages/Orders/Exchange/ExchangeHistory/components/CryptoExchangeOrder.tsx
+++ b/app/javascript/src/pages/Orders/Exchange/ExchangeHistory/components/CryptoExchangeOrder.tsx
@@ -3,6 +3,7 @@ import React from "react";
import cx from "classnames";
import type { ProcessStatus } from "../__generated__/ExchangeHistory_buyCryptoOrders.graphql";
+import { getStatusTextAndColors } from "../../../utils/processStatus";
export type CryptoExchangeOrderProps = {
payed?: string;
@@ -11,18 +12,6 @@ export type CryptoExchangeOrderProps = {
createdAt?: string;
};
-const getStatusTextAndColors = (status: ProcessStatus) => {
- if (status === "PROCESSING") {
- return ["Processando", "text-yellow-900", "bg-yellow-200"];
- }
-
- if (status === "CANCELED") {
- return ["Cancelado", "text-red-900", "bg-red-200"];
- }
-
- return ["Completado", "text-green-900", "bg-green-200"];
-};
-
export const CryptoExchangeOrder: FC = ({
createdAt = "",
payed = "",
diff --git a/app/javascript/src/pages/Orders/Stake/Stake.tsx b/app/javascript/src/pages/Orders/Stake/Stake.tsx
new file mode 100644
index 0000000..ee88cf2
--- /dev/null
+++ b/app/javascript/src/pages/Orders/Stake/Stake.tsx
@@ -0,0 +1,120 @@
+import { graphql } from "babel-plugin-relay/macro";
+import type { FC } from "react";
+import React from "react";
+import { useLazyLoadQuery } from "react-relay";
+import cx from "classnames";
+
+import { getStatusTextAndColors } from "../utils/processStatus";
+import type { StakeQuery } from "./__generated__/StakeQuery.graphql";
+import { Messages } from "../../../messages";
+
+export const Stake: FC = () => {
+ const { stakeOrders } = useLazyLoadQuery(
+ graphql`
+ query StakeQuery {
+ stakeOrders {
+ edges {
+ node {
+ id
+ poolName
+ amount
+ createdAt
+ status
+ }
+ }
+ }
+ }
+ `,
+ {}
+ );
+
+ if (!stakeOrders.edges.length)
+ return ;
+
+ return (
+
+
+
+
+
+
+
+ |
+ Pool
+ |
+
+ Montante
+ |
+
+ Criado em
+ |
+
+ Status
+ |
+
+
+
+ {stakeOrders.edges.map(({ node }) => {
+ const [label, textStyles, bgStyles] = getStatusTextAndColors(
+ node.status
+ );
+
+ return (
+
+ |
+
+ {node.poolName}
+
+ |
+
+
+ {node.amount}
+
+ |
+
+
+ {new Date(
+ node.createdAt as string
+ ).toLocaleTimeString()}
+
+ |
+
+
+
+ {label}
+
+ |
+
+ );
+ })}
+
+
+
+
+
+
+ );
+};
diff --git a/app/javascript/src/pages/Orders/Stake/__generated__/StakeQuery.graphql.ts b/app/javascript/src/pages/Orders/Stake/__generated__/StakeQuery.graphql.ts
new file mode 100644
index 0000000..de82479
--- /dev/null
+++ b/app/javascript/src/pages/Orders/Stake/__generated__/StakeQuery.graphql.ts
@@ -0,0 +1,143 @@
+/* tslint:disable */
+/* eslint-disable */
+// @ts-nocheck
+
+import { ConcreteRequest } from "relay-runtime";
+export type ProcessStatus = "CANCELED" | "COMPLETED" | "PROCESSING" | "%future added value";
+export type StakeQueryVariables = {};
+export type StakeQueryResponse = {
+ readonly stakeOrders: {
+ readonly edges: ReadonlyArray<{
+ readonly node: {
+ readonly id: string;
+ readonly poolName: string;
+ readonly amount: string;
+ readonly createdAt: unknown;
+ readonly status: ProcessStatus;
+ };
+ }>;
+ };
+};
+export type StakeQuery = {
+ readonly response: StakeQueryResponse;
+ readonly variables: StakeQueryVariables;
+};
+
+
+
+/*
+query StakeQuery {
+ stakeOrders {
+ edges {
+ node {
+ id
+ poolName
+ amount
+ createdAt
+ status
+ }
+ }
+ }
+}
+*/
+
+const node: ConcreteRequest = (function(){
+var v0 = [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "StakeOrderConnection",
+ "kind": "LinkedField",
+ "name": "stakeOrders",
+ "plural": false,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "StakeOrderEdge",
+ "kind": "LinkedField",
+ "name": "edges",
+ "plural": true,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "concreteType": "StakeOrder",
+ "kind": "LinkedField",
+ "name": "node",
+ "plural": false,
+ "selections": [
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "id",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "poolName",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "amount",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "createdAt",
+ "storageKey": null
+ },
+ {
+ "alias": null,
+ "args": null,
+ "kind": "ScalarField",
+ "name": "status",
+ "storageKey": null
+ }
+ ],
+ "storageKey": null
+ }
+ ],
+ "storageKey": null
+ }
+ ],
+ "storageKey": null
+ }
+];
+return {
+ "fragment": {
+ "argumentDefinitions": [],
+ "kind": "Fragment",
+ "metadata": null,
+ "name": "StakeQuery",
+ "selections": (v0/*: any*/),
+ "type": "Query",
+ "abstractKey": null
+ },
+ "kind": "Request",
+ "operation": {
+ "argumentDefinitions": [],
+ "kind": "Operation",
+ "name": "StakeQuery",
+ "selections": (v0/*: any*/)
+ },
+ "params": {
+ "cacheID": "87576f672bf070da8b3a0da1e47f53b1",
+ "id": null,
+ "metadata": {},
+ "name": "StakeQuery",
+ "operationKind": "query",
+ "text": "query StakeQuery {\n stakeOrders {\n edges {\n node {\n id\n poolName\n amount\n createdAt\n status\n }\n }\n }\n}\n"
+ }
+};
+})();
+(node as any).hash = '29eb880947d0b6abb92c13928f5fbbe0';
+export default node;
diff --git a/app/javascript/src/pages/Orders/Stake/index.ts b/app/javascript/src/pages/Orders/Stake/index.ts
new file mode 100644
index 0000000..8e61697
--- /dev/null
+++ b/app/javascript/src/pages/Orders/Stake/index.ts
@@ -0,0 +1 @@
+export * from "./Stake";
diff --git a/app/javascript/src/pages/Orders/index.ts b/app/javascript/src/pages/Orders/index.ts
index 5824f1b..7c2f26f 100644
--- a/app/javascript/src/pages/Orders/index.ts
+++ b/app/javascript/src/pages/Orders/index.ts
@@ -1,5 +1,7 @@
import { Exchange } from "./Exchange";
+import { Stake } from "./Stake";
export const Orders = {
Exchange,
+ Stake,
};
diff --git a/app/javascript/src/pages/Orders/utils/processStatus.ts b/app/javascript/src/pages/Orders/utils/processStatus.ts
new file mode 100644
index 0000000..2ec7962
--- /dev/null
+++ b/app/javascript/src/pages/Orders/utils/processStatus.ts
@@ -0,0 +1,22 @@
+type ProcessStatus =
+ | "CANCELED"
+ | "COMPLETED"
+ | "PROCESSING"
+ // eslint-disable-next-line relay/no-future-added-value
+ | "%future added value";
+
+export const getStatusTextAndColors = (status: ProcessStatus) => {
+ if (status === "PROCESSING") {
+ return ["Processando", "text-yellow-900", "bg-yellow-200"];
+ }
+
+ if (status === "CANCELED") {
+ return ["Cancelado", "text-red-900", "bg-red-200"];
+ }
+
+ if (status === "COMPLETED") {
+ return ["Completado", "text-green-900", "bg-green-200"];
+ }
+
+ return ["", "", ""];
+};
diff --git a/app/models/stake_order.rb b/app/models/stake_order.rb
new file mode 100644
index 0000000..bc6e491
--- /dev/null
+++ b/app/models/stake_order.rb
@@ -0,0 +1,30 @@
+# frozen_string_literal: true
+
+# == Schema Information
+#
+# Table name: stake_orders
+#
+# id :bigint not null, primary key
+# amount :decimal(20, 10) default(0.0), not null
+# pool_name :string not null
+# status :string not null
+# created_at :datetime not null
+# updated_at :datetime not null
+# user_id :bigint not null
+#
+# Indexes
+#
+# index_stake_orders_on_user_id (user_id)
+#
+# Foreign Keys
+#
+# fk_rails_... (user_id => users.id)
+#
+class StakeOrder < ApplicationRecord
+ include Processable
+
+ belongs_to :user
+
+ validates :pool_name, presence: true
+ validates :amount, presence: true
+end
diff --git a/app/models/user.rb b/app/models/user.rb
index 88d48b1..fadf31e 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -25,6 +25,7 @@ class User < ApplicationRecord
:recoverable, :rememberable, :validatable
has_many :documents, class_name: "UserDocument", dependent: :destroy
+ has_many :stake_orders, dependent: :restrict_with_error
has_many :balances, dependent: :restrict_with_error
has_one :fiat_balance, dependent: :restrict_with_error
diff --git a/app/policies/stake_order_policy.rb b/app/policies/stake_order_policy.rb
new file mode 100644
index 0000000..911a975
--- /dev/null
+++ b/app/policies/stake_order_policy.rb
@@ -0,0 +1,10 @@
+# frozen_string_literal: true
+class StakeOrderPolicy < ApplicationPolicy
+ class Scope < Scope
+ def resolve
+ return scope.none if user.nil?
+
+ scope.where(user_id: user.id)
+ end
+ end
+end
diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml
index 38517c5..ea4b93f 100644
--- a/config/locales/pt-BR.yml
+++ b/config/locales/pt-BR.yml
@@ -39,7 +39,7 @@ pt-BR:
fiat_balance:
amount_formatted: Quantia
- amount_cents: Quantia em centavos
+ amount_cents: Quantia
currency:
name: Nome
diff --git a/db/migrate/20210816032056_create_stake_orders.rb b/db/migrate/20210816032056_create_stake_orders.rb
new file mode 100644
index 0000000..f79acbd
--- /dev/null
+++ b/db/migrate/20210816032056_create_stake_orders.rb
@@ -0,0 +1,14 @@
+# frozen_string_literal: true
+class CreateStakeOrders < ActiveRecord::Migration[6.1]
+ def change
+ create_table(:stake_orders) do |t|
+ t.references(:user, null: false, foreign_key: true)
+ t.string(:pool_name, null: false)
+ t.string(:status, null: false)
+
+ t.decimal(:amount, precision: 20, scale: 10, null: false, default: 0)
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index 4516172..adbc574 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 2021_08_16_015156) do
+ActiveRecord::Schema.define(version: 2021_08_16_032056) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -104,6 +104,16 @@ ActiveRecord::Schema.define(version: 2021_08_16_015156) do
t.index ["user_id"], name: "index_sell_crypto_orders_on_user_id"
end
+ create_table "stake_orders", force: :cascade do |t|
+ t.bigint "user_id", null: false
+ t.string "pool_name", null: false
+ t.string "status", null: false
+ t.decimal "amount", precision: 20, scale: 10, default: "0.0", null: false
+ t.datetime "created_at", precision: 6, null: false
+ t.datetime "updated_at", precision: 6, null: false
+ t.index ["user_id"], name: "index_stake_orders_on_user_id"
+ end
+
create_table "user_documents", force: :cascade do |t|
t.string "status", null: false
t.bigint "user_id", null: false
@@ -135,5 +145,6 @@ ActiveRecord::Schema.define(version: 2021_08_16_015156) do
add_foreign_key "fiat_balances", "users"
add_foreign_key "sell_crypto_orders", "currencies"
add_foreign_key "sell_crypto_orders", "users"
+ add_foreign_key "stake_orders", "users"
add_foreign_key "user_documents", "users"
end
diff --git a/erd.svg b/erd.svg
index 4ea3eee..e9b3d71 100644
--- a/erd.svg
+++ b/erd.svg
@@ -4,176 +4,197 @@
-