update
This commit is contained in:
parent
34256d42ba
commit
afb278ad87
1
.babelrc
Normal file
1
.babelrc
Normal file
@ -0,0 +1 @@
|
|||||||
|
{ "presets": ["@babel/preset-env", "@babel/preset-react"] }
|
||||||
142
.eslintrc.json
Normal file
142
.eslintrc.json
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
{
|
||||||
|
"env": {
|
||||||
|
"browser": true,
|
||||||
|
"es6": true
|
||||||
|
},
|
||||||
|
"extends": [
|
||||||
|
"eslint:recommended",
|
||||||
|
"plugin:react/recommended",
|
||||||
|
"airbnb",
|
||||||
|
"plugin:@typescript-eslint/recommended",
|
||||||
|
"prettier",
|
||||||
|
"prettier/prettier",
|
||||||
|
"plugin:import/typescript"
|
||||||
|
],
|
||||||
|
"parser": "@typescript-eslint/parser",
|
||||||
|
"parserOptions": {
|
||||||
|
"ecmaFeatures": {
|
||||||
|
"experimentalObjectRestSpread": true,
|
||||||
|
"jsx": true
|
||||||
|
},
|
||||||
|
"ecmaVersion": 9,
|
||||||
|
"sourceType": "module",
|
||||||
|
"project": "./tsconfig.json"
|
||||||
|
},
|
||||||
|
"plugins": [
|
||||||
|
"react",
|
||||||
|
"@typescript-eslint",
|
||||||
|
"react-hooks"
|
||||||
|
],
|
||||||
|
"rules": {
|
||||||
|
"linebreak-style": [
|
||||||
|
"error",
|
||||||
|
"unix"
|
||||||
|
],
|
||||||
|
"semi": [
|
||||||
|
"error",
|
||||||
|
"always"
|
||||||
|
],
|
||||||
|
"react/jsx-uses-react": [
|
||||||
|
"error"
|
||||||
|
],
|
||||||
|
"react/jsx-uses-vars": [
|
||||||
|
"error"
|
||||||
|
],
|
||||||
|
"react-hooks/rules-of-hooks": "error",
|
||||||
|
// Checks rules of Hooks
|
||||||
|
"react-hooks/exhaustive-deps": "warn",
|
||||||
|
// Checks effect dependencies
|
||||||
|
"react/jsx-filename-extension": [
|
||||||
|
"warn",
|
||||||
|
{
|
||||||
|
"extensions": [
|
||||||
|
".tsx"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"import/extensions": [
|
||||||
|
"error",
|
||||||
|
"ignorePackages",
|
||||||
|
{
|
||||||
|
"js": "never",
|
||||||
|
"jsx": "never",
|
||||||
|
"ts": "never",
|
||||||
|
"tsx": "never"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"no-shadow": "off",
|
||||||
|
"@typescript-eslint/no-shadow": [
|
||||||
|
"error"
|
||||||
|
],
|
||||||
|
"lines-between-class-members": [
|
||||||
|
"warn",
|
||||||
|
"always",
|
||||||
|
{
|
||||||
|
"exceptAfterSingleLine": true
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"react/sort-comp": ["warn", {
|
||||||
|
"order": [
|
||||||
|
"static-variables",
|
||||||
|
"instance-variables",
|
||||||
|
"static-methods",
|
||||||
|
"lifecycle",
|
||||||
|
"render",
|
||||||
|
"/^render.+$/",
|
||||||
|
"instance-methods",
|
||||||
|
"everything-else"
|
||||||
|
]
|
||||||
|
}],
|
||||||
|
"import/no-extraneous-dependencies": ["error", {"devDependencies": ["src/client/**/*.tsx", "src/client/**/*.ts"]}],
|
||||||
|
"react/destructuring-assignment": ["error", "always", { "ignoreClassFields": true }],
|
||||||
|
"react/state-in-constructor": ["error", "never"],
|
||||||
|
|
||||||
|
|
||||||
|
"no-return-assign": ["error", "except-parens"],
|
||||||
|
"@typescript-eslint/no-unused-vars": ["error"],
|
||||||
|
"no-console": "off",
|
||||||
|
"no-use-before-define": "off",
|
||||||
|
"@typescript-eslint/no-use-before-define": "off",
|
||||||
|
"@typescript-eslint/no-explicit-any": "off",
|
||||||
|
"import/order": "off",
|
||||||
|
"import/prefer-default-export": "off",
|
||||||
|
"react/prop-types": "off",
|
||||||
|
"@typescript-eslint/explicit-function-return-type": "off",
|
||||||
|
"@typescript-eslint/explicit-module-boundary-types": "off",
|
||||||
|
"react/jsx-props-no-spreading": "off",
|
||||||
|
"react/jsx-boolean-value": "off",
|
||||||
|
"no-plusplus": "off",
|
||||||
|
"no-param-reassign": "off",
|
||||||
|
"default-case": "off",
|
||||||
|
"jsx-a11y/click-events-have-key-events": "off"
|
||||||
|
},
|
||||||
|
"settings": {
|
||||||
|
"react": {
|
||||||
|
"version": "detect"
|
||||||
|
},
|
||||||
|
"import/resolver": {
|
||||||
|
"typescript": {
|
||||||
|
"extensions": [
|
||||||
|
".js",
|
||||||
|
".jsx",
|
||||||
|
".ts",
|
||||||
|
".tsx"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"node": {
|
||||||
|
"extensions": [
|
||||||
|
".js",
|
||||||
|
".jsx",
|
||||||
|
".ts",
|
||||||
|
".tsx"
|
||||||
|
],
|
||||||
|
"moduleDirectory": [
|
||||||
|
"node_modules",
|
||||||
|
"src/"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"globals": {
|
||||||
|
}
|
||||||
|
}
|
||||||
9
.gitignore
vendored
Normal file
9
.gitignore
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
.DS_Store
|
||||||
|
|
||||||
|
# Generated by package manager
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Generated by Cordova
|
||||||
|
/plugins/
|
||||||
|
/platforms/
|
||||||
|
/www/
|
||||||
5
.prettierrc
Normal file
5
.prettierrc
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"printWidth": 120,
|
||||||
|
"tabWidth": 4,
|
||||||
|
"singleQuote": true
|
||||||
|
}
|
||||||
25
config.xml
Normal file
25
config.xml
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<?xml version='1.0' encoding='utf-8'?>
|
||||||
|
<widget id="io.cordova.hellocordova" version="1.0.0" xmlns="http://www.w3.org/ns/widgets" xmlns:cdv="http://cordova.apache.org/ns/1.0">
|
||||||
|
<name>HelloCordova</name>
|
||||||
|
<description>
|
||||||
|
A sample Apache Cordova application that responds to the deviceready event.
|
||||||
|
</description>
|
||||||
|
<author email="dev@cordova.apache.org" href="http://cordova.io">
|
||||||
|
Apache Cordova Team
|
||||||
|
</author>
|
||||||
|
<content src="index.html" />
|
||||||
|
<access origin="*" />
|
||||||
|
<allow-intent href="http://*/*" />
|
||||||
|
<allow-intent href="https://*/*" />
|
||||||
|
<allow-intent href="tel:*" />
|
||||||
|
<allow-intent href="sms:*" />
|
||||||
|
<allow-intent href="mailto:*" />
|
||||||
|
<allow-intent href="geo:*" />
|
||||||
|
<platform name="android">
|
||||||
|
<allow-intent href="market:*" />
|
||||||
|
</platform>
|
||||||
|
<platform name="ios">
|
||||||
|
<allow-intent href="itms:*" />
|
||||||
|
<allow-intent href="itms-apps:*" />
|
||||||
|
</platform>
|
||||||
|
</widget>
|
||||||
171
dist/bundle.js
vendored
171
dist/bundle.js
vendored
File diff suppressed because one or more lines are too long
196
dist/img/trashcan.svg
vendored
196
dist/img/trashcan.svg
vendored
@ -1,196 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
|
||||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
|
||||||
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="1.70667in" height="1.70667in"
|
|
||||||
viewBox="0 0 512 512">
|
|
||||||
<path id="Auswahl"
|
|
||||||
stroke="black" stroke-width="1"
|
|
||||||
d="M 3.00,32.00
|
|
||||||
C 11.60,32.19 14.07,27.79 22.00,24.60
|
|
||||||
22.00,24.60 38.00,19.25 38.00,19.25
|
|
||||||
38.00,19.25 49.00,16.91 49.00,16.91
|
|
||||||
49.00,16.91 57.00,14.46 57.00,14.46
|
|
||||||
57.00,14.46 73.00,11.96 73.00,11.96
|
|
||||||
73.00,11.96 85.00,9.42 85.00,9.42
|
|
||||||
85.00,9.42 109.00,6.88 109.00,6.88
|
|
||||||
109.00,6.88 117.00,5.12 117.00,5.12
|
|
||||||
117.00,5.12 160.00,2.00 160.00,2.00
|
|
||||||
160.00,2.00 180.00,0.00 180.00,0.00
|
|
||||||
180.00,0.00 336.00,0.00 336.00,0.00
|
|
||||||
343.97,0.12 340.87,1.94 350.00,2.00
|
|
||||||
350.00,2.00 354.00,2.00 354.00,2.00
|
|
||||||
354.00,2.00 397.83,5.24 397.83,5.24
|
|
||||||
397.83,5.24 404.04,6.87 404.04,6.87
|
|
||||||
404.04,6.87 432.00,10.04 432.00,10.04
|
|
||||||
432.00,10.04 439.00,11.78 439.00,11.78
|
|
||||||
439.00,11.78 457.91,14.95 457.91,14.95
|
|
||||||
457.91,14.95 465.04,17.16 465.04,17.16
|
|
||||||
465.04,17.16 489.91,24.45 489.91,24.45
|
|
||||||
496.64,26.85 501.95,32.54 509.00,34.00
|
|
||||||
509.00,34.00 504.17,82.00 504.17,82.00
|
|
||||||
504.17,82.00 496.17,159.00 496.17,159.00
|
|
||||||
496.17,159.00 472.83,386.00 472.83,386.00
|
|
||||||
472.83,386.00 464.83,463.00 464.83,463.00
|
|
||||||
464.83,463.00 462.00,489.00 462.00,489.00
|
|
||||||
462.00,489.00 439.00,496.69 439.00,496.69
|
|
||||||
412.57,501.93 370.65,507.69 344.00,508.00
|
|
||||||
344.00,508.00 329.00,509.00 329.00,509.00
|
|
||||||
329.00,509.00 290.00,510.00 290.00,510.00
|
|
||||||
290.00,510.00 273.00,511.00 273.00,511.00
|
|
||||||
273.00,511.00 210.00,511.00 210.00,511.00
|
|
||||||
210.00,511.00 193.00,510.00 193.00,510.00
|
|
||||||
193.00,510.00 172.00,510.00 172.00,510.00
|
|
||||||
172.00,510.00 136.00,508.00 136.00,508.00
|
|
||||||
136.00,508.00 110.00,505.00 110.00,505.00
|
|
||||||
110.00,505.00 101.00,505.00 101.00,505.00
|
|
||||||
101.00,505.00 69.00,499.29 69.00,499.29
|
|
||||||
63.23,497.71 52.49,496.02 48.57,491.32
|
|
||||||
46.64,489.00 46.97,484.98 46.58,482.00
|
|
||||||
46.58,482.00 43.98,456.00 43.98,456.00
|
|
||||||
43.98,456.00 40.17,418.00 40.17,418.00
|
|
||||||
40.17,418.00 35.83,372.00 35.83,372.00
|
|
||||||
35.83,372.00 13.83,148.00 13.83,148.00
|
|
||||||
13.83,148.00 6.83,77.00 6.83,77.00
|
|
||||||
6.83,77.00 3.00,32.00 3.00,32.00 Z
|
|
||||||
M 113.00,78.00
|
|
||||||
C 113.00,78.00 81.00,74.38 81.00,74.38
|
|
||||||
81.00,74.38 72.00,72.12 72.00,72.12
|
|
||||||
72.00,72.12 50.00,68.30 50.00,68.30
|
|
||||||
50.00,68.30 29.00,62.19 29.00,62.19
|
|
||||||
29.00,62.19 18.00,58.00 18.00,58.00
|
|
||||||
18.00,58.00 19.83,76.00 19.83,76.00
|
|
||||||
19.83,76.00 24.83,130.00 24.83,130.00
|
|
||||||
24.83,130.00 40.83,302.00 40.83,302.00
|
|
||||||
40.83,302.00 51.83,421.00 51.83,421.00
|
|
||||||
51.83,421.00 57.00,475.00 57.00,475.00
|
|
||||||
57.00,475.00 66.00,478.69 66.00,478.69
|
|
||||||
66.00,478.69 73.00,479.46 73.00,479.46
|
|
||||||
73.00,479.46 82.00,481.54 82.00,481.54
|
|
||||||
82.00,481.54 95.00,483.43 95.00,483.43
|
|
||||||
101.43,484.52 103.05,485.91 110.00,486.00
|
|
||||||
123.92,486.17 117.37,487.13 124.09,488.71
|
|
||||||
124.09,488.71 136.00,490.00 136.00,490.00
|
|
||||||
136.00,490.00 135.00,474.00 135.00,474.00
|
|
||||||
135.00,474.00 134.00,451.00 134.00,451.00
|
|
||||||
134.00,451.00 133.00,437.00 133.00,437.00
|
|
||||||
133.00,437.00 131.00,396.00 131.00,396.00
|
|
||||||
131.00,396.00 130.00,382.00 130.00,382.00
|
|
||||||
130.00,382.00 128.00,342.00 128.00,342.00
|
|
||||||
128.00,342.00 127.04,332.00 127.04,332.00
|
|
||||||
127.04,332.00 127.04,324.00 127.04,324.00
|
|
||||||
127.04,324.00 126.00,305.00 126.00,305.00
|
|
||||||
126.00,305.00 125.04,295.00 125.04,295.00
|
|
||||||
125.04,295.00 125.04,287.00 125.04,287.00
|
|
||||||
125.04,287.00 124.00,269.00 124.00,269.00
|
|
||||||
124.00,269.00 123.00,255.00 123.00,255.00
|
|
||||||
123.00,255.00 122.00,233.00 122.00,233.00
|
|
||||||
122.00,233.00 121.00,218.00 121.00,218.00
|
|
||||||
121.00,218.00 120.00,201.00 120.00,201.00
|
|
||||||
120.00,201.00 119.00,179.00 119.00,179.00
|
|
||||||
119.00,179.00 118.00,164.00 118.00,164.00
|
|
||||||
118.00,164.00 116.00,123.00 116.00,123.00
|
|
||||||
116.00,123.00 115.00,110.00 115.00,110.00
|
|
||||||
115.00,110.00 113.00,78.00 113.00,78.00 Z
|
|
||||||
M 493.00,58.00
|
|
||||||
C 493.00,58.00 481.00,61.80 481.00,61.80
|
|
||||||
481.00,61.80 473.00,64.83 473.00,64.83
|
|
||||||
473.00,64.83 459.00,67.84 459.00,67.84
|
|
||||||
459.00,67.84 450.00,70.54 450.00,70.54
|
|
||||||
450.00,70.54 432.00,73.27 432.00,73.27
|
|
||||||
432.00,73.27 413.00,76.72 413.00,76.72
|
|
||||||
413.00,76.72 404.74,78.74 404.74,78.74
|
|
||||||
404.74,78.74 403.00,88.00 403.00,88.00
|
|
||||||
403.00,88.00 402.00,99.00 402.00,99.00
|
|
||||||
402.00,99.00 402.00,108.00 402.00,108.00
|
|
||||||
402.00,108.00 396.91,187.00 396.91,187.00
|
|
||||||
396.91,187.00 390.91,281.00 390.91,281.00
|
|
||||||
390.91,281.00 389.09,294.00 389.09,294.00
|
|
||||||
389.09,294.00 384.00,372.00 384.00,372.00
|
|
||||||
384.00,372.00 384.00,381.00 384.00,381.00
|
|
||||||
384.00,381.00 380.09,436.00 380.09,436.00
|
|
||||||
380.09,436.00 376.00,487.00 376.00,487.00
|
|
||||||
376.00,487.00 385.00,486.00 385.00,486.00
|
|
||||||
385.00,486.00 381.00,484.00 381.00,484.00
|
|
||||||
391.63,484.48 402.51,484.61 413.00,482.34
|
|
||||||
413.00,482.34 426.00,479.01 426.00,479.01
|
|
||||||
437.40,476.56 438.80,477.78 451.00,473.00
|
|
||||||
451.00,473.00 457.83,405.00 457.83,405.00
|
|
||||||
457.83,405.00 465.17,328.00 465.17,328.00
|
|
||||||
465.17,328.00 468.83,301.00 468.83,301.00
|
|
||||||
468.83,301.00 480.17,184.00 480.17,184.00
|
|
||||||
480.17,184.00 487.18,114.00 487.18,114.00
|
|
||||||
487.18,114.00 488.82,106.00 488.82,106.00
|
|
||||||
488.82,106.00 493.00,58.00 493.00,58.00 Z
|
|
||||||
M 382.00,80.00
|
|
||||||
C 382.00,80.00 345.00,83.00 345.00,83.00
|
|
||||||
345.00,83.00 332.00,84.04 332.00,84.04
|
|
||||||
332.00,84.04 317.00,84.04 317.00,84.04
|
|
||||||
317.00,84.04 305.00,85.00 305.00,85.00
|
|
||||||
305.00,85.00 268.00,85.00 268.00,85.00
|
|
||||||
268.00,85.00 268.00,111.00 268.00,111.00
|
|
||||||
268.00,111.00 267.00,128.00 267.00,128.00
|
|
||||||
267.00,128.00 267.00,243.00 267.00,243.00
|
|
||||||
267.00,243.00 266.00,258.00 266.00,258.00
|
|
||||||
266.00,258.00 266.00,372.00 266.00,372.00
|
|
||||||
266.00,372.00 265.00,387.00 265.00,387.00
|
|
||||||
265.00,387.00 265.00,493.00 265.00,493.00
|
|
||||||
265.00,493.00 304.00,492.00 304.00,492.00
|
|
||||||
304.00,492.00 321.00,491.00 321.00,491.00
|
|
||||||
321.00,491.00 342.00,490.09 342.00,490.09
|
|
||||||
342.00,490.09 359.00,489.00 359.00,489.00
|
|
||||||
359.00,489.00 361.00,448.00 361.00,448.00
|
|
||||||
361.00,448.00 362.00,433.00 362.00,433.00
|
|
||||||
362.00,433.00 363.00,415.00 363.00,415.00
|
|
||||||
363.00,415.00 364.00,396.00 364.00,396.00
|
|
||||||
364.00,396.00 365.00,375.00 365.00,375.00
|
|
||||||
365.00,375.00 366.00,359.00 366.00,359.00
|
|
||||||
366.00,359.00 367.00,335.00 367.00,335.00
|
|
||||||
367.00,335.00 368.08,322.00 368.08,322.00
|
|
||||||
368.08,322.00 368.08,313.00 368.08,313.00
|
|
||||||
368.08,313.00 370.00,301.00 370.00,301.00
|
|
||||||
370.00,301.00 370.00,292.00 370.00,292.00
|
|
||||||
370.00,292.00 371.00,278.00 371.00,278.00
|
|
||||||
371.00,278.00 372.00,258.00 372.00,258.00
|
|
||||||
372.00,258.00 373.00,244.00 373.00,244.00
|
|
||||||
373.00,244.00 375.00,202.00 375.00,202.00
|
|
||||||
375.00,202.00 375.96,192.00 375.96,192.00
|
|
||||||
375.96,192.00 375.96,184.00 375.96,184.00
|
|
||||||
375.96,184.00 377.00,165.00 377.00,165.00
|
|
||||||
377.00,165.00 378.00,147.00 378.00,147.00
|
|
||||||
378.00,147.00 379.00,131.00 379.00,131.00
|
|
||||||
379.00,131.00 380.00,115.00 380.00,115.00
|
|
||||||
380.00,115.00 381.00,93.00 381.00,93.00
|
|
||||||
381.00,93.00 382.00,80.00 382.00,80.00 Z
|
|
||||||
M 247.00,85.00
|
|
||||||
C 247.00,85.00 208.00,85.00 208.00,85.00
|
|
||||||
208.00,85.00 196.00,84.04 196.00,84.04
|
|
||||||
196.00,84.04 183.00,84.04 183.00,84.04
|
|
||||||
183.00,84.04 167.00,83.00 167.00,83.00
|
|
||||||
167.00,83.00 134.00,81.00 134.00,81.00
|
|
||||||
134.00,81.00 135.00,93.00 135.00,93.00
|
|
||||||
135.00,93.00 136.00,121.00 136.00,121.00
|
|
||||||
136.00,121.00 137.00,138.00 137.00,138.00
|
|
||||||
137.00,138.00 138.00,165.00 138.00,165.00
|
|
||||||
138.00,165.00 139.04,179.00 139.04,179.00
|
|
||||||
139.04,179.00 139.04,190.00 139.04,190.00
|
|
||||||
139.04,190.00 140.00,202.00 140.00,202.00
|
|
||||||
140.00,202.00 141.00,223.00 141.00,223.00
|
|
||||||
141.00,223.00 142.00,252.00 142.00,252.00
|
|
||||||
142.00,252.00 143.00,267.00 143.00,267.00
|
|
||||||
143.00,267.00 144.00,287.00 144.00,287.00
|
|
||||||
144.00,287.00 145.00,316.00 145.00,316.00
|
|
||||||
145.00,316.00 146.00,331.00 146.00,331.00
|
|
||||||
146.00,331.00 148.00,380.00 148.00,380.00
|
|
||||||
148.00,380.00 149.00,394.00 149.00,394.00
|
|
||||||
149.00,394.00 150.00,422.00 150.00,422.00
|
|
||||||
150.00,422.00 151.00,439.00 151.00,439.00
|
|
||||||
151.00,439.00 152.00,459.00 152.00,459.00
|
|
||||||
152.00,459.00 153.00,491.00 153.00,491.00
|
|
||||||
153.00,491.00 173.00,492.00 173.00,492.00
|
|
||||||
173.00,492.00 195.00,492.00 195.00,492.00
|
|
||||||
195.00,492.00 211.00,493.00 211.00,493.00
|
|
||||||
211.00,493.00 247.00,493.00 247.00,493.00
|
|
||||||
247.00,493.00 247.00,85.00 247.00,85.00 Z" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 9.9 KiB |
74
dist/index.html
vendored
74
dist/index.html
vendored
@ -1,74 +0,0 @@
|
|||||||
<!DOCTYPE html>
|
|
||||||
<html lang="en">
|
|
||||||
<head>
|
|
||||||
<meta charset="UTF-8"/>
|
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
|
|
||||||
<title>Prayercircle</title>
|
|
||||||
<link href="main.css" rel="stylesheet"></head>
|
|
||||||
<body class="starting-page">
|
|
||||||
<div class="container">
|
|
||||||
<header class="header">
|
|
||||||
<div class="logo-container">
|
|
||||||
<!-- <img src="img/doge.png" alt="doge logo" class="logo-img"/>-->
|
|
||||||
<h1 class="logo-text">
|
|
||||||
<span class="logo-highlight">Prayer</span>Circle
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<section id="list-section">
|
|
||||||
<button id="add-button">+</button>
|
|
||||||
<div id="list-container">
|
|
||||||
<div id="input-template"><input class="name" placeholder="Name">
|
|
||||||
<button class="delete-button"></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section id="table-section">
|
|
||||||
<div id = "week-selection">
|
|
||||||
<button id = "previous-week"><</button>
|
|
||||||
<span id = "week-input"></span>
|
|
||||||
<button id = "next-week">></button>
|
|
||||||
</div>
|
|
||||||
<div id="table-container">
|
|
||||||
<table id="table-template" class="prayer-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="name"></th>
|
|
||||||
<th>Mo</th>
|
|
||||||
<th>Di</th>
|
|
||||||
<th>Mi</th>
|
|
||||||
<th>Do</th>
|
|
||||||
<th>Fr</th>
|
|
||||||
<th>Sa</th>
|
|
||||||
<th>So</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>Ich bete für:</td>
|
|
||||||
<td class="for-0"></td>
|
|
||||||
<td class="for-1"></td>
|
|
||||||
<td class="for-2"></td>
|
|
||||||
<td class="for-3"></td>
|
|
||||||
<td class="for-4"></td>
|
|
||||||
<td class="for-5"></td>
|
|
||||||
<td class="for-6"></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Für mich betet:</td>
|
|
||||||
<td class="by-0"></td>
|
|
||||||
<td class="by-1"></td>
|
|
||||||
<td class="by-2"></td>
|
|
||||||
<td class="by-3"></td>
|
|
||||||
<td class="by-4"></td>
|
|
||||||
<td class="by-5"></td>
|
|
||||||
<td class="by-6"></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
<script src="bundle.js"></script></body>
|
|
||||||
</html>
|
|
||||||
88
dist/main.css
vendored
88
dist/main.css
vendored
@ -1,88 +0,0 @@
|
|||||||
body {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
font-family: "Montserrat", sans-serif;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
background-color: #f9fafc;
|
|
||||||
color: #595354; }
|
|
||||||
|
|
||||||
#video-section {
|
|
||||||
position: relative; }
|
|
||||||
#video-section .site-control {
|
|
||||||
font-size: 3rem;
|
|
||||||
padding: 0.2rem;
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
transform: translate(0%, -50%); }
|
|
||||||
#video-section .site-control.previous {
|
|
||||||
left: 0; }
|
|
||||||
#video-section .site-control.next {
|
|
||||||
right: 0; }
|
|
||||||
|
|
||||||
.header {
|
|
||||||
background-color: #ffffff;
|
|
||||||
padding: 10px 40px;
|
|
||||||
box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.1); }
|
|
||||||
|
|
||||||
.header > .logo-container {
|
|
||||||
display: flex;
|
|
||||||
align-items: center; }
|
|
||||||
|
|
||||||
.header > .logo-container > .logo-img {
|
|
||||||
width: 60px;
|
|
||||||
height: 60px;
|
|
||||||
margin-right: 15px; }
|
|
||||||
|
|
||||||
.header > .logo-container > .logo-text {
|
|
||||||
font-size: 26px;
|
|
||||||
font-weight: 700; }
|
|
||||||
|
|
||||||
.header > .logo-container > .logo-text > .logo-highlight {
|
|
||||||
color: #65a9e5; }
|
|
||||||
|
|
||||||
#list-section {
|
|
||||||
margin: 1rem; }
|
|
||||||
|
|
||||||
button {
|
|
||||||
background: white;
|
|
||||||
padding: 0 0.3rem;
|
|
||||||
font-size: 1.5rem;
|
|
||||||
border: solid 1px black; }
|
|
||||||
button.delete-button {
|
|
||||||
background: url(/img/trashcan.svg);
|
|
||||||
background-size: contain;
|
|
||||||
width: 1.5rem;
|
|
||||||
height: 1.5rem;
|
|
||||||
border: 0; }
|
|
||||||
|
|
||||||
input {
|
|
||||||
border: 0;
|
|
||||||
background: transparent;
|
|
||||||
outline: none;
|
|
||||||
font-size: 1.5rem; }
|
|
||||||
input:placeholder-shown, input:focus {
|
|
||||||
border-bottom: solid 1px black; }
|
|
||||||
|
|
||||||
#week-input {
|
|
||||||
width: 3rem;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 1.5rem;
|
|
||||||
font-weight: bold; }
|
|
||||||
|
|
||||||
#table-section {
|
|
||||||
margin-top: 2rem; }
|
|
||||||
#table-section #week-selection {
|
|
||||||
margin-left: 1rem; }
|
|
||||||
#table-section #table-container .prayer-table {
|
|
||||||
max-width: calc(100% - 2rem);
|
|
||||||
margin: 1rem;
|
|
||||||
border: solid 1px #adadad;
|
|
||||||
border-collapse: collapse; }
|
|
||||||
#table-section #table-container .prayer-table td, #table-section #table-container .prayer-table th {
|
|
||||||
padding: 0.2rem;
|
|
||||||
width: 12.5%;
|
|
||||||
border: solid 1px #adadad; }
|
|
||||||
#table-section #table-container .prayer-table th {
|
|
||||||
text-align: left; }
|
|
||||||
|
|
||||||
35734
package-lock.json
generated
35734
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
114
package.json
114
package.json
@ -1,43 +1,89 @@
|
|||||||
{
|
{
|
||||||
"name": "prayercircle",
|
"name": "prayercircle.silas.link",
|
||||||
|
"displayName": "PrayerCircle",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "",
|
"description": "A sample Apache Cordova application that responds to the deviceready event.",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"compile": "webpack --config webpack.config.js",
|
"test": "echo \"Error: no test specified\" && exit 1",
|
||||||
"start": "ts-node src/server/index.ts",
|
"build": "tsc",
|
||||||
"test": "echo \"Error: no test specified\" && exit 1"
|
"start": "cordova run -- --livereload",
|
||||||
|
"eslint": "eslint 'src/**/*.tsx'"
|
||||||
},
|
},
|
||||||
"author": "",
|
"keywords": [
|
||||||
"license": "ISC",
|
"ecosystem:cordova"
|
||||||
|
],
|
||||||
|
"homepage": "./",
|
||||||
|
"author": "Apache Cordova Team",
|
||||||
|
"license": "Apache-2.0",
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.11.6",
|
"proxy-memoize": "^0.3.7",
|
||||||
"@babel/plugin-transform-runtime": "^7.11.5",
|
"@babel/core": "^7.15.0",
|
||||||
"@babel/polyfill": "^7.11.5",
|
"@babel/preset-env": "^7.15.0",
|
||||||
"autoprefixer": "^10.0.1",
|
"@babel/preset-react": "^7.14.5",
|
||||||
"babel-loader": "^8.1.0",
|
"@reduxjs/toolkit": "^1.6.1",
|
||||||
"babel-preset-env": "^1.7.0",
|
"@types/react": "^17.0.19",
|
||||||
"clean-webpack-plugin": "^3.0.0",
|
"@types/react-dom": "^17.0.9",
|
||||||
"copy-webpack-plugin": "^6.1.1",
|
"@types/react-redux": "^7.1.18",
|
||||||
"css-loader": "^4.3.0",
|
"@typescript-eslint/eslint-plugin": "^4.30.0",
|
||||||
"extract-loader": "^5.1.0",
|
"@typescript-eslint/parser": "^4.30.0",
|
||||||
"file-loader": "^6.1.0",
|
"babel-loader": "^8.2.2",
|
||||||
"html-loader": "^1.3.1",
|
"bootstrap": "^5.1.0",
|
||||||
"html-webpack-plugin": "^4.5.0",
|
"cordova-browser": "^6.0.0",
|
||||||
"mini-css-extract-plugin": "^0.11.2",
|
"cordova-plugin-webpack": "^1.0.5",
|
||||||
"node-sass": "^5.0.0",
|
"cordova-plugin-whitelist": "^1.3.4",
|
||||||
"postcss-loader": "^4.0.4",
|
"cordova-sites": "git+https://github.com/Ainias/cordova-sites.git#0.7.15",
|
||||||
"sass-loader": "^10.1.0",
|
"css-loader": "^5.2.7",
|
||||||
"terser-webpack-plugin": "^4.2.2",
|
"dotenv": "^10.0.0",
|
||||||
"ts-loader": "^8.0.4",
|
"eslint": "^7.32.0",
|
||||||
"typescript": "^4.0.2",
|
"eslint-config-airbnb": "^18.2.1",
|
||||||
"webpack": "^4.44.2",
|
"eslint-config-airbnb-typescript": "^14.0.0",
|
||||||
|
"eslint-config-prettier": "^8.3.0",
|
||||||
|
"eslint-import-resolver-typescript": "^2.4.0",
|
||||||
|
"eslint-plugin-import": "^2.25.3",
|
||||||
|
"eslint-plugin-jsx-a11y": "^6.5.1",
|
||||||
|
"eslint-plugin-react": "^7.25.1",
|
||||||
|
"eslint-plugin-react-hooks": "^4.3.0",
|
||||||
|
"file-loader": "^6.2.0",
|
||||||
|
"html-webpack-plugin": "^4.5.2",
|
||||||
|
"js-helper": "git+https://github.com/Ainias/js-helper#0.7.5",
|
||||||
|
"mini-css-extract-plugin": "^1.6.2",
|
||||||
|
"optimize-css-assets-webpack-plugin": "^6.0.1",
|
||||||
|
"postcss-flexbugs-fixes": "^5.0.2",
|
||||||
|
"postcss-loader": "^4.3.0",
|
||||||
|
"postcss-normalize": "^10.0.0",
|
||||||
|
"postcss-preset-env": "^6.7.0",
|
||||||
|
"postcss-safe-parser": "^6.0.0",
|
||||||
|
"prettier": "^2.3.2",
|
||||||
|
"react": "^17.0.2",
|
||||||
|
"react-bootstrap": "^2.0.0-beta.6",
|
||||||
|
"react-bootstrap-mobile": "git+https://github.com/Ainias/react-bootstrap-mobile#0.0.1",
|
||||||
|
"react-dom": "^17.0.2",
|
||||||
|
"react-redux": "^7.2.4",
|
||||||
|
"resolve-url-loader": "^4.0.0",
|
||||||
|
"sass": "^1.39.2",
|
||||||
|
"sass-loader": "^10.2.0",
|
||||||
|
"style-loader": "^2.0.0",
|
||||||
|
"terser-webpack-plugin": "^4.2.3",
|
||||||
|
"ts-loader": "^8.3.0",
|
||||||
|
"typescript": "^4.3.5",
|
||||||
|
"url-loader": "^4.1.1",
|
||||||
|
"webpack": "^4.46.0",
|
||||||
"webpack-cli": "^3.3.12",
|
"webpack-cli": "^3.3.12",
|
||||||
"dotenv": "^8.2.0",
|
"webpack-dev-server": "^3.11.3",
|
||||||
"ts-node": "^9.1.1",
|
"webpack-manifest-plugin": "^4.0.2",
|
||||||
"js-helper": "git+https://github.com/Ainias/js-helper.git#0.6.3"
|
"workbox-webpack-plugin": "^6.3.0",
|
||||||
|
"react-table": "^7.7.0",
|
||||||
|
"redux-persist": "^6.0.0"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"cordova": {
|
||||||
"express": "^4.17.1"
|
"plugins": {
|
||||||
|
"cordova-plugin-whitelist": {},
|
||||||
|
"cordova-plugin-webpack": {},
|
||||||
|
"cordova-plugin-nativestorage": {}
|
||||||
|
},
|
||||||
|
"platforms": [
|
||||||
|
"browser"
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 204 KiB |
@ -1,196 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
|
||||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
|
||||||
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg"
|
|
||||||
width="1.70667in" height="1.70667in"
|
|
||||||
viewBox="0 0 512 512">
|
|
||||||
<path id="Auswahl"
|
|
||||||
stroke="black" stroke-width="1"
|
|
||||||
d="M 3.00,32.00
|
|
||||||
C 11.60,32.19 14.07,27.79 22.00,24.60
|
|
||||||
22.00,24.60 38.00,19.25 38.00,19.25
|
|
||||||
38.00,19.25 49.00,16.91 49.00,16.91
|
|
||||||
49.00,16.91 57.00,14.46 57.00,14.46
|
|
||||||
57.00,14.46 73.00,11.96 73.00,11.96
|
|
||||||
73.00,11.96 85.00,9.42 85.00,9.42
|
|
||||||
85.00,9.42 109.00,6.88 109.00,6.88
|
|
||||||
109.00,6.88 117.00,5.12 117.00,5.12
|
|
||||||
117.00,5.12 160.00,2.00 160.00,2.00
|
|
||||||
160.00,2.00 180.00,0.00 180.00,0.00
|
|
||||||
180.00,0.00 336.00,0.00 336.00,0.00
|
|
||||||
343.97,0.12 340.87,1.94 350.00,2.00
|
|
||||||
350.00,2.00 354.00,2.00 354.00,2.00
|
|
||||||
354.00,2.00 397.83,5.24 397.83,5.24
|
|
||||||
397.83,5.24 404.04,6.87 404.04,6.87
|
|
||||||
404.04,6.87 432.00,10.04 432.00,10.04
|
|
||||||
432.00,10.04 439.00,11.78 439.00,11.78
|
|
||||||
439.00,11.78 457.91,14.95 457.91,14.95
|
|
||||||
457.91,14.95 465.04,17.16 465.04,17.16
|
|
||||||
465.04,17.16 489.91,24.45 489.91,24.45
|
|
||||||
496.64,26.85 501.95,32.54 509.00,34.00
|
|
||||||
509.00,34.00 504.17,82.00 504.17,82.00
|
|
||||||
504.17,82.00 496.17,159.00 496.17,159.00
|
|
||||||
496.17,159.00 472.83,386.00 472.83,386.00
|
|
||||||
472.83,386.00 464.83,463.00 464.83,463.00
|
|
||||||
464.83,463.00 462.00,489.00 462.00,489.00
|
|
||||||
462.00,489.00 439.00,496.69 439.00,496.69
|
|
||||||
412.57,501.93 370.65,507.69 344.00,508.00
|
|
||||||
344.00,508.00 329.00,509.00 329.00,509.00
|
|
||||||
329.00,509.00 290.00,510.00 290.00,510.00
|
|
||||||
290.00,510.00 273.00,511.00 273.00,511.00
|
|
||||||
273.00,511.00 210.00,511.00 210.00,511.00
|
|
||||||
210.00,511.00 193.00,510.00 193.00,510.00
|
|
||||||
193.00,510.00 172.00,510.00 172.00,510.00
|
|
||||||
172.00,510.00 136.00,508.00 136.00,508.00
|
|
||||||
136.00,508.00 110.00,505.00 110.00,505.00
|
|
||||||
110.00,505.00 101.00,505.00 101.00,505.00
|
|
||||||
101.00,505.00 69.00,499.29 69.00,499.29
|
|
||||||
63.23,497.71 52.49,496.02 48.57,491.32
|
|
||||||
46.64,489.00 46.97,484.98 46.58,482.00
|
|
||||||
46.58,482.00 43.98,456.00 43.98,456.00
|
|
||||||
43.98,456.00 40.17,418.00 40.17,418.00
|
|
||||||
40.17,418.00 35.83,372.00 35.83,372.00
|
|
||||||
35.83,372.00 13.83,148.00 13.83,148.00
|
|
||||||
13.83,148.00 6.83,77.00 6.83,77.00
|
|
||||||
6.83,77.00 3.00,32.00 3.00,32.00 Z
|
|
||||||
M 113.00,78.00
|
|
||||||
C 113.00,78.00 81.00,74.38 81.00,74.38
|
|
||||||
81.00,74.38 72.00,72.12 72.00,72.12
|
|
||||||
72.00,72.12 50.00,68.30 50.00,68.30
|
|
||||||
50.00,68.30 29.00,62.19 29.00,62.19
|
|
||||||
29.00,62.19 18.00,58.00 18.00,58.00
|
|
||||||
18.00,58.00 19.83,76.00 19.83,76.00
|
|
||||||
19.83,76.00 24.83,130.00 24.83,130.00
|
|
||||||
24.83,130.00 40.83,302.00 40.83,302.00
|
|
||||||
40.83,302.00 51.83,421.00 51.83,421.00
|
|
||||||
51.83,421.00 57.00,475.00 57.00,475.00
|
|
||||||
57.00,475.00 66.00,478.69 66.00,478.69
|
|
||||||
66.00,478.69 73.00,479.46 73.00,479.46
|
|
||||||
73.00,479.46 82.00,481.54 82.00,481.54
|
|
||||||
82.00,481.54 95.00,483.43 95.00,483.43
|
|
||||||
101.43,484.52 103.05,485.91 110.00,486.00
|
|
||||||
123.92,486.17 117.37,487.13 124.09,488.71
|
|
||||||
124.09,488.71 136.00,490.00 136.00,490.00
|
|
||||||
136.00,490.00 135.00,474.00 135.00,474.00
|
|
||||||
135.00,474.00 134.00,451.00 134.00,451.00
|
|
||||||
134.00,451.00 133.00,437.00 133.00,437.00
|
|
||||||
133.00,437.00 131.00,396.00 131.00,396.00
|
|
||||||
131.00,396.00 130.00,382.00 130.00,382.00
|
|
||||||
130.00,382.00 128.00,342.00 128.00,342.00
|
|
||||||
128.00,342.00 127.04,332.00 127.04,332.00
|
|
||||||
127.04,332.00 127.04,324.00 127.04,324.00
|
|
||||||
127.04,324.00 126.00,305.00 126.00,305.00
|
|
||||||
126.00,305.00 125.04,295.00 125.04,295.00
|
|
||||||
125.04,295.00 125.04,287.00 125.04,287.00
|
|
||||||
125.04,287.00 124.00,269.00 124.00,269.00
|
|
||||||
124.00,269.00 123.00,255.00 123.00,255.00
|
|
||||||
123.00,255.00 122.00,233.00 122.00,233.00
|
|
||||||
122.00,233.00 121.00,218.00 121.00,218.00
|
|
||||||
121.00,218.00 120.00,201.00 120.00,201.00
|
|
||||||
120.00,201.00 119.00,179.00 119.00,179.00
|
|
||||||
119.00,179.00 118.00,164.00 118.00,164.00
|
|
||||||
118.00,164.00 116.00,123.00 116.00,123.00
|
|
||||||
116.00,123.00 115.00,110.00 115.00,110.00
|
|
||||||
115.00,110.00 113.00,78.00 113.00,78.00 Z
|
|
||||||
M 493.00,58.00
|
|
||||||
C 493.00,58.00 481.00,61.80 481.00,61.80
|
|
||||||
481.00,61.80 473.00,64.83 473.00,64.83
|
|
||||||
473.00,64.83 459.00,67.84 459.00,67.84
|
|
||||||
459.00,67.84 450.00,70.54 450.00,70.54
|
|
||||||
450.00,70.54 432.00,73.27 432.00,73.27
|
|
||||||
432.00,73.27 413.00,76.72 413.00,76.72
|
|
||||||
413.00,76.72 404.74,78.74 404.74,78.74
|
|
||||||
404.74,78.74 403.00,88.00 403.00,88.00
|
|
||||||
403.00,88.00 402.00,99.00 402.00,99.00
|
|
||||||
402.00,99.00 402.00,108.00 402.00,108.00
|
|
||||||
402.00,108.00 396.91,187.00 396.91,187.00
|
|
||||||
396.91,187.00 390.91,281.00 390.91,281.00
|
|
||||||
390.91,281.00 389.09,294.00 389.09,294.00
|
|
||||||
389.09,294.00 384.00,372.00 384.00,372.00
|
|
||||||
384.00,372.00 384.00,381.00 384.00,381.00
|
|
||||||
384.00,381.00 380.09,436.00 380.09,436.00
|
|
||||||
380.09,436.00 376.00,487.00 376.00,487.00
|
|
||||||
376.00,487.00 385.00,486.00 385.00,486.00
|
|
||||||
385.00,486.00 381.00,484.00 381.00,484.00
|
|
||||||
391.63,484.48 402.51,484.61 413.00,482.34
|
|
||||||
413.00,482.34 426.00,479.01 426.00,479.01
|
|
||||||
437.40,476.56 438.80,477.78 451.00,473.00
|
|
||||||
451.00,473.00 457.83,405.00 457.83,405.00
|
|
||||||
457.83,405.00 465.17,328.00 465.17,328.00
|
|
||||||
465.17,328.00 468.83,301.00 468.83,301.00
|
|
||||||
468.83,301.00 480.17,184.00 480.17,184.00
|
|
||||||
480.17,184.00 487.18,114.00 487.18,114.00
|
|
||||||
487.18,114.00 488.82,106.00 488.82,106.00
|
|
||||||
488.82,106.00 493.00,58.00 493.00,58.00 Z
|
|
||||||
M 382.00,80.00
|
|
||||||
C 382.00,80.00 345.00,83.00 345.00,83.00
|
|
||||||
345.00,83.00 332.00,84.04 332.00,84.04
|
|
||||||
332.00,84.04 317.00,84.04 317.00,84.04
|
|
||||||
317.00,84.04 305.00,85.00 305.00,85.00
|
|
||||||
305.00,85.00 268.00,85.00 268.00,85.00
|
|
||||||
268.00,85.00 268.00,111.00 268.00,111.00
|
|
||||||
268.00,111.00 267.00,128.00 267.00,128.00
|
|
||||||
267.00,128.00 267.00,243.00 267.00,243.00
|
|
||||||
267.00,243.00 266.00,258.00 266.00,258.00
|
|
||||||
266.00,258.00 266.00,372.00 266.00,372.00
|
|
||||||
266.00,372.00 265.00,387.00 265.00,387.00
|
|
||||||
265.00,387.00 265.00,493.00 265.00,493.00
|
|
||||||
265.00,493.00 304.00,492.00 304.00,492.00
|
|
||||||
304.00,492.00 321.00,491.00 321.00,491.00
|
|
||||||
321.00,491.00 342.00,490.09 342.00,490.09
|
|
||||||
342.00,490.09 359.00,489.00 359.00,489.00
|
|
||||||
359.00,489.00 361.00,448.00 361.00,448.00
|
|
||||||
361.00,448.00 362.00,433.00 362.00,433.00
|
|
||||||
362.00,433.00 363.00,415.00 363.00,415.00
|
|
||||||
363.00,415.00 364.00,396.00 364.00,396.00
|
|
||||||
364.00,396.00 365.00,375.00 365.00,375.00
|
|
||||||
365.00,375.00 366.00,359.00 366.00,359.00
|
|
||||||
366.00,359.00 367.00,335.00 367.00,335.00
|
|
||||||
367.00,335.00 368.08,322.00 368.08,322.00
|
|
||||||
368.08,322.00 368.08,313.00 368.08,313.00
|
|
||||||
368.08,313.00 370.00,301.00 370.00,301.00
|
|
||||||
370.00,301.00 370.00,292.00 370.00,292.00
|
|
||||||
370.00,292.00 371.00,278.00 371.00,278.00
|
|
||||||
371.00,278.00 372.00,258.00 372.00,258.00
|
|
||||||
372.00,258.00 373.00,244.00 373.00,244.00
|
|
||||||
373.00,244.00 375.00,202.00 375.00,202.00
|
|
||||||
375.00,202.00 375.96,192.00 375.96,192.00
|
|
||||||
375.96,192.00 375.96,184.00 375.96,184.00
|
|
||||||
375.96,184.00 377.00,165.00 377.00,165.00
|
|
||||||
377.00,165.00 378.00,147.00 378.00,147.00
|
|
||||||
378.00,147.00 379.00,131.00 379.00,131.00
|
|
||||||
379.00,131.00 380.00,115.00 380.00,115.00
|
|
||||||
380.00,115.00 381.00,93.00 381.00,93.00
|
|
||||||
381.00,93.00 382.00,80.00 382.00,80.00 Z
|
|
||||||
M 247.00,85.00
|
|
||||||
C 247.00,85.00 208.00,85.00 208.00,85.00
|
|
||||||
208.00,85.00 196.00,84.04 196.00,84.04
|
|
||||||
196.00,84.04 183.00,84.04 183.00,84.04
|
|
||||||
183.00,84.04 167.00,83.00 167.00,83.00
|
|
||||||
167.00,83.00 134.00,81.00 134.00,81.00
|
|
||||||
134.00,81.00 135.00,93.00 135.00,93.00
|
|
||||||
135.00,93.00 136.00,121.00 136.00,121.00
|
|
||||||
136.00,121.00 137.00,138.00 137.00,138.00
|
|
||||||
137.00,138.00 138.00,165.00 138.00,165.00
|
|
||||||
138.00,165.00 139.04,179.00 139.04,179.00
|
|
||||||
139.04,179.00 139.04,190.00 139.04,190.00
|
|
||||||
139.04,190.00 140.00,202.00 140.00,202.00
|
|
||||||
140.00,202.00 141.00,223.00 141.00,223.00
|
|
||||||
141.00,223.00 142.00,252.00 142.00,252.00
|
|
||||||
142.00,252.00 143.00,267.00 143.00,267.00
|
|
||||||
143.00,267.00 144.00,287.00 144.00,287.00
|
|
||||||
144.00,287.00 145.00,316.00 145.00,316.00
|
|
||||||
145.00,316.00 146.00,331.00 146.00,331.00
|
|
||||||
146.00,331.00 148.00,380.00 148.00,380.00
|
|
||||||
148.00,380.00 149.00,394.00 149.00,394.00
|
|
||||||
149.00,394.00 150.00,422.00 150.00,422.00
|
|
||||||
150.00,422.00 151.00,439.00 151.00,439.00
|
|
||||||
151.00,439.00 152.00,459.00 152.00,459.00
|
|
||||||
152.00,459.00 153.00,491.00 153.00,491.00
|
|
||||||
153.00,491.00 173.00,492.00 173.00,492.00
|
|
||||||
173.00,492.00 195.00,492.00 195.00,492.00
|
|
||||||
195.00,492.00 211.00,493.00 211.00,493.00
|
|
||||||
211.00,493.00 247.00,493.00 247.00,493.00
|
|
||||||
247.00,493.00 247.00,85.00 247.00,85.00 Z" />
|
|
||||||
</svg>
|
|
||||||
|
Before Width: | Height: | Size: 9.9 KiB |
@ -1,74 +1,19 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8"/>
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
|
<meta http-equiv="Content-Security-Policy"
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge"/>
|
content="default-src 'self' data: gap: https://ssl.gstatic.com 'unsafe-eval'; style-src 'self' 'unsafe-inline'; media-src *; img-src 'self' data: content:;">
|
||||||
<title>Prayercircle</title>
|
<meta name="format-detection" content="telephone=no">
|
||||||
|
<meta name="msapplication-tap-highlight" content="no">
|
||||||
|
<meta name="viewport" content="initial-scale=1, width=device-width, viewport-fit=cover">
|
||||||
|
<meta name="color-scheme" content="light dark">
|
||||||
|
<!-- <link rel="stylesheet" href="css/index.css">-->
|
||||||
|
<title>Hello World</title>
|
||||||
</head>
|
</head>
|
||||||
<body class="starting-page">
|
<!--<body class="flat-design">-->
|
||||||
<div class="container">
|
<body class="material-design">
|
||||||
<header class="header">
|
<div id = "react-container" style="width: 100%;height: 100%"></div>
|
||||||
<div class="logo-container">
|
<script src="cordova.js"></script>
|
||||||
<!-- <img src="img/doge.png" alt="doge logo" class="logo-img"/>-->
|
|
||||||
<h1 class="logo-text">
|
|
||||||
<span class="logo-highlight">Prayer</span>Circle
|
|
||||||
</h1>
|
|
||||||
</div>
|
|
||||||
</header>
|
|
||||||
<section id="list-section">
|
|
||||||
<button id="add-button">+</button>
|
|
||||||
<div id="list-container">
|
|
||||||
<div id="input-template"><input class="name" placeholder="Name">
|
|
||||||
<button class="delete-button"></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
<section id="table-section">
|
|
||||||
<div id = "week-selection">
|
|
||||||
<button id = "previous-week"><</button>
|
|
||||||
<span id = "week-input"></span>
|
|
||||||
<button id = "next-week">></button>
|
|
||||||
</div>
|
|
||||||
<div id="table-container">
|
|
||||||
<table id="table-template" class="prayer-table">
|
|
||||||
<thead>
|
|
||||||
<tr>
|
|
||||||
<th class="name"></th>
|
|
||||||
<th>Mo</th>
|
|
||||||
<th>Di</th>
|
|
||||||
<th>Mi</th>
|
|
||||||
<th>Do</th>
|
|
||||||
<th>Fr</th>
|
|
||||||
<th>Sa</th>
|
|
||||||
<th>So</th>
|
|
||||||
</tr>
|
|
||||||
</thead>
|
|
||||||
<tbody>
|
|
||||||
<tr>
|
|
||||||
<td>Ich bete für:</td>
|
|
||||||
<td class="for-0"></td>
|
|
||||||
<td class="for-1"></td>
|
|
||||||
<td class="for-2"></td>
|
|
||||||
<td class="for-3"></td>
|
|
||||||
<td class="for-4"></td>
|
|
||||||
<td class="for-5"></td>
|
|
||||||
<td class="for-6"></td>
|
|
||||||
</tr>
|
|
||||||
<tr>
|
|
||||||
<td>Für mich betet:</td>
|
|
||||||
<td class="by-0"></td>
|
|
||||||
<td class="by-1"></td>
|
|
||||||
<td class="by-2"></td>
|
|
||||||
<td class="by-3"></td>
|
|
||||||
<td class="by-4"></td>
|
|
||||||
<td class="by-5"></td>
|
|
||||||
<td class="by-6"></td>
|
|
||||||
</tr>
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
</div>
|
|
||||||
</section>
|
|
||||||
</div>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
@ -1,138 +0,0 @@
|
|||||||
import {ViewHelper} from "js-helper/dist/client/ViewHelper";
|
|
||||||
import {Helper} from "js-helper/dist/shared/Helper";
|
|
||||||
|
|
||||||
export class CircleManager {
|
|
||||||
|
|
||||||
constructor(listSection, tableSection) {
|
|
||||||
this._members = [];
|
|
||||||
this._week = 0;
|
|
||||||
|
|
||||||
this._inputTemplate = listSection.querySelector("#input-template");
|
|
||||||
this._inputTemplate.remove();
|
|
||||||
this._inputTemplate.removeAttribute("id");
|
|
||||||
this._listContainer = listSection.querySelector("#list-container");
|
|
||||||
listSection.querySelector("#add-button").addEventListener("click", () => this.addMember());
|
|
||||||
|
|
||||||
this._tableTemplate = tableSection.querySelector("#table-template");
|
|
||||||
this._tableTemplate.remove();
|
|
||||||
this._tableTemplate.removeAttribute("id");
|
|
||||||
this._tableContainer = tableSection.querySelector("#table-container");
|
|
||||||
|
|
||||||
this._weekInput = tableSection.querySelector("#week-input");
|
|
||||||
tableSection.querySelector("#next-week").addEventListener("click", () => this.setWeek(this._week + 1));
|
|
||||||
tableSection.querySelector("#previous-week").addEventListener("click", () => this.setWeek(this._week - 1));
|
|
||||||
|
|
||||||
this.load();
|
|
||||||
this.setWeek(this._week);
|
|
||||||
}
|
|
||||||
|
|
||||||
setWeek(newWeek) {
|
|
||||||
newWeek = parseInt(newWeek);
|
|
||||||
if (!isNaN(newWeek)) {
|
|
||||||
newWeek = Math.max(newWeek, 0);
|
|
||||||
this._week = newWeek;
|
|
||||||
this._weekInput.innerText = (this._week + 1);
|
|
||||||
this.updateTables();
|
|
||||||
this.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
save(){
|
|
||||||
console.log("saving...");
|
|
||||||
localStorage.setItem("list", JSON.stringify({"week": this._week, "members": this._members}));
|
|
||||||
}
|
|
||||||
|
|
||||||
load(){
|
|
||||||
const jsonSavedata = localStorage.getItem("list");
|
|
||||||
console.log("liste", jsonSavedata);
|
|
||||||
if (jsonSavedata){
|
|
||||||
const data = JSON.parse(jsonSavedata);
|
|
||||||
this._week = data.week;
|
|
||||||
this._members = data.members;
|
|
||||||
this.updateList();
|
|
||||||
this.updateTables();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
updateList() {
|
|
||||||
ViewHelper.removeAllChildren(this._listContainer);
|
|
||||||
this._members.forEach((member, id) => {
|
|
||||||
const memberElement = this._inputTemplate.cloneNode(true);
|
|
||||||
memberElement.querySelector(".delete-button").addEventListener("click", () => this.deleteMember(id))
|
|
||||||
|
|
||||||
const inputElem =
|
|
||||||
memberElement.querySelector(".name");
|
|
||||||
inputElem.value = member;
|
|
||||||
inputElem.addEventListener("input", () => {
|
|
||||||
this._members[id] = inputElem.value;
|
|
||||||
this.updateTables();
|
|
||||||
this.save();
|
|
||||||
});
|
|
||||||
this._listContainer.appendChild(memberElement);
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
deleteMember(index) {
|
|
||||||
if (index >= 0 && index < this._members.length) {
|
|
||||||
this._members.splice(index, 1);
|
|
||||||
this.updateList();
|
|
||||||
this.updateTables();
|
|
||||||
this.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
addMember(name) {
|
|
||||||
name = Helper.nonNull(name, "");
|
|
||||||
this._members.push(name);
|
|
||||||
this.updateList();
|
|
||||||
this.updateTables();
|
|
||||||
this.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
updateTables() {
|
|
||||||
if (this._members.length < 2) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const tables = {};
|
|
||||||
this._members.forEach((member, index) => {
|
|
||||||
const listPrayers = [];
|
|
||||||
const listPrayedBy = [];
|
|
||||||
|
|
||||||
const otherMembers = this._members.filter((v, i) => i !== index);
|
|
||||||
|
|
||||||
let prayersIndex = index - 1;
|
|
||||||
let prayedIndex = index;
|
|
||||||
|
|
||||||
const weekOffset = this._week * 7;
|
|
||||||
prayersIndex += weekOffset;
|
|
||||||
prayedIndex -= weekOffset;
|
|
||||||
if (prayedIndex < 0) {
|
|
||||||
prayedIndex += otherMembers.length * Math.floor(weekOffset / otherMembers.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (let i = 0; i < 7; i++) {
|
|
||||||
prayersIndex = (prayersIndex + 1) % otherMembers.length
|
|
||||||
prayedIndex = (prayedIndex - 1 + otherMembers.length) % otherMembers.length;
|
|
||||||
|
|
||||||
listPrayers.push(otherMembers[prayersIndex]);
|
|
||||||
listPrayedBy.push(otherMembers[prayedIndex]);
|
|
||||||
}
|
|
||||||
|
|
||||||
tables[index] = {"for": listPrayers, "by": listPrayedBy}
|
|
||||||
});
|
|
||||||
|
|
||||||
ViewHelper.removeAllChildren(this._tableContainer);
|
|
||||||
Object.keys(tables).forEach(memberIndex => {
|
|
||||||
const tableElement = this._tableTemplate.cloneNode(true);
|
|
||||||
tableElement.querySelector(".name").innerText = this._members[memberIndex];
|
|
||||||
tables[memberIndex].for.forEach((otherMember, index) => {
|
|
||||||
tableElement.querySelector(".for-" + index).innerText = otherMember;
|
|
||||||
});
|
|
||||||
tables[memberIndex].by.forEach((otherMember, index) => {
|
|
||||||
tableElement.querySelector(".by-" + index).innerText = otherMember;
|
|
||||||
});
|
|
||||||
|
|
||||||
this._tableContainer.appendChild(tableElement);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,7 +0,0 @@
|
|||||||
import "../sass/index.scss"
|
|
||||||
import {CircleManager} from "./CircleManager";
|
|
||||||
|
|
||||||
const listSegment = document.getElementById("list-section");
|
|
||||||
const tableSegment = document.getElementById("table-section");
|
|
||||||
|
|
||||||
new CircleManager(listSegment, tableSegment);
|
|
||||||
@ -1,119 +1,2 @@
|
|||||||
body {
|
@import 'node_modules/react-bootstrap-mobile/react-bootstrap-mobile.scss';
|
||||||
margin: 0;
|
@import 'node_modules/cordova-sites/cordova-sites.scss';
|
||||||
padding: 0;
|
|
||||||
font-family: "Montserrat", sans-serif;
|
|
||||||
-webkit-font-smoothing: antialiased;
|
|
||||||
-moz-osx-font-smoothing: grayscale;
|
|
||||||
background-color: #f9fafc;
|
|
||||||
color: #595354;
|
|
||||||
}
|
|
||||||
|
|
||||||
#video-section {
|
|
||||||
position: relative;
|
|
||||||
|
|
||||||
.site-control {
|
|
||||||
font-size: 3rem;
|
|
||||||
padding: 0.2rem;
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
transform: translate(0%, -50%);
|
|
||||||
|
|
||||||
&.previous {
|
|
||||||
left: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.next {
|
|
||||||
right: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
background-color: #ffffff;
|
|
||||||
padding: 10px 40px;
|
|
||||||
box-shadow: 0px 3px 6px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.header > .logo-container {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header > .logo-container > .logo-img {
|
|
||||||
width: 60px;
|
|
||||||
height: 60px;
|
|
||||||
margin-right: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header > .logo-container > .logo-text {
|
|
||||||
font-size: 26px;
|
|
||||||
font-weight: 700;
|
|
||||||
}
|
|
||||||
|
|
||||||
.header > .logo-container > .logo-text > .logo-highlight {
|
|
||||||
color: #65a9e5;
|
|
||||||
}
|
|
||||||
|
|
||||||
#list-section{
|
|
||||||
margin: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
background: white;
|
|
||||||
padding: 0 0.3rem;
|
|
||||||
font-size: 1.5rem;
|
|
||||||
border: solid 1px black;
|
|
||||||
|
|
||||||
&.delete-button {
|
|
||||||
background: url("../img/trashcan.svg");
|
|
||||||
background-size: contain;
|
|
||||||
width: 1.5rem;
|
|
||||||
height: 1.5rem;
|
|
||||||
border: 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
input {
|
|
||||||
border: 0;
|
|
||||||
background: transparent;
|
|
||||||
outline: none;
|
|
||||||
font-size: 1.5rem;
|
|
||||||
|
|
||||||
&:placeholder-shown, &:focus {
|
|
||||||
border-bottom: solid 1px black;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#week-input{
|
|
||||||
width: 3rem;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 1.5rem;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
#table-section {
|
|
||||||
margin-top: 2rem;
|
|
||||||
|
|
||||||
#week-selection{
|
|
||||||
margin-left: 1rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
#table-container {
|
|
||||||
.prayer-table {
|
|
||||||
max-width: calc(100% - 2rem);
|
|
||||||
margin: 1rem;
|
|
||||||
border: solid 1px #adadad;
|
|
||||||
border-collapse: collapse;
|
|
||||||
|
|
||||||
td, th {
|
|
||||||
padding: 0.2rem;
|
|
||||||
width: 12.5%;
|
|
||||||
border: solid 1px #adadad;
|
|
||||||
}
|
|
||||||
|
|
||||||
th {
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
67
src/client/ts/PrayerCircle/MemberList.tsx
Normal file
67
src/client/ts/PrayerCircle/MemberList.tsx
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { FunctionComponent, useCallback } from 'react';
|
||||||
|
import { HiddenInput, List } from 'react-bootstrap-mobile';
|
||||||
|
import { useAppDispatch, useAppSelector } from '../Store/reduxHooks';
|
||||||
|
import { removeMember, saveMember, selectMembers } from './prayerCircleSlice';
|
||||||
|
import { MemberType } from './MemberType';
|
||||||
|
import { nanoid } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
|
type Props = {};
|
||||||
|
|
||||||
|
export const MemberList: FunctionComponent<Props> = React.memo(({}) => {
|
||||||
|
// Variables
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const members = useAppSelector((state) => selectMembers(state));
|
||||||
|
members.push({
|
||||||
|
id: nanoid(),
|
||||||
|
name: '',
|
||||||
|
usedForBalance: false,
|
||||||
|
});
|
||||||
|
|
||||||
|
// States
|
||||||
|
|
||||||
|
// Refs
|
||||||
|
|
||||||
|
// Callbacks
|
||||||
|
const keyExtractor = useCallback((item: MemberType) => item.id ?? 'undefined', []);
|
||||||
|
const saveChangedMember = useCallback(
|
||||||
|
({ extraData: memberId, target: { value: name } }) => {
|
||||||
|
if (name.trim() === '') {
|
||||||
|
if (memberId) {
|
||||||
|
dispatch(removeMember(memberId));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
dispatch(
|
||||||
|
saveMember({
|
||||||
|
id: memberId,
|
||||||
|
name,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
[dispatch]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Effects
|
||||||
|
|
||||||
|
// Other
|
||||||
|
|
||||||
|
// Render Functions
|
||||||
|
const renderMember = useCallback(
|
||||||
|
(member: MemberType) => {
|
||||||
|
return (
|
||||||
|
<HiddenInput
|
||||||
|
key={member.id}
|
||||||
|
noFocusHint={true}
|
||||||
|
value={member.name}
|
||||||
|
placeholder="+ Add Person"
|
||||||
|
onChange={saveChangedMember}
|
||||||
|
onChangeData={member.id}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
[saveChangedMember]
|
||||||
|
);
|
||||||
|
|
||||||
|
return <List items={members} renderItem={renderMember} keyExtractor={keyExtractor} />;
|
||||||
|
});
|
||||||
5
src/client/ts/PrayerCircle/MemberType.ts
Normal file
5
src/client/ts/PrayerCircle/MemberType.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
export type MemberType = {
|
||||||
|
id: string,
|
||||||
|
name: string,
|
||||||
|
usedForBalance?: boolean,
|
||||||
|
};
|
||||||
135
src/client/ts/PrayerCircle/PartnerTable.tsx
Normal file
135
src/client/ts/PrayerCircle/PartnerTable.tsx
Normal file
@ -0,0 +1,135 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { useCallback, useMemo } from 'react';
|
||||||
|
import { useAppDispatch, useAppSelector } from '../Store/reduxHooks';
|
||||||
|
import { selectMemberIds, setWeek } from './prayerCircleSlice';
|
||||||
|
import { Button, Flex, Grow, Table } from 'react-bootstrap-mobile';
|
||||||
|
import { PrayerCircleCalculator } from './PrayerCircleCalculator';
|
||||||
|
|
||||||
|
export type PartnerTableProps = {};
|
||||||
|
|
||||||
|
function PartnerTable({}: PartnerTableProps) {
|
||||||
|
// Variables
|
||||||
|
const membersIds = useAppSelector((state) => selectMemberIds(state));
|
||||||
|
const members = useAppSelector((state) => state.prayerCircle.members);
|
||||||
|
const week = useAppSelector((state) => state.prayerCircle.week ?? 0);
|
||||||
|
const useWeekdays = useAppSelector((state) => state.prayerCircle.useWeekdays);
|
||||||
|
const usePartners = useAppSelector((state) => state.prayerCircle.usePartners);
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
const columnsWeek = useMemo(
|
||||||
|
() => [
|
||||||
|
{
|
||||||
|
Header: 'Partner 1',
|
||||||
|
accessor: 'partner1', // accessor is the "key" in the data
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'Partner 2',
|
||||||
|
accessor: 'partner2',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
const columnsWeekdays = useMemo(
|
||||||
|
() => [
|
||||||
|
{
|
||||||
|
Header: 'Person',
|
||||||
|
accessor: 'person', // accessor is the "key" in the data
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'Mo',
|
||||||
|
accessor: 'day0',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'Di',
|
||||||
|
accessor: 'day1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'Mi',
|
||||||
|
accessor: 'day2',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'Do',
|
||||||
|
accessor: 'day3',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'Fr',
|
||||||
|
accessor: 'day4',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'Sa',
|
||||||
|
accessor: 'day5',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Header: 'So',
|
||||||
|
accessor: 'day6',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
[]
|
||||||
|
);
|
||||||
|
|
||||||
|
// States
|
||||||
|
|
||||||
|
// Refs
|
||||||
|
|
||||||
|
// Callbacks
|
||||||
|
const incrementWeek = useCallback(() => dispatch(setWeek(week + 1)), [week, dispatch]);
|
||||||
|
const decrementWeek = useCallback(() => dispatch(setWeek(week - 1)), [week, dispatch]);
|
||||||
|
|
||||||
|
// Effects
|
||||||
|
|
||||||
|
// Other
|
||||||
|
const partnerTable = useMemo(
|
||||||
|
() => PrayerCircleCalculator.generateTableFor(membersIds, usePartners),
|
||||||
|
[membersIds, usePartners]
|
||||||
|
);
|
||||||
|
|
||||||
|
if (!partnerTable || membersIds.length === 0) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const partnerTableNames = partnerTable.map((partnerColumn) => {
|
||||||
|
return Object.keys(partnerColumn).map((id) => {
|
||||||
|
const name = members[id]?.name ?? id;
|
||||||
|
const partnerName = members[partnerColumn[id]]?.name ?? partnerColumn[id];
|
||||||
|
return [name, partnerName];
|
||||||
|
}) as [string, string][];
|
||||||
|
});
|
||||||
|
|
||||||
|
let data: Record<string, string>[] = [];
|
||||||
|
if (!useWeekdays) {
|
||||||
|
const column = partnerTableNames[week % partnerTableNames.length];
|
||||||
|
data = column.map(([name1, name2]) => ({
|
||||||
|
partner1: name1,
|
||||||
|
partner2: name2,
|
||||||
|
}));
|
||||||
|
} else {
|
||||||
|
data = [];
|
||||||
|
for (let i = 0; i < 7; i++) {
|
||||||
|
const column = partnerTableNames[(week * 7 + i) % partnerTableNames.length];
|
||||||
|
column.forEach(([name1, name2], index) => {
|
||||||
|
if (!data[index]) {
|
||||||
|
data[index] = { person: name1 };
|
||||||
|
}
|
||||||
|
data[index][`day${i}`] = name2;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const columns = useWeekdays ? columnsWeekdays : columnsWeek;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Flex>
|
||||||
|
<Button onClick={decrementWeek}><</Button>
|
||||||
|
<Grow center>Woche {week + 1}</Grow>
|
||||||
|
<Button onClick={incrementWeek}>></Button>
|
||||||
|
</Flex>
|
||||||
|
{/* <List renderItem={renderPartnerPaar} keyExtractor={partnerKeyExtractor} items={partners}/> */}
|
||||||
|
<Table data={data} columns={columns} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const tmp = React.memo(PartnerTable) as typeof PartnerTable;
|
||||||
|
export { tmp as PartnerTable };
|
||||||
64
src/client/ts/PrayerCircle/PrayerCircle.tsx
Normal file
64
src/client/ts/PrayerCircle/PrayerCircle.tsx
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { Sites, useSites, useTopBar } from 'cordova-sites';
|
||||||
|
import { useState } from 'react';
|
||||||
|
import { MemberList } from './MemberList';
|
||||||
|
import { Settings } from '../Settings/Settings';
|
||||||
|
import { Card } from 'react-bootstrap-mobile';
|
||||||
|
import { PartnerTable } from './PartnerTable';
|
||||||
|
import { Col, Row } from 'react-bootstrap';
|
||||||
|
import { PrayerCircleSettings } from './PrayercircleSettings';
|
||||||
|
|
||||||
|
export type PrayerCircleProps = {};
|
||||||
|
|
||||||
|
function PrayerCircle({}: PrayerCircleProps) {
|
||||||
|
// Variables
|
||||||
|
const sites = useSites();
|
||||||
|
|
||||||
|
// States
|
||||||
|
|
||||||
|
// Refs
|
||||||
|
|
||||||
|
// Callbacks
|
||||||
|
|
||||||
|
// Effects
|
||||||
|
useTopBar({
|
||||||
|
title: 'Prayercircle',
|
||||||
|
rightButtons: [
|
||||||
|
{
|
||||||
|
title: 'Settings',
|
||||||
|
action: () => {
|
||||||
|
sites?.startSite(Settings);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
// Other
|
||||||
|
|
||||||
|
// Render Functions
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Row lg={2} sm={1}>
|
||||||
|
<Col>
|
||||||
|
<Card fullHeight={true}>
|
||||||
|
<PrayerCircleSettings />
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
<Col className="order-lg-first">
|
||||||
|
<Card noPaddingHeight={true}>
|
||||||
|
<MemberList />
|
||||||
|
</Card>
|
||||||
|
</Col>
|
||||||
|
</Row>
|
||||||
|
<Card>
|
||||||
|
<PartnerTable />
|
||||||
|
</Card>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const tmp = React.memo(PrayerCircle) as typeof PrayerCircle;
|
||||||
|
export { tmp as PrayerCircle };
|
||||||
|
|
||||||
|
Sites.addInitialization((app) => app.addDeepLink('/PrayerCircle', tmp));
|
||||||
4406
src/client/ts/PrayerCircle/PrayerCircleCalculator.ts
Normal file
4406
src/client/ts/PrayerCircle/PrayerCircleCalculator.ts
Normal file
File diff suppressed because it is too large
Load Diff
9249
src/client/ts/PrayerCircle/PrayerCircleCalculator_old.ts
Normal file
9249
src/client/ts/PrayerCircle/PrayerCircleCalculator_old.ts
Normal file
File diff suppressed because it is too large
Load Diff
41
src/client/ts/PrayerCircle/PrayercircleSettings.tsx
Normal file
41
src/client/ts/PrayerCircle/PrayercircleSettings.tsx
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { Checkbox, Switch } from 'react-bootstrap-mobile';
|
||||||
|
import { useCallback } from 'react';
|
||||||
|
import { useAppDispatch, useAppSelector } from '../Store/reduxHooks';
|
||||||
|
import { setUsePartners, setUseWeekdays } from './prayerCircleSlice';
|
||||||
|
|
||||||
|
export type PrayerCircleSettingsProps = {};
|
||||||
|
|
||||||
|
function PrayerCircleSettings({}: PrayerCircleSettingsProps) {
|
||||||
|
// Variables
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
const useWeekdays = useAppSelector((store) => store.prayerCircle.useWeekdays ?? false);
|
||||||
|
const usePartners = useAppSelector((store) => store.prayerCircle.usePartners ?? true);
|
||||||
|
|
||||||
|
// States
|
||||||
|
|
||||||
|
// Refs
|
||||||
|
|
||||||
|
// Callbacks
|
||||||
|
const onChangeUseWeekdays = useCallback(({ target: { checked } }) => dispatch(setUseWeekdays(checked)), [dispatch]);
|
||||||
|
const onChangeUsePartners = useCallback(({ target: { checked } }) => dispatch(setUsePartners(checked)), [dispatch]);
|
||||||
|
|
||||||
|
// Effects
|
||||||
|
|
||||||
|
// Other
|
||||||
|
|
||||||
|
// Render Functions
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<Switch preLabel="Kette" onChange={onChangeUsePartners} checked={usePartners}>
|
||||||
|
Partner
|
||||||
|
</Switch>
|
||||||
|
<br />
|
||||||
|
<Checkbox label="Benutze Wochentage" checked={useWeekdays} onChange={onChangeUseWeekdays} />
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const tmp = React.memo(PrayerCircleSettings) as typeof PrayerCircleSettings;
|
||||||
|
export { tmp as PrayerCircleSettings };
|
||||||
38
src/client/ts/PrayerCircle/prayerCircleSlice.ts
Normal file
38
src/client/ts/PrayerCircle/prayerCircleSlice.ts
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||||
|
import { MemberType } from './MemberType';
|
||||||
|
import memoize from 'proxy-memoize';
|
||||||
|
import type { StoreState } from '../Store/store';
|
||||||
|
|
||||||
|
export const prayerCircleSlice = createSlice({
|
||||||
|
name: 'prayerCircle',
|
||||||
|
initialState: {
|
||||||
|
members: {} as Record<string, MemberType>,
|
||||||
|
week: 0,
|
||||||
|
useWeekdays: false,
|
||||||
|
usePartners: true,
|
||||||
|
},
|
||||||
|
reducers: {
|
||||||
|
saveMember: (state, action: PayloadAction<MemberType>) => {
|
||||||
|
const member = action.payload;
|
||||||
|
state.members[member.id] = member;
|
||||||
|
},
|
||||||
|
removeMember: (state, { payload: memberId }: PayloadAction<string>) => {
|
||||||
|
delete state.members[memberId];
|
||||||
|
},
|
||||||
|
setWeek: (state, { payload: week }: PayloadAction<number>) => {
|
||||||
|
state.week = week;
|
||||||
|
},
|
||||||
|
setUseWeekdays: (state, { payload: useWeekdays }: PayloadAction<boolean>) => {
|
||||||
|
state.useWeekdays = useWeekdays;
|
||||||
|
},
|
||||||
|
setUsePartners: (state, { payload: usePartners }: PayloadAction<boolean>) => {
|
||||||
|
state.usePartners = usePartners;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const { saveMember, removeMember, setWeek, setUseWeekdays, setUsePartners } = prayerCircleSlice.actions;
|
||||||
|
export const { reducer: prayerCircle } = prayerCircleSlice;
|
||||||
|
|
||||||
|
export const selectMembers = memoize((state: StoreState) => Object.values(state.prayerCircle.members));
|
||||||
|
export const selectMemberIds = memoize((state: StoreState) => Object.keys(state.prayerCircle.members));
|
||||||
49
src/client/ts/Settings/Settings.tsx
Normal file
49
src/client/ts/Settings/Settings.tsx
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { Sites, useTopBar } from 'cordova-sites';
|
||||||
|
import { FunctionComponent, useCallback } from 'react';
|
||||||
|
import { Button, Switch } from 'react-bootstrap-mobile';
|
||||||
|
import { useAppDispatch, useAppSelector } from '../Store/reduxHooks';
|
||||||
|
import { setDesign } from './settingsSlice';
|
||||||
|
|
||||||
|
type Props = {};
|
||||||
|
|
||||||
|
export const Settings: FunctionComponent<Props> = React.memo(({}) => {
|
||||||
|
// Variables
|
||||||
|
const design = useAppSelector((state) => state.settings.design);
|
||||||
|
const isActive = design === 'flat';
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
|
// States
|
||||||
|
|
||||||
|
// Refs
|
||||||
|
|
||||||
|
// Callbacks
|
||||||
|
const toggleThemeCallback = useCallback(() => {
|
||||||
|
if (design === 'material') {
|
||||||
|
dispatch(setDesign('flat'));
|
||||||
|
} else {
|
||||||
|
dispatch(setDesign('material'));
|
||||||
|
}
|
||||||
|
}, [dispatch, design]);
|
||||||
|
|
||||||
|
// Effects
|
||||||
|
useTopBar({
|
||||||
|
title: 'Settings',
|
||||||
|
});
|
||||||
|
|
||||||
|
// Other
|
||||||
|
|
||||||
|
// Render Functions
|
||||||
|
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<Switch id="switchTheme" checked={isActive} preLabel="android" isDual={true} onChange={toggleThemeCallback}>
|
||||||
|
ios
|
||||||
|
</Switch>
|
||||||
|
<Button onClick={toggleThemeCallback}>Change Theme</Button>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
Sites.addInitialization((app) => app.addDeepLink('/Settings', Settings));
|
||||||
16
src/client/ts/Settings/settingsSlice.ts
Normal file
16
src/client/ts/Settings/settingsSlice.ts
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
import { createSlice, PayloadAction } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
|
export const settingsSlice = createSlice({
|
||||||
|
name: 'settings',
|
||||||
|
initialState: {
|
||||||
|
design: 'material' as 'material' | 'flat',
|
||||||
|
},
|
||||||
|
reducers: {
|
||||||
|
setDesign: (state, { payload: design }: PayloadAction<'material' | 'flat'>) => {
|
||||||
|
state.design = design;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const { setDesign } = settingsSlice.actions;
|
||||||
|
export const { reducer: settings } = settingsSlice;
|
||||||
6
src/client/ts/Store/reduxHooks.ts
Normal file
6
src/client/ts/Store/reduxHooks.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
import { TypedUseSelectorHook, useDispatch, useSelector } from 'react-redux';
|
||||||
|
import type { StoreState, AppDispatch } from './store';
|
||||||
|
|
||||||
|
// Use throughout your app instead of plain `useDispatch` and `useSelector`
|
||||||
|
export const useAppDispatch = () => useDispatch<AppDispatch>();
|
||||||
|
export const useAppSelector: TypedUseSelectorHook<StoreState> = useSelector;
|
||||||
41
src/client/ts/Store/store.ts
Normal file
41
src/client/ts/Store/store.ts
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
import { combineReducers, configureStore } from '@reduxjs/toolkit';
|
||||||
|
import { prayerCircle } from '../PrayerCircle/prayerCircleSlice';
|
||||||
|
import { NativeStoragePromise } from 'cordova-sites';
|
||||||
|
import { persistReducer, persistStore, FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER } from 'redux-persist';
|
||||||
|
import { settings } from '../Settings/settingsSlice';
|
||||||
|
|
||||||
|
const reducers = combineReducers({
|
||||||
|
prayerCircle,
|
||||||
|
settings,
|
||||||
|
});
|
||||||
|
|
||||||
|
const persistConfig = {
|
||||||
|
key: 'redux-store',
|
||||||
|
version: 1,
|
||||||
|
storage: NativeStoragePromise,
|
||||||
|
};
|
||||||
|
|
||||||
|
const persistedReducer = persistReducer(persistConfig, reducers);
|
||||||
|
|
||||||
|
export const store = configureStore({
|
||||||
|
reducer: persistedReducer,
|
||||||
|
middleware: (getDefaultMiddleware) =>
|
||||||
|
getDefaultMiddleware({
|
||||||
|
serializableCheck: { ignoredActions: [FLUSH, REHYDRATE, PAUSE, PERSIST, PURGE, REGISTER] },
|
||||||
|
}),
|
||||||
|
});
|
||||||
|
|
||||||
|
// let saveTimeout: TimeoutId | undefined;
|
||||||
|
// store.subscribe(() => {
|
||||||
|
// if (!saveTimeout) {
|
||||||
|
// saveTimeout = setTimeout(async () => {
|
||||||
|
// saveTimeout = undefined;
|
||||||
|
// const data = store.getState();
|
||||||
|
// await NativeStoragePromise.setItem(`store-data`, data);
|
||||||
|
// }, 500);
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
export const persistor = persistStore(store);
|
||||||
|
|
||||||
|
export type StoreState = ReturnType<typeof store.getState>;
|
||||||
|
export type AppDispatch = typeof store.dispatch;
|
||||||
46
src/client/ts/Tasks/TaskList.tsx
Normal file
46
src/client/ts/Tasks/TaskList.tsx
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import { Sites, useSites, useTopBar } from 'cordova-sites';
|
||||||
|
import { FunctionComponent } from 'react';
|
||||||
|
import { Settings } from '../Settings/Settings';
|
||||||
|
import { Input, Switch } from 'react-bootstrap-mobile';
|
||||||
|
|
||||||
|
type Props = {};
|
||||||
|
|
||||||
|
export const TaskList: FunctionComponent<Props> = React.memo(({}) => {
|
||||||
|
// Variables
|
||||||
|
const sites = useSites();
|
||||||
|
|
||||||
|
// States
|
||||||
|
|
||||||
|
// Refs
|
||||||
|
|
||||||
|
// Callbacks
|
||||||
|
|
||||||
|
// Effects
|
||||||
|
useTopBar({
|
||||||
|
title: 'TaskList',
|
||||||
|
rightButtons: [
|
||||||
|
{
|
||||||
|
title: 'Settings',
|
||||||
|
action: () => {
|
||||||
|
sites?.startSite(Settings);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
// Other
|
||||||
|
|
||||||
|
// Render Functions
|
||||||
|
return (
|
||||||
|
<>
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
<Input label="test" placeholder="Your Text" />
|
||||||
|
<Switch id="switchTheme" isDual={false} preLabel="android" onChange={(e) => console.log(e.target.checked)}>
|
||||||
|
ios
|
||||||
|
</Switch>
|
||||||
|
</>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
Sites.addInitialization((app) => app.addDeepLink('/TaskList', TaskList));
|
||||||
22
src/client/ts/Tasks/tasksSlice.ts
Normal file
22
src/client/ts/Tasks/tasksSlice.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { createSlice } from '@reduxjs/toolkit';
|
||||||
|
|
||||||
|
export const tasksSlice = createSlice({
|
||||||
|
name: 'tasks',
|
||||||
|
initialState: {
|
||||||
|
value: 0,
|
||||||
|
},
|
||||||
|
reducers: {
|
||||||
|
increment: (state) => {
|
||||||
|
state.value += 1;
|
||||||
|
},
|
||||||
|
decrement: (state) => {
|
||||||
|
state.value -= 1;
|
||||||
|
},
|
||||||
|
incrementByAmount: (state, action) => {
|
||||||
|
state.value += action.payload;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const { increment, decrement, incrementByAmount } = tasksSlice.actions;
|
||||||
|
export default tasksSlice.reducer;
|
||||||
42
src/client/ts/index.tsx
Normal file
42
src/client/ts/index.tsx
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import * as ReactDOM from 'react-dom';
|
||||||
|
import { Sites } from 'cordova-sites/dist/client';
|
||||||
|
|
||||||
|
import 'bootstrap/dist/css/bootstrap.min.css';
|
||||||
|
import '../sass/index.scss';
|
||||||
|
|
||||||
|
import { persistor, store } from './Store/store';
|
||||||
|
import { Provider } from 'react-redux';
|
||||||
|
import { PrayerCircle } from './PrayerCircle/PrayerCircle';
|
||||||
|
import { PersistGate } from 'redux-persist/integration/react';
|
||||||
|
|
||||||
|
const Wrapper = React.memo(({ children }) => {
|
||||||
|
return (
|
||||||
|
<PersistGate persistor={persistor} loading={null}>
|
||||||
|
{children}
|
||||||
|
</PersistGate>
|
||||||
|
);
|
||||||
|
});
|
||||||
|
|
||||||
|
ReactDOM.render(
|
||||||
|
<Provider store={store}>
|
||||||
|
<Sites startSite={PrayerCircle} basePath={window.location.origin} contentWrapper={Wrapper} />
|
||||||
|
</Provider>,
|
||||||
|
document.getElementById('react-container')
|
||||||
|
);
|
||||||
|
|
||||||
|
let oldDesign: 'material' | 'flat' = 'material';
|
||||||
|
store.subscribe(() => {
|
||||||
|
const newDesign = store.getState().settings.design;
|
||||||
|
if (oldDesign !== newDesign) {
|
||||||
|
oldDesign = newDesign;
|
||||||
|
|
||||||
|
if (newDesign === 'material') {
|
||||||
|
document.body.classList.remove('flat-design');
|
||||||
|
document.body.classList.add('material-design');
|
||||||
|
} else {
|
||||||
|
document.body.classList.remove('material-design');
|
||||||
|
document.body.classList.add('flat-design');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
0
src/declarations.d.ts
vendored
Normal file
0
src/declarations.d.ts
vendored
Normal file
@ -1,40 +0,0 @@
|
|||||||
import * as express from "express";
|
|
||||||
import {createServer, Server as HTTPServer} from "http";
|
|
||||||
import * as path from "path";
|
|
||||||
|
|
||||||
export class Server {
|
|
||||||
private httpServer: HTTPServer;
|
|
||||||
private app: express.Application;
|
|
||||||
|
|
||||||
private activeSockets: string[] = [];
|
|
||||||
|
|
||||||
private readonly DEFAULT_PORT = 5000;
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
this.initialize();
|
|
||||||
}
|
|
||||||
|
|
||||||
private initialize(): void {
|
|
||||||
this.app = express();
|
|
||||||
this.httpServer = createServer(this.app);
|
|
||||||
|
|
||||||
this.configureApp();
|
|
||||||
this.configureRoutes();
|
|
||||||
}
|
|
||||||
|
|
||||||
private configureApp(): void {
|
|
||||||
this.app.use(express.static(path.join(__dirname, "../../dist")));
|
|
||||||
}
|
|
||||||
|
|
||||||
private configureRoutes(): void {
|
|
||||||
this.app.get("/", (req, res) => {
|
|
||||||
res.sendFile("index.html");
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public listen(callback: (port: number) => void): void {
|
|
||||||
this.httpServer.listen(this.DEFAULT_PORT, () => {
|
|
||||||
callback(this.DEFAULT_PORT);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,99 +0,0 @@
|
|||||||
import * as stream from "stream";
|
|
||||||
import * as fs from "fs";
|
|
||||||
|
|
||||||
export class TailStream extends stream.Readable {
|
|
||||||
private filepath: string;
|
|
||||||
private fd;
|
|
||||||
private bytesRead: number = 0;
|
|
||||||
private dataAvailable: boolean;
|
|
||||||
private watcher;
|
|
||||||
private renamed: boolean = false;
|
|
||||||
|
|
||||||
constructor(filepath: string, opts?) {
|
|
||||||
super(opts);
|
|
||||||
this.filepath = filepath;
|
|
||||||
|
|
||||||
this.init();
|
|
||||||
this.initWatcher();
|
|
||||||
}
|
|
||||||
|
|
||||||
private init() {
|
|
||||||
fs.open(this.filepath, 'r', (err, fd) => {
|
|
||||||
if (err) {
|
|
||||||
console.error(err);
|
|
||||||
} else {
|
|
||||||
|
|
||||||
this.fd = fd;
|
|
||||||
this.dataAvailable = true;
|
|
||||||
this._read();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_read() {
|
|
||||||
if (!this.dataAvailable || typeof this.fd !== "number") {
|
|
||||||
return this.push('');
|
|
||||||
}
|
|
||||||
|
|
||||||
const buffer = Buffer.alloc(16 * 1024);
|
|
||||||
fs.read(this.fd, buffer, 0, buffer.length, this.bytesRead, (err, bytesRead) => {
|
|
||||||
if (err) {
|
|
||||||
console.error(err);
|
|
||||||
this.end();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (bytesRead === 0) {
|
|
||||||
if (this.renamed) {
|
|
||||||
this.end();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
this.dataAvailable = false;
|
|
||||||
this.push('');
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!this.destroyed) {
|
|
||||||
this.bytesRead += bytesRead;
|
|
||||||
this.push(buffer.slice(0, bytesRead));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private initWatcher() {
|
|
||||||
this.watcher = fs.watch(this.filepath, (event, filename) => {
|
|
||||||
if (event === "change" && !this.dataAvailable) {
|
|
||||||
this.dataAvailable = true;
|
|
||||||
this.read(0);
|
|
||||||
} else if (event === "rename") {
|
|
||||||
if (this.filepath.endsWith(".tmp") && false) {
|
|
||||||
this.dataAvailable = false;
|
|
||||||
this.filepath = this.filepath.substring(0, this.filepath.length - 4);
|
|
||||||
this.renamed = true;
|
|
||||||
this.watcher.close();
|
|
||||||
if (this.fd) {
|
|
||||||
fs.close(this.fd, () => {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
this.init();
|
|
||||||
this.initWatcher();
|
|
||||||
} else {
|
|
||||||
this.end();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
private end() {
|
|
||||||
this.dataAvailable = false;
|
|
||||||
if (this.fd) {
|
|
||||||
fs.close(this.fd, () => {
|
|
||||||
});
|
|
||||||
}
|
|
||||||
this.push(null);
|
|
||||||
if (this.watcher) {
|
|
||||||
this.watcher.close();
|
|
||||||
}
|
|
||||||
this.destroy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,8 +0,0 @@
|
|||||||
import { Server } from "./Server";
|
|
||||||
|
|
||||||
// const server = new DashServer();
|
|
||||||
const server = new Server();
|
|
||||||
|
|
||||||
server.listen(port => {
|
|
||||||
console.log(`Server is listening on http://localhost:${port}`);
|
|
||||||
});
|
|
||||||
34
tsconfig.json
Normal file
34
tsconfig.json
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "build",
|
||||||
|
"module": "CommonJS",
|
||||||
|
"target": "es5",
|
||||||
|
"lib": ["es6", "dom"],
|
||||||
|
"sourceMap": true,
|
||||||
|
"allowJs": true,
|
||||||
|
"jsx": "react",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"noImplicitReturns": true,
|
||||||
|
"noImplicitThis": true,
|
||||||
|
"noImplicitAny": true,
|
||||||
|
"strictNullChecks": true
|
||||||
|
},
|
||||||
|
"exclude": [
|
||||||
|
"node_modules",
|
||||||
|
"redux-persist",
|
||||||
|
"./node_modules",
|
||||||
|
"/home/silas/Projekte/web/prayercircle/node_modules/redux-persist/es/integration/react.js",
|
||||||
|
"build",
|
||||||
|
"scripts",
|
||||||
|
"acceptance-tests",
|
||||||
|
"webpack",
|
||||||
|
"jest",
|
||||||
|
"www",
|
||||||
|
"platforms",
|
||||||
|
"plugins",
|
||||||
|
"webpack.config.js"
|
||||||
|
],
|
||||||
|
"types": [
|
||||||
|
"typePatches"
|
||||||
|
]
|
||||||
|
}
|
||||||
537
webpack.config.js
Executable file → Normal file
537
webpack.config.js
Executable file → Normal file
@ -1,221 +1,352 @@
|
|||||||
require("dotenv").config();
|
const path = require('path');
|
||||||
|
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
|
||||||
|
|
||||||
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
const fs = require('fs');
|
||||||
const {CleanWebpackPlugin} = require('clean-webpack-plugin');
|
|
||||||
const CopyWebpackPlugin = require("copy-webpack-plugin");
|
|
||||||
const TerserPlugin = require("terser-webpack-plugin");
|
|
||||||
const webpack = require('webpack');
|
const webpack = require('webpack');
|
||||||
const path = require("path");
|
const HtmlWebpackPlugin = require('html-webpack-plugin');
|
||||||
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
|
const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin');
|
||||||
// const WorkboxPlugin = require('workbox-webpack-plugin');
|
const TerserPlugin = require('terser-webpack-plugin');
|
||||||
|
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin');
|
||||||
|
const safePostCssParser = require('postcss-safe-parser');
|
||||||
|
const { WebpackManifestPlugin: ManifestPlugin } = require('webpack-manifest-plugin');
|
||||||
|
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
|
||||||
|
const WorkboxWebpackPlugin = require('workbox-webpack-plugin');
|
||||||
|
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
|
||||||
|
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
|
||||||
|
const getCSSModuleLocalIdent = require('react-dev-utils/getCSSModuleLocalIdent');
|
||||||
|
const ModuleNotFoundPlugin = require('react-dev-utils/ModuleNotFoundPlugin');
|
||||||
|
const ForkTsCheckerWebpackPlugin = require('react-dev-utils/ForkTsCheckerWebpackPlugin');
|
||||||
|
const typescriptFormatter = require('react-dev-utils/typescriptFormatter');
|
||||||
|
|
||||||
|
const postcssNormalize = require('postcss-normalize');
|
||||||
|
const resolvePath = (relative) => path.resolve(fs.realpathSync(process.cwd()), relative);
|
||||||
|
|
||||||
let mode = (process.env.MODE || "development");
|
const shouldInlineRuntimeChunk = process.env.INLINE_RUNTIME_CHUNK !== 'false';
|
||||||
// let mode = (process.env.MODE || "production");
|
|
||||||
// let mode = "production";
|
|
||||||
|
|
||||||
// function getIp() {
|
const emitErrorsAsWarnings = process.env.ESLINT_NO_DEV_ERRORS === 'true';
|
||||||
// let ip = null;
|
const disableESLintPlugin = process.env.DISABLE_ESLINT_PLUGIN === 'true';
|
||||||
// Object.keys(ifaces).some(function (ifname) {
|
|
||||||
// return ifaces[ifname].some(function (iface) {
|
|
||||||
// if ('IPv4' !== iface.family || iface.internal !== false) {
|
|
||||||
// // skip over internal (i.e. 127.0.0.1) and non-ipv4 addresses
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// ip = iface.address;
|
|
||||||
// return true;
|
|
||||||
// });
|
|
||||||
// });
|
|
||||||
// return ip;
|
|
||||||
// }
|
|
||||||
|
|
||||||
let moduleExports = {
|
const imageInlineSizeLimit = parseInt(process.env.IMAGE_INLINE_SIZE_LIMIT || '10000');
|
||||||
|
|
||||||
//Development oder production, wird oben durch Variable angegeben (damit später per IF überprüft)
|
// Check if TypeScript is setup
|
||||||
mode: mode,
|
const useTypeScript = fs.existsSync(resolvePath('tsconfig.json'));
|
||||||
|
|
||||||
//Beinhaltet den JS-Startpunkt und SCSS-Startpunkt
|
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
|
||||||
entry: [__dirname + "/src/client/js/index.js"],
|
const cssRegex = /\.css$/;
|
||||||
// devtool: 'inline-source-map',
|
const cssModuleRegex = /\.module\.css$/;
|
||||||
|
const sassRegex = /\.(scss|sass)$/;
|
||||||
|
const sassModuleRegex = /\.module\.(scss|sass)$/;
|
||||||
|
const swSrc = 'not-existing-file.txt';
|
||||||
|
|
||||||
//Gibt Ausgabename und Ort für JS-File an
|
module.exports = (webpackEnv) => {
|
||||||
output: {
|
// const isEnvDevelopment = webpackEnv === 'development';
|
||||||
path: path.resolve(__dirname, 'dist'),
|
const isEnvDevelopment = true;
|
||||||
filename: "bundle.js"
|
// const isEnvProduction = webpackEnv === 'production';
|
||||||
},
|
const isEnvProduction = !isEnvDevelopment;
|
||||||
resolve: {
|
|
||||||
extensions: [".ts", ".js", ".mjs", ".json", "png"]
|
|
||||||
},
|
|
||||||
|
|
||||||
optimization: {
|
const getStyleLoaders = (cssOptions, preProcessor) => {
|
||||||
// minimize: false
|
const loaders = [
|
||||||
minimizer: [
|
isEnvDevelopment && require.resolve('style-loader'),
|
||||||
new TerserPlugin({
|
isEnvProduction && {
|
||||||
cache: true,
|
loader: MiniCssExtractPlugin.loader,
|
||||||
parallel: true,
|
// css is located in `static/css`, use '../../' to locate index.html folder
|
||||||
sourceMap: true, // Must be set to true if using source-maps in production
|
// in production `paths.publicUrlOrPath` can be a relative path
|
||||||
terserOptions: {
|
options: { publicPath: '../../' },
|
||||||
mangle: {
|
},
|
||||||
reserved: []
|
{
|
||||||
}
|
loader: require.resolve('css-loader'),
|
||||||
|
options: cssOptions,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
// Options for PostCSS as we reference these options twice
|
||||||
|
// Adds vendor prefixing based on your specified browser support in
|
||||||
|
// package.json
|
||||||
|
loader: require.resolve('postcss-loader'),
|
||||||
|
options: {
|
||||||
|
// Necessary for external CSS imports to work
|
||||||
|
// https://github.com/facebook/create-react-app/issues/2677
|
||||||
|
postcssOptions: {
|
||||||
|
ident: 'postcss',
|
||||||
|
plugins: () => [
|
||||||
|
require('postcss-flexbugs-fixes'),
|
||||||
|
require('postcss-preset-env')({
|
||||||
|
autoprefixer: {
|
||||||
|
flexbox: 'no-2009',
|
||||||
|
},
|
||||||
|
stage: 3,
|
||||||
|
}),
|
||||||
|
// Adds PostCSS Normalize as the reset css with default options,
|
||||||
|
// so that it honors browserslist config in package.json
|
||||||
|
// which in turn let's users customize the target behavior as per their needs.
|
||||||
|
postcssNormalize(),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
].filter(Boolean);
|
||||||
|
if (preProcessor) {
|
||||||
|
loaders.push(
|
||||||
|
{
|
||||||
|
loader: require.resolve('resolve-url-loader'),
|
||||||
|
options: {
|
||||||
|
sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
|
||||||
|
root: resolvePath('src/client'),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
loader: require.resolve(preProcessor),
|
||||||
|
options: {
|
||||||
|
sourceMap: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
})
|
);
|
||||||
]
|
}
|
||||||
},
|
return loaders;
|
||||||
|
};
|
||||||
|
|
||||||
plugins: [
|
return {
|
||||||
//Delete www before every Build (to only have nessesary files)
|
mode: 'development',
|
||||||
new CleanWebpackPlugin({cleanOnceBeforeBuildPatterns: ['**/*', '!**/.gitkeep']}),
|
entry: './src/client/ts/index.tsx',
|
||||||
|
output: {
|
||||||
// new WorkboxPlugin.GenerateSW({
|
path: resolvePath('www'),
|
||||||
// maximumFileSizeToCacheInBytes: 1024 * 1024 * 1024 * 5
|
pathinfo: isEnvDevelopment,
|
||||||
// }),
|
filename: 'index.bundle.js',
|
||||||
|
// futureEmitAssets: true,
|
||||||
//Erstellt (kopiert) die Index.html
|
// publicPath: '.',
|
||||||
new HtmlWebpackPlugin({
|
// // Point sourcemap entries to original disk location (format as URL on Windows)
|
||||||
template: '!!html-loader!src/client/index.html'
|
// devtoolModuleFilenameTemplate: isEnvProduction
|
||||||
}),
|
// ? (info) => path.relative(paths.appSrc, info.absoluteResourcePath).replace(/\\/g, '/')
|
||||||
new webpack.DefinePlugin({}),
|
// : isEnvDevelopment && ((info) => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/')),
|
||||||
new MiniCssExtractPlugin(),
|
// globalObject: 'this',
|
||||||
],
|
},
|
||||||
|
devtool: 'inline-source-map',
|
||||||
module: {
|
resolve: {
|
||||||
|
extensions: ['.tsx', '.ts', '.js', '.jsx'],
|
||||||
//Regeln: Wenn Regex zutrifft => führe Loader (in UMGEKEHRTER) Reihenfolge aus
|
},
|
||||||
rules: [
|
module: {
|
||||||
{
|
strictExportPresence: true,
|
||||||
//Kopiert HTML-Dateien in www. Nur die Dateien, welche im JS angefragt werden
|
rules: [
|
||||||
test: /html[\\\/].*\.html$/,
|
{
|
||||||
use: [
|
// Disable require.ensure as it's not a standard language feature.
|
||||||
{
|
parser: {
|
||||||
loader: 'file-loader',
|
requireEnsure: false,
|
||||||
options: {
|
|
||||||
name: '[name].[ext]',
|
|
||||||
outputPath: 'html'
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
{
|
},
|
||||||
loader: 'extract-loader'
|
{
|
||||||
},
|
// "oneOf" will traverse all following loaders until one will
|
||||||
{
|
// match the requirements. When no loader matches it will fall
|
||||||
loader: 'html-loader',
|
// back to the "file" loader at the end of the loader list.
|
||||||
options: {
|
oneOf: [
|
||||||
//Sorgt dafür, dass Child-Views funktionieren
|
{
|
||||||
attrs: [
|
test: /\.(ts|tsx)$/,
|
||||||
":data-view",
|
exclude: /node_modules/,
|
||||||
":src",
|
use: {
|
||||||
"link:href"
|
loader: 'ts-loader',
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
test: /\.tsx?$/,
|
|
||||||
use: ["ts-loader"],
|
|
||||||
},
|
|
||||||
{
|
|
||||||
//Kopiert nur benutzte Bilder/Videos/Sound (benutzt durch JS (import), html oder css/sass)
|
|
||||||
test: /(img|video|sound)[\\\/]/,
|
|
||||||
use: [
|
|
||||||
{
|
|
||||||
loader: 'file-loader',
|
|
||||||
options: {
|
|
||||||
name: (resourcePath, resourceQuery) => {
|
|
||||||
// console.log("path", resourcePath);
|
|
||||||
// console.log("query", resourceQuery);
|
|
||||||
return "[name].[ext]"
|
|
||||||
},
|
},
|
||||||
outputPath: 'img',
|
},
|
||||||
publicPath: (url, resourcePath, context) => {
|
{
|
||||||
// console.log("url: ", url);
|
test: /\.(js|jsx)$/,
|
||||||
// console.log("resourcePath: ", resourcePath);
|
exclude: /node_modules/,
|
||||||
// console.log("context: ", context);
|
use: {
|
||||||
|
loader: 'babel-loader',
|
||||||
return "/img/" + url;
|
|
||||||
},
|
},
|
||||||
// useRelativePath: false
|
},
|
||||||
}
|
|
||||||
},
|
// "postcss" loader applies autoprefixer to our CSS.
|
||||||
],
|
// "css" loader resolves paths in CSS and adds assets as dependencies.
|
||||||
},
|
// "style" loader turns CSS into JS modules that inject <style> tags.
|
||||||
{
|
// In production, we use MiniCSSExtractPlugin to extract that CSS
|
||||||
//Compiliert SASS zu CSS und speichert es in Datei
|
// to a file, but in development "style" loader enables hot editing
|
||||||
test: /\.scss$/,
|
// of CSS.
|
||||||
use: [
|
// By default we support CSS Modules with the extension .module.css
|
||||||
// {
|
{
|
||||||
// loader: 'file-loader',
|
test: cssRegex,
|
||||||
// options: {
|
exclude: cssModuleRegex,
|
||||||
// name: '[name].css',
|
use: getStyleLoaders({
|
||||||
// outputPath: 'css',
|
importLoaders: 1,
|
||||||
// // publicPath: '/css'
|
sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
|
||||||
// }
|
}),
|
||||||
// },
|
// Don't consider CSS imports dead code even if the
|
||||||
// {
|
// containing package claims to have no side effects.
|
||||||
// loader: 'extract-loader'
|
// Remove this when webpack adds a warning or an error for this.
|
||||||
// },
|
// See https://github.com/webpack/webpack/issues/6571
|
||||||
|
sideEffects: true,
|
||||||
|
},
|
||||||
|
// Adds support for CSS Modules (https://github.com/css-modules/css-modules)
|
||||||
|
// using the extension .module.css
|
||||||
|
{
|
||||||
|
test: cssModuleRegex,
|
||||||
|
use: getStyleLoaders({
|
||||||
|
importLoaders: 1,
|
||||||
|
sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
|
||||||
|
modules: {
|
||||||
|
getLocalIdent: getCSSModuleLocalIdent,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
},
|
||||||
|
// Opt-in support for SASS (using .scss or .sass extensions).
|
||||||
|
// By default we support SASS Modules with the
|
||||||
|
// extensions .module.scss or .module.sass
|
||||||
|
{
|
||||||
|
test: sassRegex,
|
||||||
|
exclude: sassModuleRegex,
|
||||||
|
use: getStyleLoaders(
|
||||||
|
{
|
||||||
|
importLoaders: 3,
|
||||||
|
sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
|
||||||
|
},
|
||||||
|
'sass-loader'
|
||||||
|
),
|
||||||
|
// Don't consider CSS imports dead code even if the
|
||||||
|
// containing package claims to have no side effects.
|
||||||
|
// Remove this when webpack adds a warning or an error for this.
|
||||||
|
// See https://github.com/webpack/webpack/issues/6571
|
||||||
|
sideEffects: true,
|
||||||
|
},
|
||||||
|
// Adds support for CSS Modules, but using SASS
|
||||||
|
// using the extension .module.scss or .module.sass
|
||||||
|
{
|
||||||
|
test: sassModuleRegex,
|
||||||
|
use: getStyleLoaders(
|
||||||
|
{
|
||||||
|
importLoaders: 3,
|
||||||
|
sourceMap: isEnvProduction ? shouldUseSourceMap : isEnvDevelopment,
|
||||||
|
modules: {
|
||||||
|
getLocalIdent: getCSSModuleLocalIdent,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
'sass-loader'
|
||||||
|
),
|
||||||
|
},
|
||||||
|
|
||||||
|
// "file" loader makes sure those assets get served by WebpackDevServer.
|
||||||
|
// When you `import` an asset, you get its (virtual) filename.
|
||||||
|
// In production, they would get copied to the `build` folder.
|
||||||
|
// This loader doesn't use a "test" so it will catch all modules
|
||||||
|
// that fall through the other loaders.
|
||||||
|
{
|
||||||
|
loader: require.resolve('file-loader'),
|
||||||
|
// Exclude `js` files to keep "css" loader working as it injects
|
||||||
|
// its runtime that would otherwise be processed through "file" loader.
|
||||||
|
// Also exclude `html` and `json` extensions so they get processed
|
||||||
|
// by webpacks internal loaders.
|
||||||
|
exclude: [/\.(js|mjs|jsx|ts|tsx)$/, /\.html$/, /\.json$/],
|
||||||
|
options: {
|
||||||
|
name: 'static/media/[name].[hash:8].[ext]',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// ** STOP ** Are you adding a new loader?
|
||||||
|
// Make sure to add the new loader(s) before the "file" loader.
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
plugins: [
|
||||||
|
// Generates an `index.html` file with the <script> injected.
|
||||||
|
new HtmlWebpackPlugin(
|
||||||
|
Object.assign(
|
||||||
|
{},
|
||||||
{
|
{
|
||||||
loader: MiniCssExtractPlugin.loader,
|
inject: true,
|
||||||
|
template: resolvePath('src/client/index.html'),
|
||||||
},
|
},
|
||||||
{
|
isEnvProduction
|
||||||
loader: 'css-loader'
|
? {
|
||||||
},
|
minify: {
|
||||||
{
|
removeComments: true,
|
||||||
//Compiliert zu CSS
|
collapseWhitespace: true,
|
||||||
loader: 'sass-loader'
|
removeRedundantAttributes: true,
|
||||||
}
|
useShortDoctype: true,
|
||||||
]
|
removeEmptyAttributes: true,
|
||||||
}
|
removeStyleLinkTypeAttributes: true,
|
||||||
]
|
keepClosingSlash: true,
|
||||||
}
|
minifyJS: true,
|
||||||
|
minifyCSS: true,
|
||||||
|
minifyURLs: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
: undefined
|
||||||
|
)
|
||||||
|
),
|
||||||
|
// Inlines the webpack runtime script. This script is too small to warrant
|
||||||
|
// a network request.
|
||||||
|
// https://github.com/facebook/create-react-app/issues/5358
|
||||||
|
isEnvProduction &&
|
||||||
|
shouldInlineRuntimeChunk &&
|
||||||
|
new InlineChunkHtmlPlugin(HtmlWebpackPlugin, [/runtime-.+[.]js/]),
|
||||||
|
//TODO entfernen?
|
||||||
|
// Makes some environment variables available in index.html.
|
||||||
|
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
|
||||||
|
// <link rel="icon" href="%PUBLIC_URL%/favicon.ico">
|
||||||
|
// It will be an empty string unless you specify "homepage"
|
||||||
|
// in `package.json`, in which case it will be the pathname of that URL.
|
||||||
|
// new InterpolateHtmlPlugin(HtmlWebpackPlugin, env.raw),
|
||||||
|
|
||||||
|
// This gives some necessary context to module not found errors, such as
|
||||||
|
// the requesting resource.
|
||||||
|
new ModuleNotFoundPlugin(resolvePath('.')),
|
||||||
|
|
||||||
|
//TODO Check
|
||||||
|
// Makes some environment variables available to the JS code, for example:
|
||||||
|
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
|
||||||
|
// It is absolutely essential that NODE_ENV is set to production
|
||||||
|
// during a production build.
|
||||||
|
// Otherwise React will be compiled in the very slow development mode.
|
||||||
|
// new webpack.DefinePlugin(env.stringified),
|
||||||
|
|
||||||
|
//TODO Check
|
||||||
|
// // Watcher doesn't work well if you mistype casing in a path so we use
|
||||||
|
// // a plugin that prints an error when you attempt to do this.
|
||||||
|
// // See https://github.com/facebook/create-react-app/issues/240
|
||||||
|
// isEnvDevelopment && new CaseSensitivePathsPlugin(),
|
||||||
|
|
||||||
|
isEnvProduction &&
|
||||||
|
new MiniCssExtractPlugin({
|
||||||
|
// Options similar to the same options in webpackOptions.output
|
||||||
|
// both options are optional
|
||||||
|
//TODO evtl in static ordner?
|
||||||
|
filename: 'css/[name].[contenthash:8].css',
|
||||||
|
chunkFilename: 'css/[name].[contenthash:8].chunk.css',
|
||||||
|
}),
|
||||||
|
|
||||||
|
//TODO publicPath anpassen
|
||||||
|
// Generate an asset manifest file with the following content:
|
||||||
|
// - "files" key: Mapping of all asset filenames to their corresponding
|
||||||
|
// output file so that tools can pick it up without having to parse
|
||||||
|
// `index.html`
|
||||||
|
// - "entrypoints" key: Array of files which are included in `index.html`,
|
||||||
|
// can be used to reconstruct the HTML if necessary
|
||||||
|
new ManifestPlugin({
|
||||||
|
fileName: 'asset-manifest.json',
|
||||||
|
publicPath: '.',
|
||||||
|
generate: (seed, files, entrypoints) => {
|
||||||
|
const manifestFiles = files.reduce((manifest, file) => {
|
||||||
|
manifest[file.name] = file.path;
|
||||||
|
return manifest;
|
||||||
|
}, seed);
|
||||||
|
const entrypointFiles = entrypoints.main.filter((fileName) => !fileName.endsWith('.map'));
|
||||||
|
|
||||||
|
return {
|
||||||
|
files: manifestFiles,
|
||||||
|
entrypoints: entrypointFiles,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
|
||||||
|
// Generate a service worker script that will precache, and keep up to date,
|
||||||
|
// the HTML & assets that are part of the webpack build.
|
||||||
|
isEnvProduction &&
|
||||||
|
fs.existsSync(swSrc) &&
|
||||||
|
new WorkboxWebpackPlugin.InjectManifest({
|
||||||
|
swSrc,
|
||||||
|
dontCacheBustURLsMatching: /\.[0-9a-f]{8}\./,
|
||||||
|
exclude: [/\.map$/, /asset-manifest\.json$/, /LICENSE/],
|
||||||
|
// Bump up the default maximum size (2mb) that's precached,
|
||||||
|
// to make lazy-loading failure scenarios less likely.
|
||||||
|
// See https://github.com/cra-template/pwa/issues/13#issuecomment-722667270
|
||||||
|
maximumFileSizeToCacheInBytes: 5 * 1024 * 1024,
|
||||||
|
}),
|
||||||
|
].filter(Boolean),
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
//Auslagerung von zeitintensiven Sachen in production only, damit Debugging schneller geht
|
|
||||||
if (mode === "production" && false) {
|
|
||||||
|
|
||||||
//Polyfills hinzufügen
|
|
||||||
moduleExports["entry"].unshift("@babel/polyfill");
|
|
||||||
// moduleExports["devtool"] = "source-map";
|
|
||||||
|
|
||||||
//Transpilieren zu ES5
|
|
||||||
moduleExports["module"]["rules"].push({
|
|
||||||
test: /\.m?js$/,
|
|
||||||
exclude: /node_modules\/(?!(cordova-sites|js-helper|cs-event-manager|polygon-geometry))/,
|
|
||||||
use: {
|
|
||||||
loader: 'babel-loader',
|
|
||||||
options: {
|
|
||||||
presets: ['@babel/preset-env'],
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
moduleExports["module"]["rules"][1]["use"].unshift({
|
|
||||||
loader: 'babel-loader',
|
|
||||||
options: {
|
|
||||||
presets: ['@babel/preset-env'],
|
|
||||||
inputSourceMap: "inline",
|
|
||||||
sourceMaps: true
|
|
||||||
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
//Hinzufügen von POSTCSS und Autoprefixer für alte css-Präfixe
|
|
||||||
moduleExports["module"]["rules"][3]["use"].splice(3, 0, {
|
|
||||||
//PostCSS ist nicht wichtig, autoprefixer schon. Fügt Präfixes hinzu (Bsp.: -webkit), wo diese benötigt werden
|
|
||||||
loader: 'postcss-loader',
|
|
||||||
options: {
|
|
||||||
plugins: [require('autoprefixer')()]
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
// moduleExports["optimization"] = {
|
|
||||||
// minimize: false,
|
|
||||||
// // minimizer: [new UglifyJsPlugin({
|
|
||||||
// // include: /\.min\.js$/
|
|
||||||
// // })]
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
|
|
||||||
module.exports = moduleExports;
|
|
||||||
|
|
||||||
|
|||||||
0
www/.gitkeep
Normal file
0
www/.gitkeep
Normal file
Loading…
x
Reference in New Issue
Block a user