diff --git a/system/apps/blog/components/main-layout/main-layout.tsx b/system/apps/blog/components/main-layout/main-layout.tsx
index eb5815fc6..1697379d3 100644
--- a/system/apps/blog/components/main-layout/main-layout.tsx
+++ b/system/apps/blog/components/main-layout/main-layout.tsx
@@ -15,7 +15,6 @@ import {
tokens,
row,
M_DOWN,
- AlertsProvider,
} from '@system/figa-ui';
import type { MainLayoutProps } from './defs';
import { Link } from '../link';
@@ -75,7 +74,7 @@ const MainLayout = ({
));
return (
-
+ <>
-
+ >
);
};
diff --git a/system/apps/blog/pages/_app.tsx b/system/apps/blog/pages/_app.tsx
index 38d7b6cd1..a2bfd3e59 100644
--- a/system/apps/blog/pages/_app.tsx
+++ b/system/apps/blog/pages/_app.tsx
@@ -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';
@@ -30,7 +30,9 @@ const App = ({ Component, pageProps }: AppProps) => {
-
+
+
+
>
);
diff --git a/system/apps/blog/store/articles-creator/actions.ts b/system/apps/blog/store/articles-creator/actions.ts
index b59c76e92..e7d4e7ca7 100644
--- a/system/apps/blog/store/articles-creator/actions.ts
+++ b/system/apps/blog/store/articles-creator/actions.ts
@@ -7,15 +7,18 @@ 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 = {}): void => {
+ setForm: (values = {}) => {
set({
form: creatorForm.init({
...get().form.values,
@@ -23,18 +26,12 @@ const articles_creator_store_actions = {
}),
});
},
- 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 => {
+ confirm: async (url) => {
const state = get();
set({
@@ -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) });
}
diff --git a/system/apps/blog/store/articles-creator/defs.ts b/system/apps/blog/store/articles-creator/defs.ts
index 6587cded7..7a3925896 100644
--- a/system/apps/blog/store/articles-creator/defs.ts
+++ b/system/apps/blog/store/articles-creator/defs.ts
@@ -3,7 +3,9 @@ import type {
ArticleTag,
ArticleTags,
CreateArticlePayload,
+ Id,
ResponseError,
+ Url,
} from '@system/blog-api-models';
import type { FormState } from '@system/utils';
@@ -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;
@@ -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): void;
+ change(
+ key: K,
+ value: V
+ ): void;
+ confirm(url?: Url): Promise;
+ }
+
+ export interface States {
+ idle(): Idle;
+ }
}
export type { ArticlesCreatorStore };
diff --git a/system/apps/blog/store/articles-creator/index.ts b/system/apps/blog/store/articles-creator/index.ts
index afdbe9756..7e0191f4d 100644
--- a/system/apps/blog/store/articles-creator/index.ts
+++ b/system/apps/blog/store/articles-creator/index.ts
@@ -1,3 +1,4 @@
export * from './store';
export * from './defs';
export * from './actions';
+export * from './states'
\ No newline at end of file
diff --git a/system/apps/blog/store/articles-creator/states.ts b/system/apps/blog/store/articles-creator/states.ts
new file mode 100644
index 000000000..0ec4166c0
--- /dev/null
+++ b/system/apps/blog/store/articles-creator/states.ts
@@ -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 };
diff --git a/system/apps/blog/store/articles-creator/store.ts b/system/apps/blog/store/articles-creator/store.ts
index 2274ae009..ccfeb738d 100644
--- a/system/apps/blog/store/articles-creator/store.ts
+++ b/system/apps/blog/store/articles-creator/store.ts
@@ -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(() => ({
- is: 'idle',
- view: 'initial',
- form: creatorForm.init({
- title: '',
- description: '',
- tags: [],
- thumbnail: {
- file: null,
- preview: [],
- },
- content: '',
- lang: 'en',
- sendToReview: false,
- }),
-}));
+const useArticlesCreatorStore = create(() =>
+ articles_creator_store_states.idle()
+);
export { useArticlesCreatorStore };
diff --git a/system/apps/blog/views/articles-creator/articles-creator.view.tsx b/system/apps/blog/views/articles-creator/articles-creator.view.tsx
index 25d078572..5e7927d12 100644
--- a/system/apps/blog/views/articles-creator/articles-creator.view.tsx
+++ b/system/apps/blog/views/articles-creator/articles-creator.view.tsx
@@ -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 ;
- if (articleCreatorState.view === 'confirm') return ;
+ if (articleCreatorState.view === 'initial')
+ return (
+
+
+
+ );
+
+ if (articleCreatorState.view === 'confirm')
+ return (
+
+
+
+ );
return ;
};
diff --git a/system/apps/blog/views/articles-creator/confirm-screen.tsx b/system/apps/blog/views/articles-creator/confirm-screen.tsx
index 49079d9e2..d36140f84 100644
--- a/system/apps/blog/views/articles-creator/confirm-screen.tsx
+++ b/system/apps/blog/views/articles-creator/confirm-screen.tsx
@@ -7,16 +7,18 @@ 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();
@@ -24,6 +26,9 @@ const ConfirmScreen = () => {
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');
@@ -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 (
-
+ <>
{articleCreatorState.is === 'busy' ? (
@@ -68,9 +90,7 @@ const ConfirmScreen = () => {
150,
400,
250,
- articleCreatorState.is === 'fail' || articleCreatorState.is === 'ok'
- ? 250
- : 0,
+ articleCreatorState.is === 'fail' ? 250 : 0,
]}
>
{wantToChangePublishedArticle && (
@@ -120,18 +140,12 @@ const ConfirmScreen = () => {
{confirmation.opened ? 'Sure?' : 'Submit'}
- {articleCreatorState.is === 'ok' && (
-
- Article has been{' '}
- {articleStore.is === 'idle' ? 'created' : 'edited'} ❤!
-
- )}
{articleCreatorState.is === 'fail' && (
{articleCreatorState.error.message}
)}
)}
-
+ >
);
};
diff --git a/system/apps/blog/views/articles-creator/initial-screen.tsx b/system/apps/blog/views/articles-creator/initial-screen.tsx
index 2dc2557e7..67c7553c3 100644
--- a/system/apps/blog/views/articles-creator/initial-screen.tsx
+++ b/system/apps/blog/views/articles-creator/initial-screen.tsx
@@ -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';
@@ -101,7 +100,7 @@ const InitialScreen = () => {
const { is } = articleStore;
return (
-
+ <>
{is === 'busy' ? (
@@ -136,7 +135,7 @@ const InitialScreen = () => {
)}
)}
-
+ >
);
};