This commit is contained in:
Stanislaw-Golebiewski 2020-01-27 14:46:28 +01:00
parent 7d5a3626c6
commit 6430ab919e
16 changed files with 491 additions and 91 deletions

View File

@ -10,6 +10,7 @@ router.register('shops', ShopViewSet)
router.register('products', ProductViewSet) router.register('products', ProductViewSet)
router.register('products_on_bills', ProductOnBillViewSet) router.register('products_on_bills', ProductOnBillViewSet)
router.register('receipts', ReceiptViewSet) router.register('receipts', ReceiptViewSet)
# router.register('stats', GeneralStats)
urlpatterns = [ urlpatterns = [
url("^", include(router.urls)), url("^", include(router.urls)),

View File

@ -0,0 +1,32 @@
from django.db.models import Count
from .models import Tag, Product, ProductOnBill, Receipt, Shop, ShopTag
def get_general_stats(user, date_range=None):
out = {
"receipts": user.receipts.all().count(),
"products": user.products.all().count(),
"shops": user.shops.all().count(),
"purchases": user.products_on_bills.all().count(),
"product_tags": user.tags.all().count(),
"shop_tags": user.shop_tags.all().count(),
}
return out
def get_shops_stats(user):
def shop_cout(name):
return user.receipts.all().filter(shop__name=name).count()
out = [{"name": s.name, "count": shop_cout(s.name)} for s in user.shops.all()]
return out
def get_products_stats(user):
# def shop_cout(name):
# return user..all().filter(pro__name=name).count()
out = [
{"name": "product", "count": "times bought"}
]
return out

9
bk_api/bills/urls.py Normal file
View File

@ -0,0 +1,9 @@
from django.urls import path
from .views import general_stats_view, shops_stats_view, products_stats_view
urlpatterns = [
path('', general_stats_view),
path('shops/', shops_stats_view),
path('products/', products_stats_view),
]

View File

@ -1,10 +1,15 @@
from django.shortcuts import render from django.shortcuts import render
from rest_framework.views import APIView
from rest_framework.response import Response
from rest_framework import viewsets, permissions, pagination, filters from rest_framework import viewsets, permissions, pagination, filters
from django.http import JsonResponse
from .models import Tag, Product, ProductOnBill, Receipt, Shop, ShopTag from .models import Tag, Product, ProductOnBill, Receipt, Shop, ShopTag
from .serializers import TagSerializer, ProductSerializer, ProductOnBillSerializer, ReceiptSerializer, ShopSerializer, ShopTagSerializer from .serializers import TagSerializer, ProductSerializer, ProductOnBillSerializer, ReceiptSerializer, ShopSerializer, ShopTagSerializer
from .statistics import get_general_stats, get_shops_stats, get_products_stats
class TagViewSet(viewsets.ModelViewSet): class TagViewSet(viewsets.ModelViewSet):
queryset = Tag.objects.all() queryset = Tag.objects.all()
@ -21,6 +26,7 @@ class ShopTagViewSet(viewsets.ModelViewSet):
queryset = ShopTag.objects.all() queryset = ShopTag.objects.all()
# permission_classes = [permissions.AllowAny] # permission_classes = [permissions.AllowAny]
serializer_class = ShopTagSerializer serializer_class = ShopTagSerializer
def get_queryset(self): def get_queryset(self):
return self.request.user.shop_tags.all() return self.request.user.shop_tags.all()
@ -62,7 +68,6 @@ class ProductOnBillViewSet(viewsets.ModelViewSet):
serializer.save(owner=self.request.user) serializer.save(owner=self.request.user)
class StandardResultsSetPagination(pagination.PageNumberPagination): class StandardResultsSetPagination(pagination.PageNumberPagination):
page_size = 10 page_size = 10
page_size_query_param = 'page_size' page_size_query_param = 'page_size'
@ -80,3 +85,25 @@ class ReceiptViewSet(viewsets.ModelViewSet):
def perform_create(self, serializer): def perform_create(self, serializer):
serializer.save(owner=self.request.user) serializer.save(owner=self.request.user)
# === STATS VIEWS ===
# def GeneralStats(APIView):
# # authentication_classes = [authentication.TokenAuthentication]
# # permission_classes = [permissions.IsAdminUser]
# def get(self, request, format=None):
# print(request.user)
# return Response(get_general_stats(request.user))
# # def shops_stats_view(request):
# # responseData = get_shops_stats(request.user)
# # return JsonResponse(responseData, safe=False)
# # def products_stats_view(request):
# # responseData = get_products_stats(request.user)
# # return JsonResponse(responseData, safe=False)

View File

@ -40,6 +40,10 @@ REST_FRAMEWORK = {
# 'PAGE_SIZE': 10 # 'PAGE_SIZE': 10
} }
REST_KNOX = {
'TOKEN_TTL': None,
}
# Application definition # Application definition
INSTALLED_APPS = [ INSTALLED_APPS = [

View File

@ -22,11 +22,13 @@ from knox import views as knox_views
from .views import LoginView from .views import LoginView
from bills import endpoints from bills import endpoints
import core import core
import bills
urlpatterns = [ urlpatterns = [
path('api/photo/', include('core.urls')), path('api/photo/', include('core.urls')),
path('api/admin/', admin.site.urls), path('api/admin/', admin.site.urls),
url('^api/', include(endpoints)), url('^api/', include(endpoints)),
# path('api/stats/', include('bills.urls')),
url(r'api/auth/login/', LoginView.as_view(), name='knox_login'), url(r'api/auth/login/', LoginView.as_view(), name='knox_login'),
url(r'api/auth/logout/', knox_views.LogoutView.as_view(), name='knox_logout'), url(r'api/auth/logout/', knox_views.LogoutView.as_view(), name='knox_logout'),
url(r'api/auth/logoutall/', knox_views.LogoutAllView.as_view(), name='knox_logoutall'), url(r'api/auth/logoutall/', knox_views.LogoutAllView.as_view(), name='knox_logoutall'),

View File

@ -60,4 +60,3 @@ def upload_bill_debug_text(request):
products = [{'name': prod, 'price': pri} for _, prod, pri in product_list] products = [{'name': prod, 'price': pri} for _, prod, pri in product_list]
response = JsonResponse({'products': products, 'text': full_text}) response = JsonResponse({'products': products, 'text': full_text})
return response return response

View File

@ -4277,6 +4277,67 @@
"type": "^1.0.1" "type": "^1.0.1"
} }
}, },
"d3-array": {
"version": "2.4.0",
"resolved": "https://registry.npmjs.org/d3-array/-/d3-array-2.4.0.tgz",
"integrity": "sha512-KQ41bAF2BMakf/HdKT865ALd4cgND6VcIztVQZUTt0+BH3RWy6ZYnHghVXf6NFjt2ritLr8H1T8LreAAlfiNcw=="
},
"d3-color": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/d3-color/-/d3-color-1.4.0.tgz",
"integrity": "sha512-TzNPeJy2+iEepfiL92LAAB7fvnp/dV2YwANPVHdDWmYMm23qIJBYww3qT8I8C1wXrmrg4UWs7BKc2tKIgyjzHg=="
},
"d3-format": {
"version": "1.4.3",
"resolved": "https://registry.npmjs.org/d3-format/-/d3-format-1.4.3.tgz",
"integrity": "sha512-mm/nE2Y9HgGyjP+rKIekeITVgBtX97o1nrvHCWX8F/yBYyevUTvu9vb5pUnKwrcSw7o7GuwMOWjS9gFDs4O+uQ=="
},
"d3-interpolate": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/d3-interpolate/-/d3-interpolate-1.4.0.tgz",
"integrity": "sha512-V9znK0zc3jOPV4VD2zZn0sDhZU3WAE2bmlxdIwwQPPzPjvyLkd8B3JUVdS1IDUFDkWZ72c9qnv1GK2ZagTZ8EA==",
"requires": {
"d3-color": "1"
}
},
"d3-path": {
"version": "1.0.9",
"resolved": "https://registry.npmjs.org/d3-path/-/d3-path-1.0.9.tgz",
"integrity": "sha512-VLaYcn81dtHVTjEHd8B+pbe9yHWpXKZUC87PzoFmsFrJqgFwDe/qxfp5MlfsfM1V5E/iVt0MmEbWQ7FVIXh/bg=="
},
"d3-scale": {
"version": "3.2.1",
"resolved": "https://registry.npmjs.org/d3-scale/-/d3-scale-3.2.1.tgz",
"integrity": "sha512-huz5byJO/6MPpz6Q8d4lg7GgSpTjIZW/l+1MQkzKfu2u8P6hjaXaStOpmyrD6ymKoW87d2QVFCKvSjLwjzx/rA==",
"requires": {
"d3-array": "1.2.0 - 2",
"d3-format": "1",
"d3-interpolate": "^1.2.0",
"d3-time": "1",
"d3-time-format": "2"
}
},
"d3-shape": {
"version": "1.3.7",
"resolved": "https://registry.npmjs.org/d3-shape/-/d3-shape-1.3.7.tgz",
"integrity": "sha512-EUkvKjqPFUAZyOlhY5gzCxCeI0Aep04LwIRpsZ/mLFelJiUfnK56jo5JMDSE7yyP2kLSb6LtF+S5chMk7uqPqw==",
"requires": {
"d3-path": "1"
}
},
"d3-time": {
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/d3-time/-/d3-time-1.1.0.tgz",
"integrity": "sha512-Xh0isrZ5rPYYdqhAVk8VLnMEidhz5aP7htAADH6MfzgmmicPkTo8LhkLxci61/lCB7n7UmE3bN0leRt+qvkLxA=="
},
"d3-time-format": {
"version": "2.2.3",
"resolved": "https://registry.npmjs.org/d3-time-format/-/d3-time-format-2.2.3.tgz",
"integrity": "sha512-RAHNnD8+XvC4Zc4d2A56Uw0yJoM7bsvOlJR33bclxq399Rak/b9bhvu/InjxdWhPtkgU53JJcleJTGkNRnN6IA==",
"requires": {
"d3-time": "1"
}
},
"damerau-levenshtein": { "damerau-levenshtein": {
"version": "1.0.5", "version": "1.0.5",
"resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.5.tgz", "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.5.tgz",
@ -4346,6 +4407,11 @@
"resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz", "resolved": "https://registry.npmjs.org/decamelize/-/decamelize-1.2.0.tgz",
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=" "integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA="
}, },
"decimal.js-light": {
"version": "2.5.0",
"resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.0.tgz",
"integrity": "sha512-b3VJCbd2hwUpeRGG3Toob+CRo8W22xplipNhP3tN7TSVB/cyMX71P1vM2Xjc9H74uV6dS2hDDmo/rHq8L87Upg=="
},
"decode-uri-component": { "decode-uri-component": {
"version": "0.2.0", "version": "0.2.0",
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
@ -4593,6 +4659,14 @@
"utila": "~0.4" "utila": "~0.4"
} }
}, },
"dom-helpers": {
"version": "3.4.0",
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-3.4.0.tgz",
"integrity": "sha512-LnuPJ+dwqKDIyotW1VzmOZ5TONUN7CwkCR5hrgawTUbkBGYdeoNLZo6nNfGkCrjtE1nXXaj7iMMpDa8/d9WoIA==",
"requires": {
"@babel/runtime": "^7.1.2"
}
},
"dom-serializer": { "dom-serializer": {
"version": "0.2.2", "version": "0.2.2",
"resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz", "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.2.2.tgz",
@ -8377,6 +8451,11 @@
"resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz",
"integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A=="
}, },
"lodash-es": {
"version": "4.17.15",
"resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.15.tgz",
"integrity": "sha512-rlrc3yU3+JNOpZ9zj5pQtxnx2THmvRykwL4Xlxoa8I9lHBlVbbyPhgyPMioxVZ4NqyxaVVtaJnzsyOidQIhyyQ=="
},
"lodash._reinterpolate": { "lodash._reinterpolate": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz", "resolved": "https://registry.npmjs.org/lodash._reinterpolate/-/lodash._reinterpolate-3.0.0.tgz",
@ -8507,6 +8586,11 @@
"object-visit": "^1.0.0" "object-visit": "^1.0.0"
} }
}, },
"math-expression-evaluator": {
"version": "1.2.22",
"resolved": "https://registry.npmjs.org/math-expression-evaluator/-/math-expression-evaluator-1.2.22.tgz",
"integrity": "sha512-L0j0tFVZBQQLeEjmWOvDLoRciIY8gQGWahvkztXUal8jH8R5Rlqo9GCvgqvXcy9LQhEWdQCVvzqAbxgYNt4blQ=="
},
"md5.js": { "md5.js": {
"version": "1.3.5", "version": "1.3.5",
"resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz", "resolved": "https://registry.npmjs.org/md5.js/-/md5.js-1.3.5.tgz",
@ -10885,6 +10969,11 @@
"performance-now": "^2.1.0" "performance-now": "^2.1.0"
} }
}, },
"raf-schd": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/raf-schd/-/raf-schd-4.0.2.tgz",
"integrity": "sha512-VhlMZmGy6A6hrkJWHLNTGl5gtgMUm+xfGza6wbwnE914yeQ5Ybm18vgM734RZhMgfw4tacUrWseGZlpUrrakEQ=="
},
"randombytes": { "randombytes": {
"version": "2.1.0", "version": "2.1.0",
"resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz", "resolved": "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz",
@ -11114,6 +11203,11 @@
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz",
"integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==" "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q=="
}, },
"react-lifecycles-compat": {
"version": "3.0.4",
"resolved": "https://registry.npmjs.org/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz",
"integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA=="
},
"react-minimal-pie-chart": { "react-minimal-pie-chart": {
"version": "6.0.1", "version": "6.0.1",
"resolved": "https://registry.npmjs.org/react-minimal-pie-chart/-/react-minimal-pie-chart-6.0.1.tgz", "resolved": "https://registry.npmjs.org/react-minimal-pie-chart/-/react-minimal-pie-chart-6.0.1.tgz",
@ -11136,6 +11230,18 @@
"warning": "^4.0.2" "warning": "^4.0.2"
} }
}, },
"react-resize-detector": {
"version": "4.2.1",
"resolved": "https://registry.npmjs.org/react-resize-detector/-/react-resize-detector-4.2.1.tgz",
"integrity": "sha512-ZfPMBPxXi0o3xox42MIEtz84tPSVMW9GgwLHYvjVXlFM+OkNzbeEtpVSV+mSTJmk4Znwomolzt35zHN9LNBQMQ==",
"requires": {
"lodash": "^4.17.15",
"lodash-es": "^4.17.15",
"prop-types": "^15.7.2",
"raf-schd": "^4.0.2",
"resize-observer-polyfill": "^1.5.1"
}
},
"react-router": { "react-router": {
"version": "5.1.2", "version": "5.1.2",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-5.1.2.tgz", "resolved": "https://registry.npmjs.org/react-router/-/react-router-5.1.2.tgz",
@ -11271,6 +11377,28 @@
} }
} }
}, },
"react-smooth": {
"version": "1.0.5",
"resolved": "https://registry.npmjs.org/react-smooth/-/react-smooth-1.0.5.tgz",
"integrity": "sha512-eW057HT0lFgCKh8ilr0y2JaH2YbNcuEdFpxyg7Gf/qDKk9hqGMyXryZJ8iMGJEuKH0+wxS0ccSsBBB3W8yCn8w==",
"requires": {
"lodash": "~4.17.4",
"prop-types": "^15.6.0",
"raf": "^3.4.0",
"react-transition-group": "^2.5.0"
}
},
"react-transition-group": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-2.9.0.tgz",
"integrity": "sha512-+HzNTCHpeQyl4MJ/bdE0u6XRMe9+XG/+aL4mCxVN4DnPBQ0/5bfHWPDuOZUzYdMj94daZaZdCCc1Dzt9R/xSSg==",
"requires": {
"dom-helpers": "^3.4.0",
"loose-envify": "^1.4.0",
"prop-types": "^15.6.2",
"react-lifecycles-compat": "^3.0.4"
}
},
"read-pkg": { "read-pkg": {
"version": "3.0.0", "version": "3.0.0",
"resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-3.0.0.tgz",
@ -11342,6 +11470,32 @@
"util.promisify": "^1.0.0" "util.promisify": "^1.0.0"
} }
}, },
"recharts": {
"version": "2.0.0-beta.1",
"resolved": "https://registry.npmjs.org/recharts/-/recharts-2.0.0-beta.1.tgz",
"integrity": "sha512-awJH2DE6JRgp5ymzmH5dKh2Pu6prqZJCr3NRaYCcyub1fBa+fIG3ZlpLyl9hWizHPGEvfZLvcjIM+qgTsr9aSQ==",
"requires": {
"classnames": "^2.2.5",
"core-js": "^3.4.2",
"d3-interpolate": "^1.3.0",
"d3-scale": "^3.1.0",
"d3-shape": "^1.3.5",
"lodash": "^4.17.5",
"prop-types": "^15.6.0",
"react-resize-detector": "^4.2.1",
"react-smooth": "^1.0.5",
"recharts-scale": "^0.4.2",
"reduce-css-calc": "^1.3.0"
}
},
"recharts-scale": {
"version": "0.4.3",
"resolved": "https://registry.npmjs.org/recharts-scale/-/recharts-scale-0.4.3.tgz",
"integrity": "sha512-t8p5sccG9Blm7c1JQK/ak9O8o95WGhNXD7TXg/BW5bYbVlr6eCeRBNpgyigD4p6pSSMehC5nSvBUPj6F68rbFA==",
"requires": {
"decimal.js-light": "^2.4.1"
}
},
"recursive-readdir": { "recursive-readdir": {
"version": "2.2.2", "version": "2.2.2",
"resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz", "resolved": "https://registry.npmjs.org/recursive-readdir/-/recursive-readdir-2.2.2.tgz",
@ -11359,6 +11513,31 @@
"strip-indent": "^3.0.0" "strip-indent": "^3.0.0"
} }
}, },
"reduce-css-calc": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/reduce-css-calc/-/reduce-css-calc-1.3.0.tgz",
"integrity": "sha1-dHyRTgSWFKTJz7umKYca0dKSdxY=",
"requires": {
"balanced-match": "^0.4.2",
"math-expression-evaluator": "^1.2.14",
"reduce-function-call": "^1.0.1"
},
"dependencies": {
"balanced-match": {
"version": "0.4.2",
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-0.4.2.tgz",
"integrity": "sha1-yz8+PHMtwPAe5wtAPzAuYddwmDg="
}
}
},
"reduce-function-call": {
"version": "1.0.3",
"resolved": "https://registry.npmjs.org/reduce-function-call/-/reduce-function-call-1.0.3.tgz",
"integrity": "sha512-Hl/tuV2VDgWgCSEeWMLwxLZqX7OK59eU1guxXsRKTAyeYimivsKdtcV4fu3r710tpG5GmDKDhQ0HSZLExnNmyQ==",
"requires": {
"balanced-match": "^1.0.0"
}
},
"regenerate": { "regenerate": {
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz",
@ -11593,6 +11772,11 @@
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=" "integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8="
}, },
"resize-observer-polyfill": {
"version": "1.5.1",
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
"integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg=="
},
"resolve": { "resolve": {
"version": "1.12.2", "version": "1.12.2",
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.2.tgz", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.12.2.tgz",

View File

@ -13,6 +13,7 @@
"react-router-dom": "^5.1.2", "react-router-dom": "^5.1.2",
"react-scripts": "3.3.0", "react-scripts": "3.3.0",
"react-semantic-ui-datepickers": "^2.3.0", "react-semantic-ui-datepickers": "^2.3.0",
"recharts": "^2.0.0-beta.1",
"semantic-ui-react": "^0.88.2", "semantic-ui-react": "^0.88.2",
"use-global-hook": "^0.1.12" "use-global-hook": "^0.1.12"
}, },

View File

@ -37,7 +37,7 @@ function Home() {
icon icon
size="massive" size="massive"
className="home-button-wrapper" className="home-button-wrapper"
onClick={() => history.push("/home/statistics")} onClick={() => history.push("/home/statistics/summary")}
> >
<Icon <Icon
className="home-button-icon" className="home-button-icon"

View File

@ -1,88 +0,0 @@
import React, { useState } from "react";
import { Container, Icon, Menu, Sidebar } from "semantic-ui-react";
import { useHistory } from "react-router-dom";
import PieChart from "react-minimal-pie-chart";
import "./Statistics.css";
function Statistics() {
const [visible, setVisible] = useState(false);
const history = useHistory();
return (
<Sidebar.Pushable>
<Sidebar
as={Menu}
animation="overlay"
icon="labeled"
inverted
onHide={() => setVisible(false)}
vertical
visible={visible}
width="thin"
>
<Menu.Item>Ogólne</Menu.Item>
<Menu.Item>Tagi</Menu.Item>
<Menu.Item>Produkty</Menu.Item>
<Menu.Item>Zakupy</Menu.Item>
</Sidebar>
<Sidebar.Pusher dimmed={visible}>
<Menu icon>
<Menu.Item onClick={() => history.push("/home")}>
<Icon name="arrow left" />
</Menu.Item>
<Menu.Item position="right" onClick={() => setVisible(true)}>
<Icon name="sidebar" />
</Menu.Item>
</Menu>
<Container>
<PieChart
animate={true}
animationDuration={500}
animationEasing="ease-out"
cx={50}
cy={50}
data={[
{
color: "#E38627",
title: "One",
value: 10
},
{
color: "#C13C37",
title: "Two",
value: 15
},
{
color: "#6A2135",
title: "Three",
value: 20
}
]}
label
labelPosition={50}
labelStyle={{
fill: "#121212",
fontFamily: "sans-serif",
fontSize: "5px"
}}
lengthAngle={360}
lineWidth={100}
onClick={undefined}
onMouseOut={undefined}
onMouseOver={undefined}
paddingAngle={0}
radius={50}
rounded={false}
startAngle={0}
viewBoxSize={[100, 100]}
/>
</Container>
</Sidebar.Pusher>
</Sidebar.Pushable>
);
}
export default Statistics;

View File

@ -0,0 +1,74 @@
import React, { useState } from "react";
import { Container, Icon, Menu, Sidebar } from "semantic-ui-react";
import {
Link,
Switch,
Route,
useHistory,
useRouteMatch
} from "react-router-dom";
import "./Statistics.css";
import { Shops, Products, Summary } from "./subscreens";
function Statistics() {
const history = useHistory();
const match = useRouteMatch();
const [visible, setVisible] = useState(false);
const handleSidebarItemClick = (event, data) => {
history.push(`${match.path}/${data.target}`);
setVisible(false);
};
return (
<Sidebar.Pushable>
<Sidebar
as={Menu}
animation="overlay"
icon="labeled"
inverted
onHide={() => setVisible(false)}
vertical
visible={visible}
width="thin"
>
<Menu.Item target="summary" onClick={handleSidebarItemClick}>
Ogólne
</Menu.Item>
<Menu.Item target="products" onClick={handleSidebarItemClick}>
Produkty
</Menu.Item>
<Menu.Item target="shops" onClick={handleSidebarItemClick}>
Sklepy
</Menu.Item>
</Sidebar>
<Sidebar.Pusher dimmed={visible}>
<Menu icon>
<Menu.Item onClick={() => history.push("/home")}>
<Icon name="arrow left" />
</Menu.Item>
<Menu.Item position="right" onClick={() => setVisible(true)}>
<Icon name="sidebar" />
</Menu.Item>
</Menu>
<Container>
<Switch>
<Route path={`${match.path}/summary`}>
<Summary />
</Route>
<Route path={`${match.path}/shops`}>
<Shops />
</Route>
<Route path={`${match.path}/products`}>
<Products />
</Route>
</Switch>
</Container>
</Sidebar.Pusher>
</Sidebar.Pushable>
);
}
export default Statistics;

View File

@ -0,0 +1,8 @@
import React, { useState } from "react";
import { Container, Icon, Menu, Accordion, Table } from "semantic-ui-react";
function Products() {
return <h1>Produkty</h1>;
}
export default Products;

View File

@ -0,0 +1,73 @@
import React, { useState } from "react";
import { Container, Icon, Menu, Accordion, Table } from "semantic-ui-react";
import PieChart from "react-minimal-pie-chart";
import {
LineChart,
Line,
BarChart,
Bar,
Brush,
Cell,
CartesianGrid,
ReferenceLine,
ReferenceDot,
XAxis,
YAxis,
Tooltip,
Legend,
ErrorBar,
LabelList
} from "recharts";
const data = [
{
color: "#E38627",
title: "Biedronka",
value: 15
},
{
color: "#C13C37",
title: "Lidl",
value: 15
},
{
color: "#6A2135",
title: "Piotr i Paweł",
value: 10
}
];
function Shops() {
return (
<Container>
<h1>Sklepy</h1>
<PieChart
animate={true}
animationDuration={500}
animationEasing="ease-out"
cx={50}
cy={50}
data={data}
label={({ data, dataIndex }) => data[dataIndex].title}
labelPosition={50}
labelStyle={{
fill: "#121212",
fontFamily: "sans-serif",
fontSize: "5px"
}}
lengthAngle={360}
lineWidth={100}
onClick={undefined}
onMouseOut={undefined}
onMouseOver={undefined}
paddingAngle={0}
radius={50}
rounded={false}
startAngle={0}
viewBoxSize={[100, 100]}
/>
</Container>
);
}
export default Shops;

View File

@ -0,0 +1,69 @@
import React, { useState, useEffect } from "react";
import { Container, Label, List } from "semantic-ui-react";
import axios from "axios";
import useGlobal from "../../../../utils/global_state";
import config from "../../../../config";
function Summary() {
const [summaryData, setSummaryData] = useState([]);
const [globalState, setGlobalState] = useGlobal();
const [summaryLoading, setSummaryLoading] = useState(true);
// load data on first render
useEffect(() => {
setSummaryLoading(true);
axios
.get(`${config.api_url}/api/stats/`, {
headers: { Authorization: `Token ${globalState.auth_token}` }
})
.then(resp => {
processResponse(resp.data);
})
.catch(err => {
console.log(err);
setSummaryLoading(false);
});
}, []);
const processResponse = data => {};
return (
<Container>
<h1>Podsumowanie</h1>
<List divided relaxed size="big">
<List.Item>
<List.Content>
<List.Header>Zapisanych paragonów</List.Header>
<List.Description as="a">31</List.Description>
</List.Content>
</List.Item>
<List.Item>
<List.Content>
<List.Header>Sklepów</List.Header>
<List.Description as="a">3</List.Description>
</List.Content>
</List.Item>
<List.Item>
<List.Content>
<List.Header>Zapisanych produktów</List.Header>
<List.Description as="a">14</List.Description>
</List.Content>
</List.Item>
<List.Item>
<List.Content>
<List.Header>Tagów produktów</List.Header>
<List.Description as="a">4</List.Description>
</List.Content>
</List.Item>
<List.Item>
<List.Content>
<List.Header>Tagów sklepów</List.Header>
<List.Description as="a">2</List.Description>
</List.Content>
</List.Item>
</List>
</Container>
);
}
export default Summary;

View File

@ -0,0 +1,5 @@
import Shops from "./Shops/Shops";
import Products from "./Products/Products";
import Summary from "./Summary/Summary";
export { Shops, Products, Summary };