Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions system/apps/blog/components/main-layout/main-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
tokens,
row,
M_DOWN,
AlertsProvider,
} from '@system/figa-ui';
import type { MainLayoutProps } from './defs';
import { Link } from '../link';
Expand Down Expand Up @@ -75,7 +74,7 @@ const MainLayout = ({
));

return (
<AlertsProvider>
<>
<Layout
offPadding={offPadding}
header={
Expand Down Expand Up @@ -167,7 +166,7 @@ const MainLayout = ({
{children}
</Layout>
<LeftBar />
</AlertsProvider>
</>
);
};

Expand Down
8 changes: 5 additions & 3 deletions system/apps/blog/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import './index.css';
import { ThemeProvider } from '@system/figa-ui';
import { AppProps } from 'next/app';
import { AlertsProvider, ThemeProvider } from '@system/figa-ui';
import type { AppProps } from 'next/app';
import Head from 'next/head';
import { useAuth } from '../core';
import { useEffect } from 'react';
Expand Down Expand Up @@ -30,7 +30,9 @@ const App = ({ Component, pageProps }: AppProps) => {
<meta title="App" />
</Head>
<ThemeProvider>
<Component {...pageProps} />
<AlertsProvider>
<Component {...pageProps} />
</AlertsProvider>
</ThemeProvider>
</>
);
Expand Down
23 changes: 10 additions & 13 deletions system/apps/blog/store/articles-creator/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,31 @@ import {
sendArticleForApproval,
updateArticle,
} from '@system/blog-api';
import { Url } from '@system/blog-api-models';
import { articles_creator_store_states } from './states';

const { getState: get, setState: set } = useArticlesCreatorStore;

const articles_creator_store_actions = {
setView: (view: ArticlesCreatorStore.View): void => {
const articles_creator_store_actions: ArticlesCreatorStore.Actions = {
reset: () => {
set(articles_creator_store_states.idle());
},
setView: (view) => {
set({ view });
},
setForm: (values: Partial<ArticlesCreatorStore.FormData> = {}): void => {
setForm: (values = {}) => {
set({
form: creatorForm.init({
...get().form.values,
...values,
}),
});
},
change: <
K extends keyof ArticlesCreatorStore.FormData,
V extends ArticlesCreatorStore.FormData[K]
>(
key: K,
value: V
): void => {
change: (key, value) => {
set({
form: creatorForm.set(get().form)({ [key]: value }),
});
},
confirm: async (url?: Url): Promise<void> => {
confirm: async (url) => {
const state = get();

set({
Expand Down Expand Up @@ -66,7 +63,7 @@ const articles_creator_store_actions = {
await sendArticleForApproval({ id: data.id });
}

set({ is: 'ok' });
set({ is: 'ok', data });
} catch (error: unknown) {
set({ is: 'fail', error: getError(error) });
}
Expand Down
24 changes: 23 additions & 1 deletion system/apps/blog/store/articles-creator/defs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@ import type {
ArticleTag,
ArticleTags,
CreateArticlePayload,
Id,
ResponseError,
Url,
} from '@system/blog-api-models';
import type { FormState } from '@system/utils';

Expand All @@ -23,7 +25,12 @@ namespace ArticlesCreatorStore {
export type View = 'initial' | 'creator' | 'confirm';
export type Idle = { is: 'idle'; form: FormDataState; view: View };
export type Busy = { is: 'busy'; form: FormDataState; view: View };
export type Ok = { is: 'ok'; form: FormDataState; view: View };
export type Ok = {
is: 'ok';
form: FormDataState;
view: View;
data: { id: Id; url: Url };
};
export type Fail = {
is: 'fail';
form: FormDataState;
Expand All @@ -32,6 +39,21 @@ namespace ArticlesCreatorStore {
};

export type State = Idle | Busy | Ok | Fail;

export interface Actions {
reset(): void;
setView(view: View): void;
setForm(values?: Partial<FormData>): void;
change<K extends keyof FormData, V extends FormData[K]>(
key: K,
value: V
): void;
confirm(url?: Url): Promise<void>;
}

export interface States {
idle(): Idle;
}
}

export type { ArticlesCreatorStore };
1 change: 1 addition & 0 deletions system/apps/blog/store/articles-creator/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from './store';
export * from './defs';
export * from './actions';
export * from './states'
23 changes: 23 additions & 0 deletions system/apps/blog/store/articles-creator/states.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import type { ArticlesCreatorStore } from './defs';
import { creatorForm } from './form';

const articles_creator_store_states: ArticlesCreatorStore.States = {
idle: () => ({
is: 'idle',
view: 'initial',
form: creatorForm.init({
title: '',
description: '',
tags: [],
thumbnail: {
file: null,
preview: [],
},
content: '',
lang: 'en',
sendToReview: false,
}),
}),
};

export { articles_creator_store_states };
21 changes: 4 additions & 17 deletions system/apps/blog/store/articles-creator/store.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,9 @@
import { create } from 'zustand';
import type { ArticlesCreatorStore } from './defs';
import { creatorForm } from './form';
import { articles_creator_store_states } from './states';

const useArticlesCreatorStore = create<ArticlesCreatorStore.State>(() => ({
is: 'idle',
view: 'initial',
form: creatorForm.init({
title: '',
description: '',
tags: [],
thumbnail: {
file: null,
preview: [],
},
content: '',
lang: 'en',
sendToReview: false,
}),
}));
const useArticlesCreatorStore = create<ArticlesCreatorStore.State>(() =>
articles_creator_store_states.idle()
);

export { useArticlesCreatorStore };
18 changes: 14 additions & 4 deletions system/apps/blog/views/articles-creator/articles-creator.view.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,24 @@ import { InitialScreen } from './initial-screen';
import { EditorScreen } from './editor-screen';
import { useArticlesCreatorStore } from '../../store/articles-creator';
import { ConfirmScreen } from './confirm-screen';

// @TODO: Backend allows to set thumbnail to null.
import { MainLayout } from '../../components';

const ArticlesCreatorView = () => {
const articleCreatorState = useArticlesCreatorStore();

if (articleCreatorState.view === 'initial') return <InitialScreen />;
if (articleCreatorState.view === 'confirm') return <ConfirmScreen />;
if (articleCreatorState.view === 'initial')
return (
<MainLayout>
<InitialScreen />
</MainLayout>
);

if (articleCreatorState.view === 'confirm')
return (
<MainLayout>
<ConfirmScreen />
</MainLayout>
);

return <EditorScreen />;
};
Expand Down
40 changes: 27 additions & 13 deletions system/apps/blog/views/articles-creator/confirm-screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,28 @@ import {
List,
ListItem,
Loader,
useAlert,
} from '@system/figa-ui';
import {
articles_creator_store_actions,
useArticlesCreatorStore,
} from '../../store/articles-creator';
import { MainLayout } from '../../components';
import { useAuthStore } from '../../store/auth';
import { useMoveToRedirect } from '../../dk';
import { useLang, useMoveToRedirect } from '../../dk';
import { useArticleStore } from '../../store/article';
import { useToggle } from '@system/figa-hooks';
import { useEffect } from 'react';
import { useRouter } from 'next/router';

const ConfirmScreen = () => {
const articleCreatorState = useArticlesCreatorStore();
const articleStore = useArticleStore();
const authStore = useAuthStore();
const { go } = useMoveToRedirect();
const confirmation = useToggle();
const router = useRouter();
const lang = useLang();
const alert = useAlert();

const handleClose = (): void => {
articles_creator_store_actions.setView('creator');
Expand All @@ -46,11 +51,28 @@ const ConfirmScreen = () => {
go('/sign-in', '/articles-creator');
};

useEffect(() => {
if (articleCreatorState.is === 'ok') {
alert.show({
children: `Article has been ${
articleStore.is === 'idle' ? 'created' : 'edited'
} ❤!`,
type: 'ok',
});

router.push(
`/${lang}/articles/preview?id=${articleCreatorState.data.id}&url=${articleCreatorState.data.url}`
);

articles_creator_store_actions.reset();
}
}, [articleCreatorState, lang, router, articleStore, alert]);

const wantToChangePublishedArticle =
articleStore.is === 'ok' && articleStore.article.status === 'Accepted';

return (
<MainLayout>
<>
{articleCreatorState.is === 'busy' ? (
<Box margin="auto">
<Box margin="auto">
Expand All @@ -68,9 +90,7 @@ const ConfirmScreen = () => {
150,
400,
250,
articleCreatorState.is === 'fail' || articleCreatorState.is === 'ok'
? 250
: 0,
articleCreatorState.is === 'fail' ? 250 : 0,
]}
>
{wantToChangePublishedArticle && (
Expand Down Expand Up @@ -120,18 +140,12 @@ const ConfirmScreen = () => {
{confirmation.opened ? 'Sure?' : 'Submit'}
</Button>
</Box>
{articleCreatorState.is === 'ok' && (
<Alert type="ok">
Article has been{' '}
{articleStore.is === 'idle' ? 'created' : 'edited'} ❤!
</Alert>
)}
{articleCreatorState.is === 'fail' && (
<Alert type="error">{articleCreatorState.error.message}</Alert>
)}
</Box>
)}
</MainLayout>
</>
);
};

Expand Down
5 changes: 2 additions & 3 deletions system/apps/blog/views/articles-creator/initial-screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
ListItem,
Loader,
} from '@system/figa-ui';
import { MainLayout } from '../../components';
import { article_store_actions, useArticleStore } from '../../store/article';
import { useRouter } from 'next/router';
import { getLang } from '../../dk';
Expand Down Expand Up @@ -101,7 +100,7 @@ const InitialScreen = () => {
const { is } = articleStore;

return (
<MainLayout>
<>
{is === 'busy' ? (
<Box margin="auto">
<Box margin="auto">
Expand Down Expand Up @@ -136,7 +135,7 @@ const InitialScreen = () => {
)}
</Box>
)}
</MainLayout>
</>
);
};

Expand Down