mirror of
https://github.com/foomo/foomo-docs.git
synced 2025-10-16 12:35:40 +00:00
more docs bootsrapping
This commit is contained in:
parent
2421db2805
commit
d222061f86
@ -1,4 +1,4 @@
|
||||
{
|
||||
"label": "Monitoring",
|
||||
"position": 1
|
||||
}
|
||||
"label": "Monitoring",
|
||||
"position": 1
|
||||
}
|
||||
|
||||
47
foomo/docs/frontend/rtfm.md
Normal file
47
foomo/docs/frontend/rtfm.md
Normal file
@ -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
|
||||
@ -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 (
|
||||
<div>
|
||||
<h2>It is {date.toLocaleTimeString()}.</h2>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```zsh
|
||||
brew install nvm
|
||||
brew cask install iterm2
|
||||
```
|
||||
|
||||
### Linux
|
||||
|
||||
|
||||
|
||||
### Windows
|
||||
|
||||
Install Linux ;)
|
||||
@ -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
|
||||
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.
|
||||
4
foomo/docs/frontend/typescript/_category_.json
Normal file
4
foomo/docs/frontend/typescript/_category_.json
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"label": "TypeScript",
|
||||
"position": 6
|
||||
}
|
||||
20
foomo/docs/frontend/typescript/objects.mdx
Normal file
20
foomo/docs/frontend/typescript/objects.mdx
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
sidebar_label: "Objects"
|
||||
---
|
||||
import { TypeScriptPlayground } from "../../../src/components/TypeScriptPlayground";
|
||||
|
||||
# Object declaration syntax in TypeScript
|
||||
|
||||
<TypeScriptPlayground>{`
|
||||
let foo:{[index:string]:number} = {
|
||||
foo: 1
|
||||
};
|
||||
`}
|
||||
</TypeScriptPlayground>
|
||||
|
||||
```tsx
|
||||
let foo:{[index:string]:number} = {
|
||||
foo: 1
|
||||
};
|
||||
|
||||
```
|
||||
89
foomo/docs/frontend/typescript/spreading.md
Normal file
89
foomo/docs/frontend/typescript/spreading.md
Normal file
@ -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 (
|
||||
<>
|
||||
<ul>
|
||||
<li>
|
||||
<code>foo.a</code> was incremented by 1 and is now <code>2</code>
|
||||
</li>
|
||||
<li>
|
||||
accessing <code>bar.nested.child</code> also changed{" "}
|
||||
<code>foo.nested.child</code>
|
||||
</li>
|
||||
</ul>
|
||||
<pre>foo: {JSON.stringify(foo)}</pre>
|
||||
<ul>
|
||||
<li>
|
||||
<code>bar.a</code> has kept its original value <code>1</code>
|
||||
</li>
|
||||
<li>
|
||||
a new property <code>c</code> was added
|
||||
</li>
|
||||
</ul>
|
||||
<pre>bar: {JSON.stringify(bar)}</pre>
|
||||
</>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Populating jsx attributes
|
||||
|
||||
```jsx live
|
||||
function() {
|
||||
// a simple Component, that will render all fields in props
|
||||
const Foo = (props) => (
|
||||
<ul>
|
||||
{
|
||||
Object
|
||||
.keys(props)
|
||||
.map(key => (
|
||||
<li>
|
||||
<code>{key}</code>:{props[key]}
|
||||
</li>
|
||||
)
|
||||
)
|
||||
}
|
||||
</ul>
|
||||
);
|
||||
const data = {
|
||||
a: 1,
|
||||
b: 2,
|
||||
c: 3
|
||||
}
|
||||
const {c,...part} = data;
|
||||
return (
|
||||
<>
|
||||
<p>all data props</p>
|
||||
<Foo {...data}/>
|
||||
<p>all data props and d</p>
|
||||
<Foo {...data} d={4}/>
|
||||
<p>just a part of the props, @themre please explain ;)</p>
|
||||
<Foo {...part}/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
```
|
||||
@ -1,28 +1,34 @@
|
||||
import React from "react";
|
||||
|
||||
export const Iframe = (props: { proportion:number; src:string }) => (
|
||||
<div
|
||||
style={{
|
||||
width: "100%",
|
||||
height: 0,
|
||||
paddingTop: (100 / props.proportion ) + "%",
|
||||
position: "relative",
|
||||
float:"left",
|
||||
}}
|
||||
>
|
||||
<iframe
|
||||
export const Iframe = (props: { proportion?: number; src: string }) => {
|
||||
let { proportion, src } = props;
|
||||
if (!proportion) {
|
||||
proportion = 4 / 3;
|
||||
}
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
display: "block",
|
||||
position: "absolute",
|
||||
top:0,
|
||||
left:0,
|
||||
height: 0,
|
||||
paddingTop: 100 / proportion + "%",
|
||||
position: "relative",
|
||||
float: "left",
|
||||
}}
|
||||
src={props.src}
|
||||
frameBorder="0"
|
||||
scrolling="no"
|
||||
allowFullScreen
|
||||
></iframe>
|
||||
</div>
|
||||
);
|
||||
>
|
||||
<iframe
|
||||
style={{
|
||||
width: "100%",
|
||||
height: "100%",
|
||||
display: "block",
|
||||
position: "absolute",
|
||||
top: 0,
|
||||
left: 0,
|
||||
}}
|
||||
src={src}
|
||||
frameBorder="0"
|
||||
scrolling="no"
|
||||
allowFullScreen
|
||||
></iframe>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
192
foomo/src/components/TypeScriptPlayground.tsx
Normal file
192
foomo/src/components/TypeScriptPlayground.tsx
Normal file
@ -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 (
|
||||
<div>
|
||||
<Highlight {...defaultProps} code={props.children} language="tsx">
|
||||
{({ className, style, tokens, getLineProps, getTokenProps }) => (
|
||||
<pre className={className} style={style}>
|
||||
{tokens.map((line, i) => (
|
||||
<div {...getLineProps({ line, key: i })}>
|
||||
{line.map((token, key) => (
|
||||
<span {...getTokenProps({ token, key })} />
|
||||
))}
|
||||
</div>
|
||||
))}
|
||||
</pre>
|
||||
)}
|
||||
</Highlight>
|
||||
<a href={url} className="button button--primary">
|
||||
open in playground on www.typescriptlang.org
|
||||
</a>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@ -2,6 +2,11 @@
|
||||
|
||||
A list of commercial and open source software we use, because it is awesome.
|
||||
|
||||
<div className="alert alert--danger" role="alert">
|
||||
Please note, when you are installing software, <strong>use a package manager</strong>
|
||||
</div>
|
||||
<br/>
|
||||
|
||||
## desktop software
|
||||
|
||||
### devtools
|
||||
|
||||
@ -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 (
|
||||
<header className={clsx("hero hero--primary", styles.heroBanner)}>
|
||||
<div className="container">
|
||||
<img
|
||||
style={{maxWidth: "200px", border: "1px white solid", borderRadius: "1rem"}}
|
||||
<img
|
||||
style={{
|
||||
maxWidth: "200px",
|
||||
border: "1px white solid",
|
||||
borderRadius: "1rem",
|
||||
}}
|
||||
src="https://avatars.githubusercontent.com/u/889755"
|
||||
/>
|
||||
<h1 className="hero__title">{siteConfig.title}</h1>
|
||||
@ -40,32 +43,32 @@ export default function Home(): JSX.Element {
|
||||
marginRight: "auto",
|
||||
}}
|
||||
>
|
||||
<br/>
|
||||
<br />
|
||||
<p>
|
||||
<b>foomo</b> is an open source project, that has been maintained by
|
||||
the <a href="https://www.bestbytes.com">bestbytes</a> team since 2011.
|
||||
It provides a wide range of tools and libraries, that help us to
|
||||
tackle challenging projects.
|
||||
</p>
|
||||
<h2>foomo can help, if you are</h2>
|
||||
<ul>
|
||||
<li>
|
||||
using <a href="https://www.golang.org">Go</a> to write services
|
||||
</li>
|
||||
<li>
|
||||
building frontends with{" "}
|
||||
<a href="https://www.typescriptlang.org/">TypeScript</a> and{" "}
|
||||
<a href="https://nextjs.org/">Next.js</a>
|
||||
</li>
|
||||
<li>
|
||||
running your software on <a href="https://kubernetes.io/">k8s</a>
|
||||
</li>
|
||||
<li>
|
||||
looking for a solution to deeply integrate your frontends with a
|
||||
headless cms
|
||||
</li>
|
||||
</ul>
|
||||
<sub>If more than two points apply, it will actually help a LOT</sub>
|
||||
<h2>foomo can help, if you are</h2>
|
||||
<ul>
|
||||
<li>
|
||||
using <a href="https://www.golang.org">Go</a> to write services
|
||||
</li>
|
||||
<li>
|
||||
building frontends with{" "}
|
||||
<a href="https://www.typescriptlang.org/">TypeScript</a> and{" "}
|
||||
<a href="https://nextjs.org/">Next.js</a>
|
||||
</li>
|
||||
<li>
|
||||
running your software on <a href="https://kubernetes.io/">k8s</a>
|
||||
</li>
|
||||
<li>
|
||||
looking for a solution to deeply integrate your frontends with a
|
||||
headless cms
|
||||
</li>
|
||||
</ul>
|
||||
<sub>If more than two points apply, it will actually help a LOT</sub>
|
||||
</div>
|
||||
<main>
|
||||
<HomepageFeatures />
|
||||
|
||||
Loading…
Reference in New Issue
Block a user