diff --git a/foomo/docs/devops/monitoring/_category_.json b/foomo/docs/devops/monitoring/_category_.json
index 1fa344f..47bd214 100644
--- a/foomo/docs/devops/monitoring/_category_.json
+++ b/foomo/docs/devops/monitoring/_category_.json
@@ -1,4 +1,4 @@
{
- "label": "Monitoring",
- "position": 1
- }
\ No newline at end of file
+ "label": "Monitoring",
+ "position": 1
+}
diff --git a/foomo/docs/frontend/rtfm.md b/foomo/docs/frontend/rtfm.md
new file mode 100644
index 0000000..110f119
--- /dev/null
+++ b/foomo/docs/frontend/rtfm.md
@@ -0,0 +1,47 @@
+---
+sidebar_label: RTFM
+sidebar_position: 2
+---
+# External documentation resources
+
+## Runtime / browser
+
+In general the [Mozilla Developer Network - MDN](https://developer.mozilla.org/) is a great resource, if you want to know, what your browser is capable of.
+
+Once you found out, how great an API is, the question to answer will be ["can I use"](https://caniuse.com/) feature X. https://caniuse.com/ is a great resource to find the answers, when trying to understand, if a browser API / feature is ready to use for your audience.
+
+# JavaScript
+
+JavaScript historically has a very bad reputation. Please enjoy the following classic piece of infotainment: https://www.destroyallsoftware.com/talks/wat
+
+As JavaScript has been massively iterated on, the runtimes hav ecome crazy fast and the language keeps on evolving.
+
+The (mostly functional) subset of the language, that is being used in modern JavaScript / TypeScript projects to is highly expressive and reads well.
+
+Please take the time and learn about
+
+- functional programming
+- variable scope
+- modern JavaScript syntax
+ - arrow functions
+ - new keywords
+ - spreading
+ - ...
+- promises
+
+
+# CSS
+
+- CSS block model
+- flex box
+
+# Browser APIs
+
+- canvas
+- fetch
+- local storage
+- websockets
+- sse server side events
+- built in types
+
+## TypeScript
\ No newline at end of file
diff --git a/foomo/docs/frontend/setup.md b/foomo/docs/frontend/setup.md
index 2029360..4892317 100644
--- a/foomo/docs/frontend/setup.md
+++ b/foomo/docs/frontend/setup.md
@@ -4,28 +4,23 @@ sidebar_position: 2
---
# Frontend setup
-How to setup your machine
+How to setup your machine for frontend development
-```jsx live
-function Clock(props) {
+## Install software
- const [date, setDate] = useState(new Date());
+### Mac
- useEffect(() => {
- var timerID = setInterval(() => tick(), 1000);
- return function cleanup() {
- clearInterval(timerID);
- };
- });
+First of all install `brew` from https://brew.sh
- function tick() {
- setDate(new Date());
- }
-
- return (
-
-
It is {date.toLocaleTimeString()}.
-
- );
-}
+```zsh
+brew install nvm
+brew cask install iterm2
```
+
+### Linux
+
+
+
+### Windows
+
+Install Linux ;)
\ No newline at end of file
diff --git a/foomo/docs/frontend/stack.md b/foomo/docs/frontend/stack.md
index 4fe19c0..8b194f5 100644
--- a/foomo/docs/frontend/stack.md
+++ b/foomo/docs/frontend/stack.md
@@ -7,8 +7,30 @@ tags:
---
# Frontend Stack
+Our frontend stack is permanently changing as the underlying eco system does. We are trying to adopt technologies at the "Slope of Enlightenment" in the [hype cycle](https://en.wikipedia.org/wiki/Gartner_hype_cycle).
+
+Former iterations of our stack were MVC or MVVM frontend frameworks. Since the arrival of React and state mangement libraries like Redux and Zustand we have been building reactive applications.
+
+Reactive frontends are fun to develop and they scale.
+
## TypeScript
-## React
+Is our language of choice to build frontends for web applications.
-## gotsrpc
\ No newline at end of file
+We have adopted TypeScript very early, right after its initial public release in 2012. Here is a list of motives:
+
+- it is a superset JavaScript
+- it does not try to replace JavaScript like many other languages, which compile to JavaScript, it tries to complement and improve it, while staying compatible
+- good type system
+- great tooling
+
+While it seemed to be crazy to trust Microsoft as a friendly open source company, we have not been disappointed so far.
+
+
+## React / Preact
+
+Declarative components and views, fast to develop and fast at runtime.
+
+## gotsrpc
+
+Since we are building services in Go and not with Node.js we have created a light weight RPC framework to integrate TypeScript with Go.
\ No newline at end of file
diff --git a/foomo/docs/frontend/typescript/_category_.json b/foomo/docs/frontend/typescript/_category_.json
new file mode 100644
index 0000000..a6d4cd3
--- /dev/null
+++ b/foomo/docs/frontend/typescript/_category_.json
@@ -0,0 +1,4 @@
+{
+ "label": "TypeScript",
+ "position": 6
+}
diff --git a/foomo/docs/frontend/typescript/objects.mdx b/foomo/docs/frontend/typescript/objects.mdx
new file mode 100644
index 0000000..a193bc2
--- /dev/null
+++ b/foomo/docs/frontend/typescript/objects.mdx
@@ -0,0 +1,20 @@
+---
+sidebar_label: "Objects"
+---
+import { TypeScriptPlayground } from "../../../src/components/TypeScriptPlayground";
+
+# Object declaration syntax in TypeScript
+
+{`
+let foo:{[index:string]:number} = {
+ foo: 1
+};
+`}
+
+
+```tsx
+let foo:{[index:string]:number} = {
+ foo: 1
+};
+
+```
diff --git a/foomo/docs/frontend/typescript/spreading.md b/foomo/docs/frontend/typescript/spreading.md
new file mode 100644
index 0000000..6f16c1a
--- /dev/null
+++ b/foomo/docs/frontend/typescript/spreading.md
@@ -0,0 +1,89 @@
+# Spreading
+
+JavaScript spread syntax `(...)` is a surprisingly powerful construct. It has two main use cases in our applications:
+
+## Efficiently copying data
+
+The most important use case for this is when you are working with your applications state.
+
+```jsx live
+function () {
+ // let´s start with a relatively simple object
+ const foo = {
+ a: 1,
+ b: 2,
+ nested: {
+ child: "is not a copy",
+ },
+ };
+ // this will create a shallow copy of foo and add a field "c"
+ const bar = { ...foo, c: 3 };
+ // please note, that the nested property "nested" is not deeply copied,
+ // thus changes to this object will also affect foo.nested
+ bar.nested.child += " <- I told you so";
+
+ // .foo has been copied though and changes to it affect the original only
+ foo.a += 1;
+ return (
+ <>
+
+ -
+
foo.a was incremented by 1 and is now 2
+
+ -
+ accessing
bar.nested.child also changed{" "}
+ foo.nested.child
+
+
+ foo: {JSON.stringify(foo)}
+
+ -
+
bar.a has kept its original value 1
+
+ -
+ a new property
c was added
+
+
+ bar: {JSON.stringify(bar)}
+ >
+ );
+}
+```
+
+## Populating jsx attributes
+
+```jsx live
+function() {
+ // a simple Component, that will render all fields in props
+ const Foo = (props) => (
+
+ {
+ Object
+ .keys(props)
+ .map(key => (
+ -
+
{key}:{props[key]}
+
+ )
+ )
+ }
+
+ );
+ const data = {
+ a: 1,
+ b: 2,
+ c: 3
+ }
+ const {c,...part} = data;
+ return (
+ <>
+ all data props
+
+ all data props and d
+
+ just a part of the props, @themre please explain ;)
+
+ >
+ );
+}
+```
diff --git a/foomo/src/components/Iframe.tsx b/foomo/src/components/Iframe.tsx
index 18053ce..cfa749d 100644
--- a/foomo/src/components/Iframe.tsx
+++ b/foomo/src/components/Iframe.tsx
@@ -1,28 +1,34 @@
import React from "react";
-export const Iframe = (props: { proportion:number; src:string }) => (
-
+ );
+};
diff --git a/foomo/src/components/TypeScriptPlayground.tsx b/foomo/src/components/TypeScriptPlayground.tsx
new file mode 100644
index 0000000..4c31bcd
--- /dev/null
+++ b/foomo/src/components/TypeScriptPlayground.tsx
@@ -0,0 +1,192 @@
+import React from "react";
+
+import Highlight, { defaultProps } from "prism-react-renderer";
+
+const LZString = (() => {
+ function o(o, r) {
+ if (!t[o]) {
+ t[o] = {};
+ for (var n = 0; n < o.length; n++) t[o][o.charAt(n)] = n;
+ }
+ return t[o][r];
+ }
+ var r = String.fromCharCode,
+ n = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=",
+ e = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-$",
+ t = {},
+ i = {
+ compressToBase64: function (o) {
+ if (null == o) return "";
+ var r = i._compress(o, 6, function (o) {
+ return n.charAt(o);
+ });
+ switch (r.length % 4) {
+ default:
+ case 0:
+ return r;
+ case 1:
+ return r + "===";
+ case 2:
+ return r + "==";
+ case 3:
+ return r + "=";
+ }
+ },
+ compressToUTF16: function (o) {
+ return null == o
+ ? ""
+ : i._compress(o, 15, function (o) {
+ return r(o + 32);
+ }) + " ";
+ },
+ compressToUint8Array: function (o) {
+ for (
+ var r = i.compress(o),
+ n = new Uint8Array(2 * r.length),
+ e = 0,
+ t = r.length;
+ t > e;
+ e++
+ ) {
+ var s = r.charCodeAt(e);
+ (n[2 * e] = s >>> 8), (n[2 * e + 1] = s % 256);
+ }
+ return n;
+ },
+ compressToEncodedURIComponent: function (o) {
+ return null == o
+ ? ""
+ : i._compress(o, 6, function (o) {
+ return e.charAt(o);
+ });
+ },
+ compress: function (o) {
+ return i._compress(o, 16, function (o) {
+ return r(o);
+ });
+ },
+ _compress: function (o, r, n) {
+ if (null == o) return "";
+ var e,
+ t,
+ i,
+ s = {},
+ p = {},
+ u = "",
+ c = "",
+ a = "",
+ l = 2,
+ f = 3,
+ h = 2,
+ d = [],
+ m = 0,
+ v = 0;
+ for (i = 0; i < o.length; i += 1)
+ if (
+ ((u = o.charAt(i)),
+ Object.prototype.hasOwnProperty.call(s, u) ||
+ ((s[u] = f++), (p[u] = !0)),
+ (c = a + u),
+ Object.prototype.hasOwnProperty.call(s, c))
+ )
+ a = c;
+ else {
+ if (Object.prototype.hasOwnProperty.call(p, a)) {
+ if (a.charCodeAt(0) < 256) {
+ for (e = 0; h > e; e++)
+ (m <<= 1),
+ v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++;
+ for (t = a.charCodeAt(0), e = 0; 8 > e; e++)
+ (m = (m << 1) | (1 & t)),
+ v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++,
+ (t >>= 1);
+ } else {
+ for (t = 1, e = 0; h > e; e++)
+ (m = (m << 1) | t),
+ v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++,
+ (t = 0);
+ for (t = a.charCodeAt(0), e = 0; 16 > e; e++)
+ (m = (m << 1) | (1 & t)),
+ v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++,
+ (t >>= 1);
+ }
+ l--, 0 == l && ((l = Math.pow(2, h)), h++), delete p[a];
+ } else
+ for (t = s[a], e = 0; h > e; e++)
+ (m = (m << 1) | (1 & t)),
+ v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++,
+ (t >>= 1);
+ l--,
+ 0 == l && ((l = Math.pow(2, h)), h++),
+ (s[c] = f++),
+ (a = String(u));
+ }
+ if ("" !== a) {
+ if (Object.prototype.hasOwnProperty.call(p, a)) {
+ if (a.charCodeAt(0) < 256) {
+ for (e = 0; h > e; e++)
+ (m <<= 1), v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++;
+ for (t = a.charCodeAt(0), e = 0; 8 > e; e++)
+ (m = (m << 1) | (1 & t)),
+ v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++,
+ (t >>= 1);
+ } else {
+ for (t = 1, e = 0; h > e; e++)
+ (m = (m << 1) | t),
+ v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++,
+ (t = 0);
+ for (t = a.charCodeAt(0), e = 0; 16 > e; e++)
+ (m = (m << 1) | (1 & t)),
+ v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++,
+ (t >>= 1);
+ }
+ l--, 0 == l && ((l = Math.pow(2, h)), h++), delete p[a];
+ } else
+ for (t = s[a], e = 0; h > e; e++)
+ (m = (m << 1) | (1 & t)),
+ v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++,
+ (t >>= 1);
+ l--, 0 == l && ((l = Math.pow(2, h)), h++);
+ }
+ for (t = 2, e = 0; h > e; e++)
+ (m = (m << 1) | (1 & t)),
+ v == r - 1 ? ((v = 0), d.push(n(m)), (m = 0)) : v++,
+ (t >>= 1);
+ for (;;) {
+ if (((m <<= 1), v == r - 1)) {
+ d.push(n(m));
+ break;
+ }
+ v++;
+ }
+ return d.join("");
+ },
+ };
+ return i;
+})();
+
+export const TypeScriptPlayground = (props: { children: string }) => {
+ const url =
+ "https://www.typescriptlang.org/play?#code/" +
+ escape(LZString.compressToEncodedURIComponent(props.children));
+ return (
+
+ );
+};
diff --git a/foomo/src/pages/awesome-software.md b/foomo/src/pages/awesome-software.md
index 81d8f89..0605224 100644
--- a/foomo/src/pages/awesome-software.md
+++ b/foomo/src/pages/awesome-software.md
@@ -2,6 +2,11 @@
A list of commercial and open source software we use, because it is awesome.
+
+ Please note, when you are installing software, use a package manager
+
+
+
## desktop software
### devtools
diff --git a/foomo/src/pages/index.tsx b/foomo/src/pages/index.tsx
index ff559c7..f083268 100644
--- a/foomo/src/pages/index.tsx
+++ b/foomo/src/pages/index.tsx
@@ -1,7 +1,6 @@
import React from "react";
import clsx from "clsx";
import Layout from "@theme/Layout";
-import Link from "@docusaurus/Link";
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
import styles from "./index.module.css";
import HomepageFeatures from "../components/HomepageFeatures";
@@ -11,8 +10,12 @@ function HomepageHeader() {
return (
-
{siteConfig.title}
@@ -40,32 +43,32 @@ export default function Home(): JSX.Element {
marginRight: "auto",
}}
>
-
+
foomo is an open source project, that has been maintained by
the bestbytes team since 2011.
It provides a wide range of tools and libraries, that help us to
tackle challenging projects.
-
foomo can help, if you are
-
- -
- using Go to write services
-
- -
- building frontends with{" "}
- TypeScript and{" "}
- Next.js
-
- -
- running your software on k8s
-
- -
- looking for a solution to deeply integrate your frontends with a
- headless cms
-
-
-
If more than two points apply, it will actually help a LOT
+
foomo can help, if you are
+
+ -
+ using Go to write services
+
+ -
+ building frontends with{" "}
+ TypeScript and{" "}
+ Next.js
+
+ -
+ running your software on k8s
+
+ -
+ looking for a solution to deeply integrate your frontends with a
+ headless cms
+
+
+
If more than two points apply, it will actually help a LOT