diff --git a/system/apps/blog-e2e/src/e2e/articles-filtering.cy.ts b/system/apps/blog-e2e/src/e2e/articles-filtering.cy.ts
index 990c816fe..a22bcce9d 100644
--- a/system/apps/blog-e2e/src/e2e/articles-filtering.cy.ts
+++ b/system/apps/blog-e2e/src/e2e/articles-filtering.cy.ts
@@ -7,6 +7,6 @@ describe('Articles filtering works when: ', () => {
it('not signed in user visits your articles page and session expiration section is displayed', () => {
Given('System mocked endpoint', 'getRecommendedArticles')
.And('System sets page as', '/en/articles')
- .Then('I not see text', 'Show your articles');
+ .Then('I not see text', 'Yours', 'All')
});
});
diff --git a/system/apps/blog-e2e/src/e2e/sign-in.cy.ts b/system/apps/blog-e2e/src/e2e/sign-in.cy.ts
index 091b2ef59..2740365f7 100644
--- a/system/apps/blog-e2e/src/e2e/sign-in.cy.ts
+++ b/system/apps/blog-e2e/src/e2e/sign-in.cy.ts
@@ -25,7 +25,7 @@ describe('Sign in works when: ', () => {
'Signed in'
)
.And('Im on page', '/en/articles')
- .When('I click checkbox', 'Show your articles')
+ .When('I click tab', 'Yours')
.Then('System recieved response from endpoint', 'getYourArticles')
.When('I go back')
.Then(
diff --git a/system/apps/blog/components/articles-grid/article-tile.tsx b/system/apps/blog/components/articles-grid/article-tile.tsx
index 1bd2122e2..1ac066030 100644
--- a/system/apps/blog/components/articles-grid/article-tile.tsx
+++ b/system/apps/blog/components/articles-grid/article-tile.tsx
@@ -26,12 +26,8 @@ const avatar_size = {
};
const Container = styled.div`
- background: 1px solid ${(props) => props.theme.box.outlined.bg};
- overflow: hidden;
-
.article-tile-flipped-container {
${column()}
- padding: ${tokens.spacing[200]};
height: 100%;
.detail {
diff --git a/system/apps/blog/components/articles-screen/articles-screen.tsx b/system/apps/blog/components/articles-screen/articles-screen.tsx
index deb7445a8..d2af96619 100644
--- a/system/apps/blog/components/articles-screen/articles-screen.tsx
+++ b/system/apps/blog/components/articles-screen/articles-screen.tsx
@@ -1,7 +1,6 @@
import {
Box,
Button,
- Checkbox,
Divider,
Field,
FiltersIcon,
@@ -9,7 +8,10 @@ import {
L_DOWN,
Loader,
M_DOWN,
+ M_UP,
Popover,
+ Tab,
+ Tabs,
VIEWPORT,
column,
tokens,
@@ -27,7 +29,7 @@ import { InfoSection } from '../info-section';
import { ScrollState, useScroll } from '@system/figa-hooks';
import { Lang } from '@system/blog-api-models';
import type { ArticlesStore } from '../../store-factories/articles';
-import { auth_store_selectors } from '../../store/auth';
+import { SignedInOnly } from '../../core';
const Placeholder = styled.div`
background: ${(props) => props.theme.box.filled.bg};
@@ -80,14 +82,14 @@ const Container = styled.div`
.articles-content {
${column()}
- & > .h6 {
- margin-bottom: ${tokens.spacing[250]};
+ & > .b1 {
+ margin: 0 0 ${tokens.spacing[150]} 0;
}
.articles-screen-tiles {
display: grid;
- grid-template-columns: 1fr 1fr 1fr;
- gap: ${tokens.spacing[250]};
+ grid-template-columns: 32.5% 32.5% 32.5%;
+ gap: ${tokens.spacing[300]} 2.5%;
& > * {
height: 400px;
@@ -97,21 +99,24 @@ const Container = styled.div`
@media ${L_DOWN} {
.articles-content .articles-screen-tiles {
- grid-template-columns: 1fr 1fr;
+ grid-template-columns: 49% 49%;
+ gap: ${tokens.spacing[300]} 2%;
}
}
@media (max-width: 940px) {
.articles-content .articles-screen-tiles {
- grid-template-columns: 1fr;
+ grid-template-columns: 100%;
+ gap: ${tokens.spacing[200]};
}
}
@media (max-width: 740px) {
- grid-template-columns: 1fr;
+ grid-template-columns: 100%;
.articles-content .articles-screen-tiles {
- grid-template-columns: 1fr 1fr;
+ grid-template-columns: 49% 49%;
+ gap: ${tokens.spacing[300]} 2%;
}
.articles-filters {
@@ -125,7 +130,16 @@ const Container = styled.div`
@media ${M_DOWN} {
.articles-content .articles-screen-tiles {
- grid-template-columns: 1fr;
+ grid-template-columns: 100%;
+ gap: ${tokens.spacing[300]};
+ }
+ }
+
+ .tabs {
+ margin: 0 0 ${tokens.spacing[200]} 0;
+
+ @media ${M_UP} {
+ max-width: 280px;
}
}
`;
@@ -141,8 +155,21 @@ const Filters = styled.div`
.divider div {
width: 100%;
+ height: ${tokens.spacing[12]};
background: ${(props) => props.theme.box.outlined.borderColor};
}
+
+ .articles-screen-filters-content {
+ padding: ${tokens.spacing[250]};
+
+ & > *:not(:last-child) {
+ margin-bottom: ${tokens.spacing[200]};
+ }
+
+ & > *:last-child {
+ margin-top: ${tokens.spacing[450]};
+ }
+ }
`;
const makeUrl = (lang: Lang, article: ArticlesStore.Article): string => {
@@ -194,7 +221,6 @@ const PopoverTrigger = ({
};
const ArticlesScreen = (props: ArticlesScreenProps) => {
- const authorized = auth_store_selectors.useIsAuthorized();
const { selectors, actions } = props;
const state = selectors.useState();
const lang = useLang();
@@ -214,6 +240,17 @@ const ArticlesScreen = (props: ArticlesScreenProps) => {
[state]
);
+ const filtersChanged = useMemo(() => {
+ if (state.is === 'idle') {
+ return false;
+ }
+
+ const { CurrentPage, yours, ...initialParams } = state.initialParams;
+ const { CurrentPage: cp, yours: y, ...params } = state.params;
+
+ return !isEqual(initialParams, params);
+ }, [state]);
+
const filters = (
@@ -229,31 +266,23 @@ const ArticlesScreen = (props: ArticlesScreenProps) => {
-
+
actions.change({ Search })}
/>
-
- actions.change({ Status })}
- />
-
- {authorized && (
-
- actions.change({ yours: !selectors.safeState().params.yours })
- }
- />
- )}
+
+
+
+ actions.change({ Status })}
+ />
+
+
+
{
Share
-
+
);
@@ -309,7 +338,23 @@ const ArticlesScreen = (props: ArticlesScreenProps) => {
return (
<>
- Results ({state.articles.length})
+
+
+ actions.change({ yours: false })}
+ >
+ All
+
+ actions.change({ yours: true })}
+ >
+ Yours
+
+
+
+ Results ({state.articles.length})
{state.articles.map((article) => (
{
>
);
- }, [state, lang, actions.reset]);
+ // eslint-disable-next-line react-hooks/exhaustive-deps
+ }, [state, lang]);
return (
-
+
Articles
{filters}
diff --git a/system/apps/blog/components/main-layout/main-layout.tsx b/system/apps/blog/components/main-layout/main-layout.tsx
index 1cb83296d..04a82f444 100644
--- a/system/apps/blog/components/main-layout/main-layout.tsx
+++ b/system/apps/blog/components/main-layout/main-layout.tsx
@@ -19,9 +19,6 @@ import {
ArticlesSearchIcon,
BottomNavItem,
PlusCircleIcon,
- useThemeProvider,
- SunIcon,
- HalfMoonIcon,
TopNavItem,
column,
} from '@system/figa-ui';
@@ -81,7 +78,6 @@ const LogoWrapper = styled.div`
const MainLayout = ({ children, sidebar, offPadding }: MainLayoutProps) => {
const lang = useLang();
- const theme = useThemeProvider();
const pathname = usePathname();
const [, { toTop }] = useScrollTo();
@@ -112,13 +108,6 @@ const MainLayout = ({ children, sidebar, offPadding }: MainLayoutProps) => {
Create
-
- theme.setTheme(theme.key === 'dark' ? 'light' : 'dark')
- }
- >
- Theme {theme.key === 'dark' ? : }
-
}
bottomNav={
@@ -144,13 +133,6 @@ const MainLayout = ({ children, sidebar, offPadding }: MainLayoutProps) => {
active={pathname === `/${lang}/articles-creator`}
/>
- : }
- text="Theme"
- onClick={() =>
- theme.setTheme(theme.key === 'dark' ? 'light' : 'dark')
- }
- />
>
}
sidebar={sidebar}
diff --git a/system/apps/blog/components/main-layout/user-section.tsx b/system/apps/blog/components/main-layout/user-section.tsx
index dbcd0d11c..d8a2a9960 100644
--- a/system/apps/blog/components/main-layout/user-section.tsx
+++ b/system/apps/blog/components/main-layout/user-section.tsx
@@ -1,4 +1,11 @@
-import { Box, TopNavItem } from '@system/figa-ui';
+import {
+ Box,
+ Button,
+ HalfMoonIcon,
+ SunIcon,
+ TopNavItem,
+ useThemeProvider,
+} from '@system/figa-ui';
import { Link } from '../link';
import { useLang } from '../../dk';
import { useAuthStore } from '../../store/auth';
@@ -9,22 +16,47 @@ const UserSection = () => {
const { is } = useAuthStore();
const pathname = usePathname();
const lang = useLang();
+ const theme = useThemeProvider();
if (is === 'idle') {
return (
-
+
Sign Up
Sign In
+
);
}
if (is === 'authorized') {
- return ;
+ return (
+
+
+
+
+ );
}
return (
-
+
Sign Up
@@ -35,6 +67,15 @@ const UserSection = () => {
Sign In
+
);
};
diff --git a/system/apps/blog/store-factories/articles/create-articles-store.ts b/system/apps/blog/store-factories/articles/create-articles-store.ts
index 6e8fe7a16..9b09d65aa 100644
--- a/system/apps/blog/store-factories/articles/create-articles-store.ts
+++ b/system/apps/blog/store-factories/articles/create-articles-store.ts
@@ -222,7 +222,16 @@ const createArticlesStore = () => {
initialParams: params,
});
},
- change: (params) => change.next(params),
+ change: (params) => {
+ const state = selectors.state();
+
+ if (state.is === 'changing_fail') {
+ actions.reset();
+ return;
+ }
+
+ change.next(params);
+ },
reset: () => {
const state = selectors.state();
diff --git a/system/apps/blog/store/auth/actions.ts b/system/apps/blog/store/auth/actions.ts
index 820e0b42c..4fa6890d5 100644
--- a/system/apps/blog/store/auth/actions.ts
+++ b/system/apps/blog/store/auth/actions.ts
@@ -1,6 +1,8 @@
import { type AuthStore } from './defs';
import { useAuthStore } from './store';
import { authStorage } from './core';
+import { articles_store_actions } from '../articles';
+import { sign_in_store_actions } from '../sign-in';
const { setState } = useAuthStore;
@@ -26,6 +28,8 @@ const auth_store_actions: AuthStore.Actions = {
unauthorize: () => {
authStorage.set('user', null);
useAuthStore.setState({ is: 'unauthorized', user: null });
+ articles_store_actions.reset();
+ sign_in_store_actions.reset();
},
};
diff --git a/system/apps/blog/store/sign-out/actions.ts b/system/apps/blog/store/sign-out/actions.ts
index 3761ddfc4..238080b8c 100644
--- a/system/apps/blog/store/sign-out/actions.ts
+++ b/system/apps/blog/store/sign-out/actions.ts
@@ -2,7 +2,6 @@ import { getError, signOut } from '@system/blog-api';
import { type SignOutStore } from './defs';
import { useSignOutStore } from './store';
import { auth_store_actions } from '../auth';
-import { sign_in_store_actions } from '../sign-in';
const { setState } = useSignOutStore;
@@ -18,7 +17,6 @@ const sign_out_store_actions: SignOutStore.Actions = {
await signOut();
auth_store_actions.unauthorize();
- sign_in_store_actions.reset();
set({ is: 'ok' });
} catch (error: unknown) {
diff --git a/system/apps/blog/store/sign-out/store.test.ts b/system/apps/blog/store/sign-out/store.test.ts
index 00be5c365..b41375711 100644
--- a/system/apps/blog/store/sign-out/store.test.ts
+++ b/system/apps/blog/store/sign-out/store.test.ts
@@ -4,13 +4,11 @@ import { signOut, getError } from '@system/blog-api';
import { storeFixture } from '../test-utils';
import { mockResponseError } from '@system/blog-api-mocks';
import { auth_store_actions } from '../auth';
-import { sign_in_store_actions } from '../sign-in';
import type { SignOutStore } from './defs';
import { sign_out_store_actions } from './actions';
jest.mock('@system/blog-api');
jest.mock('../auth');
-jest.mock('../sign-in');
describe('Allows to sign out user when: ', () => {
afterEach(() => {
@@ -22,7 +20,6 @@ describe('Allows to sign out user when: ', () => {
(signOut as jest.Mock).mockImplementation(() => Promise.resolve());
(auth_store_actions.unauthorize as jest.Mock).mockImplementation(jest.fn());
- (sign_in_store_actions.reset as jest.Mock).mockImplementation(jest.fn());
expect(result.current.is).toBe('idle');
@@ -37,7 +34,6 @@ describe('Allows to sign out user when: ', () => {
});
expect(auth_store_actions.unauthorize).toHaveBeenCalledTimes(1);
- expect(sign_in_store_actions.reset).toHaveBeenCalledTimes(1);
expect(result.current.is).toBe('ok');
restore();
@@ -64,7 +60,6 @@ describe('Allows to sign out user when: ', () => {
});
expect(auth_store_actions.unauthorize).not.toHaveBeenCalled();
- expect(sign_in_store_actions.reset).not.toHaveBeenCalled();
expect(result.current.is).toBe('fail');
expect((result.current as SignOutStore.Fail).error).toEqual(
mockResponseError()
diff --git a/system/libs/figa-ui/src/lib/theme-provider/light-theme.ts b/system/libs/figa-ui/src/lib/theme-provider/light-theme.ts
index 03c022f1d..d2899110d 100644
--- a/system/libs/figa-ui/src/lib/theme-provider/light-theme.ts
+++ b/system/libs/figa-ui/src/lib/theme-provider/light-theme.ts
@@ -20,11 +20,11 @@ const light: Theme = {
},
},
checkbox: {
- borderColor: tokens.common.white,
+ borderColor: tokens.common.black,
checked: {
bg: tokens.primary[50],
borderColor: tokens.primary[50],
- color: tokens.common.white,
+ color: tokens.common.black,
},
},
radio: {