summaryrefslogtreecommitdiff
path: root/packages/create-astro/src/components/App.tsx
diff options
context:
space:
mode:
authorGravatar Nate Moore <natemoo-re@users.noreply.github.com> 2021-05-03 12:15:13 -0500
committerGravatar GitHub <noreply@github.com> 2021-05-03 12:15:13 -0500
commited631329e731d31e384dacc1ec399ba60b7c906b (patch)
tree0c998bb642c1feab773cb0e751dbb0ece1e59d64 /packages/create-astro/src/components/App.tsx
parent467820996f71b0c78f2000294cb6f3c0a8f3aca4 (diff)
downloadastro-ed631329e731d31e384dacc1ec399ba60b7c906b.tar.gz
astro-ed631329e731d31e384dacc1ec399ba60b7c906b.tar.zst
astro-ed631329e731d31e384dacc1ec399ba60b7c906b.zip
`create-astro` UI (#164)
* refactor: improve create-astro layout, build script * feat(create-astro): v0.1.0 * docs(create-astro): add README * feat(create-astro): add meta files to starter templates
Diffstat (limited to 'packages/create-astro/src/components/App.tsx')
-rw-r--r--packages/create-astro/src/components/App.tsx93
1 files changed, 93 insertions, 0 deletions
diff --git a/packages/create-astro/src/components/App.tsx b/packages/create-astro/src/components/App.tsx
new file mode 100644
index 000000000..fd9192bb6
--- /dev/null
+++ b/packages/create-astro/src/components/App.tsx
@@ -0,0 +1,93 @@
+import React, {FC, useEffect} from 'react';
+import { prepareTemplate, isEmpty, emptyDir } from '../utils';
+import Header from './Header';
+import Install from './Install';
+import ProjectName from './ProjectName';
+import Template from './Template';
+import Confirm from './Confirm';
+import Finalize from './Finalize';
+
+interface Context {
+ use: 'npm'|'yarn';
+ run: boolean;
+ projectExists?: boolean;
+ force?: boolean;
+ projectName?: string;
+ template?: string;
+ templates: string[];
+ ready?: boolean;
+}
+
+const getStep = ({ projectName, projectExists: exists, template, force, ready }: Context) => {
+ switch (true) {
+ case !projectName: return {
+ key: 'projectName',
+ Component: ProjectName
+ };
+ case projectName && exists === true && typeof force === 'undefined': return {
+ key: 'force',
+ Component: Confirm
+ }
+ case (exists === false || force) && !template: return {
+ key: 'template',
+ Component: Template
+ };
+ case !ready: return {
+ key: 'install',
+ Component: Install
+ };
+ default: return {
+ key: 'final',
+ Component: Finalize
+ }
+ }
+}
+
+const App: FC<{ context: Context }> = ({ context }) => {
+ const [state, setState] = React.useState(context);
+ const step = React.useRef(getStep(context));
+ const onSubmit = (value: string|boolean) => {
+ const { key } = step.current;
+ const newState = { ...state, [key]: value };
+ step.current = getStep(newState)
+ setState(newState)
+ }
+
+ useEffect(() => {
+ let isSubscribed = true
+ if (state.projectName && typeof state.projectExists === 'undefined') {
+ const newState = { ...state, projectExists: !isEmpty(state.projectName) };
+ step.current = getStep(newState)
+ if (isSubscribed) {
+ setState(newState);
+ }
+ }
+
+ if (state.projectName && (state.projectExists === false || state.force) && state.template) {
+ if (state.force) emptyDir(state.projectName);
+ prepareTemplate(context.use, state.template, state.projectName).then(() => {
+ if (isSubscribed) {
+ setState(v => {
+ const newState = {...v, ready: true };
+ step.current = getStep(newState);
+ return newState;
+ });
+ }
+ });
+ }
+
+ return () => {
+ isSubscribed = false;
+ }
+ }, [state]);
+ const { Component } = step.current;
+
+ return (
+ <>
+ <Header context={state}/>
+ <Component context={state} onSubmit={onSubmit} />
+ </>
+ )
+};
+
+export default App;