diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 12c19a8..e86be56 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -9,6 +9,7 @@
"version": "1.0.0",
"dependencies": {
"@apollo/client": "^3.4.16",
+ "date-fns": "^2.25.0",
"graphql": "^15.7.2",
"react": "^17.0.2",
"react-dom": "^17.0.2"
@@ -4123,10 +4124,16 @@
"dev": true
},
"node_modules/date-fns": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz",
- "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==",
- "dev": true
+ "version": "2.25.0",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.25.0.tgz",
+ "integrity": "sha512-ovYRFnTrbGPD4nqaEqescPEv1mNwvt+UTqI3Ay9SzNtey9NZnYu6E2qCcBBgJ6/2VF1zGGygpyTDITqpQQ5e+w==",
+ "engines": {
+ "node": ">=0.11"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/date-fns"
+ }
},
"node_modules/debounce": {
"version": "1.2.1",
@@ -8041,6 +8048,12 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
},
+ "node_modules/listr-verbose-renderer/node_modules/date-fns": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz",
+ "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==",
+ "dev": true
+ },
"node_modules/listr-verbose-renderer/node_modules/escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
@@ -14637,10 +14650,9 @@
"dev": true
},
"date-fns": {
- "version": "1.30.1",
- "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz",
- "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==",
- "dev": true
+ "version": "2.25.0",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.25.0.tgz",
+ "integrity": "sha512-ovYRFnTrbGPD4nqaEqescPEv1mNwvt+UTqI3Ay9SzNtey9NZnYu6E2qCcBBgJ6/2VF1zGGygpyTDITqpQQ5e+w=="
},
"debounce": {
"version": "1.2.1",
@@ -17578,6 +17590,12 @@
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
"dev": true
},
+ "date-fns": {
+ "version": "1.30.1",
+ "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-1.30.1.tgz",
+ "integrity": "sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw==",
+ "dev": true
+ },
"escape-string-regexp": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index faed41a..b446c35 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -16,6 +16,7 @@
},
"dependencies": {
"@apollo/client": "^3.4.16",
+ "date-fns": "^2.25.0",
"graphql": "^15.7.2",
"react": "^17.0.2",
"react-dom": "^17.0.2"
diff --git a/frontend/src/features/Register.tsx b/frontend/src/features/Register.tsx
index c0e7f77..c1d6ae6 100644
--- a/frontend/src/features/Register.tsx
+++ b/frontend/src/features/Register.tsx
@@ -1,21 +1,25 @@
import React from "react";
-import { Product, useAllProductsQuery } from "../types";
+import { Product, User } from "../types";
+import { useRegister } from "./useRegister";
export const Register: React.FC = () => {
- const { data, error, loading } = useAllProductsQuery({ variables: { active: true } });
- if (error) {
- console.log("🔥", error);
- return null;
- }
+ const { users, products, loading, showAll, setShowAll } = useRegister();
if (loading) {
return
...
;
}
return (
- {data?.allProducts.map((product: Product) => {
- return
{product.name}
;
- })}{" "}
+
+ {users.map((user: User) => {
+ return {user.firstName}
;
+ })}
+
+
+ {products.map((product: Product) => {
+ return {product.name}
;
+ })}
+
);
};
diff --git a/frontend/src/features/allUsers.graphql b/frontend/src/features/allUsers.graphql
new file mode 100644
index 0000000..1715fd5
--- /dev/null
+++ b/frontend/src/features/allUsers.graphql
@@ -0,0 +1,13 @@
+query allUsers {
+ allUsers {
+ id
+ firstName
+ lastName
+ profile {
+ id
+ balance
+ image
+ lastPurchaseDate
+ }
+ }
+}
diff --git a/frontend/src/features/useRegister.ts b/frontend/src/features/useRegister.ts
new file mode 100644
index 0000000..cb9dcd0
--- /dev/null
+++ b/frontend/src/features/useRegister.ts
@@ -0,0 +1,23 @@
+import { parseISO, subDays } from "date-fns";
+import { useState } from "react";
+
+import { useAllProductsQuery, useAllUsersQuery, User } from "../types";
+
+const activeLimitDays = 365 / 2;
+
+export const useRegister = () => {
+ const [showAll, setShowAll] = useState(false);
+ const { data, loading } = useAllProductsQuery({ variables: { active: true } });
+ const { data: usersData, loading: usersLoading } = useAllUsersQuery();
+
+ const allUsers = usersData?.allUsers || [];
+ const users = showAll
+ ? allUsers
+ : allUsers.filter((user: User) => {
+ const balance = user.profile?.balance || 0;
+ const active = parseISO(user.profile?.lastPurchaseDate) >= subDays(new Date(), activeLimitDays);
+ return balance >= 15 && active;
+ });
+
+ return { loading: loading || usersLoading, users, products: data?.allProducts || [], showAll, setShowAll };
+};
diff --git a/frontend/src/types.ts b/frontend/src/types.ts
index a505d3d..0f91c39 100644
--- a/frontend/src/types.ts
+++ b/frontend/src/types.ts
@@ -1,10 +1,10 @@
-import { gql } from "@apollo/client";
-import * as Apollo from "@apollo/client";
+import { gql } from '@apollo/client';
+import * as Apollo from '@apollo/client';
export type Maybe = T | null;
export type Exact = { [K in keyof T]: T[K] };
export type MakeOptional = Omit & { [SubKey in K]?: Maybe };
export type MakeMaybe = Omit & { [SubKey in K]: Maybe };
-const defaultOptions = {};
+const defaultOptions = {}
/** All built-in and custom scalars, mapped to their actual values */
export type Scalars = {
ID: string;
@@ -12,49 +12,73 @@ export type Scalars = {
Boolean: boolean;
Int: number;
Float: number;
+ /** Date with time (isoformat) */
+ DateTime: any;
};
export type Product = {
- __typename?: "Product";
- id: Scalars["ID"];
- name: Scalars["String"];
- salePriceExt: Scalars["Float"];
- salePriceInt: Scalars["Float"];
+ __typename?: 'Product';
+ id: Scalars['ID'];
+ name: Scalars['String'];
+ salePriceExt: Scalars['Float'];
+ salePriceInt: Scalars['Float'];
};
export type ProductFilter = {
- active?: Maybe;
- id?: Maybe;
+ active?: Maybe;
+ id?: Maybe;
};
export type Query = {
- __typename?: "Query";
+ __typename?: 'Query';
allProducts: Array;
+ allUsers: Array;
};
+
export type QueryAllProductsArgs = {
filters?: Maybe;
};
-export type AllProductsQueryVariables = Exact<{
- active: Scalars["Boolean"];
-}>;
-
-export type AllProductsQuery = {
- __typename?: "Query";
- allProducts: Array<{ __typename?: "Product"; id: string; name: string; salePriceExt: number; salePriceInt: number }>;
+export type User = {
+ __typename?: 'User';
+ firstName: Scalars['String'];
+ id: Scalars['ID'];
+ lastName: Scalars['String'];
+ profile?: Maybe;
};
+export type UserProfile = {
+ __typename?: 'UserProfile';
+ balance: Scalars['Float'];
+ id: Scalars['ID'];
+ image: Scalars['String'];
+ lastPurchaseDate: Scalars['DateTime'];
+};
+
+export type AllProductsQueryVariables = Exact<{
+ active: Scalars['Boolean'];
+}>;
+
+
+export type AllProductsQuery = { __typename?: 'Query', allProducts: Array<{ __typename?: 'Product', id: string, name: string, salePriceExt: number, salePriceInt: number }> };
+
+export type AllUsersQueryVariables = Exact<{ [key: string]: never; }>;
+
+
+export type AllUsersQuery = { __typename?: 'Query', allUsers: Array<{ __typename?: 'User', id: string, firstName: string, lastName: string, profile?: { __typename?: 'UserProfile', id: string, balance: number, image: string, lastPurchaseDate: any } | null | undefined }> };
+
+
export const AllProductsDocument = gql`
- query allProducts($active: Boolean!) {
- allProducts(filters: { active: $active }) {
- id
- name
- salePriceExt
- salePriceInt
- }
+ query allProducts($active: Boolean!) {
+ allProducts(filters: {active: $active}) {
+ id
+ name
+ salePriceExt
+ salePriceInt
}
-`;
+}
+ `;
/**
* __useAllProductsQuery__
@@ -73,15 +97,55 @@ export const AllProductsDocument = gql`
* });
*/
export function useAllProductsQuery(baseOptions: Apollo.QueryHookOptions) {
- const options = { ...defaultOptions, ...baseOptions };
- return Apollo.useQuery(AllProductsDocument, options);
-}
-export function useAllProductsLazyQuery(
- baseOptions?: Apollo.LazyQueryHookOptions
-) {
- const options = { ...defaultOptions, ...baseOptions };
- return Apollo.useLazyQuery(AllProductsDocument, options);
-}
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useQuery(AllProductsDocument, options);
+ }
+export function useAllProductsLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useLazyQuery(AllProductsDocument, options);
+ }
export type AllProductsQueryHookResult = ReturnType;
export type AllProductsLazyQueryHookResult = ReturnType;
export type AllProductsQueryResult = Apollo.QueryResult;
+export const AllUsersDocument = gql`
+ query allUsers {
+ allUsers {
+ id
+ firstName
+ lastName
+ profile {
+ id
+ balance
+ image
+ lastPurchaseDate
+ }
+ }
+}
+ `;
+
+/**
+ * __useAllUsersQuery__
+ *
+ * To run a query within a React component, call `useAllUsersQuery` and pass it any options that fit your needs.
+ * When your component renders, `useAllUsersQuery` returns an object from Apollo Client that contains loading, error, and data properties
+ * you can use to render your UI.
+ *
+ * @param baseOptions options that will be passed into the query, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options;
+ *
+ * @example
+ * const { data, loading, error } = useAllUsersQuery({
+ * variables: {
+ * },
+ * });
+ */
+export function useAllUsersQuery(baseOptions?: Apollo.QueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useQuery(AllUsersDocument, options);
+ }
+export function useAllUsersLazyQuery(baseOptions?: Apollo.LazyQueryHookOptions) {
+ const options = {...defaultOptions, ...baseOptions}
+ return Apollo.useLazyQuery(AllUsersDocument, options);
+ }
+export type AllUsersQueryHookResult = ReturnType;
+export type AllUsersLazyQueryHookResult = ReturnType;
+export type AllUsersQueryResult = Apollo.QueryResult;
\ No newline at end of file
diff --git a/main/api/schema.py b/main/api/schema.py
index 355ef2e..f6daf93 100644
--- a/main/api/schema.py
+++ b/main/api/schema.py
@@ -1,27 +1,13 @@
import strawberry
import strawberry_django
-from strawberry_django import auto
-from main import models
-
-
-@strawberry_django.filters.filter(models.Product)
-class ProductFilter:
- id: auto
- active: auto
-
-
-@strawberry_django.type(models.Product, filters=ProductFilter)
-class Product:
- id: auto
- name: auto
- sale_price_int: auto
- sale_price_ext: auto
+from main.api.types import Product, User
@strawberry.type
class Query:
all_products: list[Product] = strawberry_django.field()
+ all_users: list[User] = strawberry_django.field()
schema = strawberry.Schema(query=Query)
diff --git a/main/api/types.py b/main/api/types.py
new file mode 100644
index 0000000..ed5ae86
--- /dev/null
+++ b/main/api/types.py
@@ -0,0 +1,44 @@
+from datetime import datetime
+
+import strawberry
+import strawberry_django
+from django.contrib.auth import get_user_model
+from strawberry_django import auto
+
+from main import models
+
+UserModel = get_user_model()
+
+
+@strawberry_django.filters.filter(models.Product)
+class ProductFilter:
+ id: auto
+ active: auto
+
+
+@strawberry_django.type(models.Product, filters=ProductFilter)
+class Product:
+ id: auto
+ name: auto
+ sale_price_int: auto
+ sale_price_ext: auto
+
+
+@strawberry_django.type(models.UserProfile)
+class UserProfile:
+ id: auto
+ balance: auto
+ image: auto
+
+ @strawberry.field()
+ def last_purchase_date(self) -> datetime:
+ return self.last_purchase_date()
+
+
+@strawberry_django.type(UserModel)
+class User:
+ id: auto
+ first_name: auto
+ last_name: auto
+ profile: UserProfile
+ # todo