Skip to content
2 changes: 1 addition & 1 deletion system/apps/blog-e2e/src/e2e/articles-filtering.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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')
});
});
2 changes: 1 addition & 1 deletion system/apps/blog-e2e/src/e2e/sign-in.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
4 changes: 0 additions & 4 deletions system/apps/blog/components/articles-grid/article-tile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
116 changes: 81 additions & 35 deletions system/apps/blog/components/articles-screen/articles-screen.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import {
Box,
Button,
Checkbox,
Divider,
Field,
FiltersIcon,
Font,
L_DOWN,
Loader,
M_DOWN,
M_UP,
Popover,
Tab,
Tabs,
VIEWPORT,
column,
tokens,
Expand All @@ -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};
Expand Down Expand Up @@ -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;
Expand All @@ -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 {
Expand All @@ -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;
}
}
`;
Expand All @@ -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 => {
Expand Down Expand Up @@ -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();
Expand All @@ -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 = (
<Filters className="articles-filters">
<Box padding={[250, 200, 250, 300]} orientation="row" between>
Expand All @@ -229,31 +266,23 @@ const ArticlesScreen = (props: ArticlesScreenProps) => {
</Button>
</Box>
<Divider />
<Box
padding={[250, 250, 250, 250]}
spacing={[250, 250, authorized ? 250 : 0, 600]}
>
<div className="articles-screen-filters-content">
<Field label="Search phrase">
<ArticlesSearchInput
search={state.is === 'idle' ? '' : state.params.Search}
onChange={(Search) => actions.change({ Search })}
/>
</Field>
<Field label="Status">
<ArticlesStatusSelect
status={state.is === 'idle' ? 'Draft' : state.params.Status}
onChange={(Status) => actions.change({ Status })}
/>
</Field>
{authorized && (
<Checkbox
label="Show your articles"
checked={state.is === 'idle' ? false : state.params.yours}
onChange={() =>
actions.change({ yours: !selectors.safeState().params.yours })
}
/>
)}

<SignedInOnly>
<Field label="Status">
<ArticlesStatusSelect
status={state.is === 'idle' ? 'Draft' : state.params.Status}
onChange={(Status) => actions.change({ Status })}
/>
</Field>
</SignedInOnly>

<Field label="Tags">
<ArticlesTagsSelect
tags={state.is === 'idle' ? [] : state.params.Tags}
Expand All @@ -269,7 +298,7 @@ const ArticlesScreen = (props: ArticlesScreenProps) => {
Share
</Button>
</Box>
</Box>
</div>
</Filters>
);

Expand Down Expand Up @@ -309,7 +338,23 @@ const ArticlesScreen = (props: ArticlesScreenProps) => {

return (
<>
<Font variant="h6">Results ({state.articles.length})</Font>
<SignedInOnly>
<Tabs>
<Tab
active={!state.params.yours}
onClick={() => actions.change({ yours: false })}
>
All
</Tab>
<Tab
active={state.params.yours}
onClick={() => actions.change({ yours: true })}
>
Yours
</Tab>
</Tabs>
</SignedInOnly>
<Font variant="b1">Results ({state.articles.length})</Font>
<div className="articles-screen-tiles">
{state.articles.map((article) => (
<ArticlesGrid.Tile
Expand All @@ -330,12 +375,13 @@ const ArticlesScreen = (props: ArticlesScreenProps) => {
</div>
</>
);
}, [state, lang, actions.reset]);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [state, lang]);

return (
<Wrapper>
<Popover closeMode="backdrop">
<PopoverTrigger active={!resetIsDisabled}>
<PopoverTrigger active={filtersChanged}>
<Font variant="h5">Articles</Font>
</PopoverTrigger>
<PopoverContent>{filters}</PopoverContent>
Expand Down
18 changes: 0 additions & 18 deletions system/apps/blog/components/main-layout/main-layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,6 @@ import {
ArticlesSearchIcon,
BottomNavItem,
PlusCircleIcon,
useThemeProvider,
SunIcon,
HalfMoonIcon,
TopNavItem,
column,
} from '@system/figa-ui';
Expand Down Expand Up @@ -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();
Expand Down Expand Up @@ -112,13 +108,6 @@ const MainLayout = ({ children, sidebar, offPadding }: MainLayoutProps) => {
Create <PlusCircleIcon />
</TopNavItem>
</Link>
<TopNavItem
onClick={() =>
theme.setTheme(theme.key === 'dark' ? 'light' : 'dark')
}
>
Theme {theme.key === 'dark' ? <SunIcon /> : <HalfMoonIcon />}
</TopNavItem>
</Nav>
}
bottomNav={
Expand All @@ -144,13 +133,6 @@ const MainLayout = ({ children, sidebar, offPadding }: MainLayoutProps) => {
active={pathname === `/${lang}/articles-creator`}
/>
</NextLink>
<BottomNavItem
icon={theme.key === 'dark' ? <SunIcon /> : <HalfMoonIcon />}
text="Theme"
onClick={() =>
theme.setTheme(theme.key === 'dark' ? 'light' : 'dark')
}
/>
</>
}
sidebar={sidebar}
Expand Down
49 changes: 45 additions & 4 deletions system/apps/blog/components/main-layout/user-section.tsx
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -9,22 +16,47 @@ const UserSection = () => {
const { is } = useAuthStore();
const pathname = usePathname();
const lang = useLang();
const theme = useThemeProvider();

if (is === 'idle') {
return (
<Box orientation="row" spacing={[150]}>
<Box orientation="row" spacing={[50, 50]}>
<TopNavItem disabled>Sign Up</TopNavItem>
<TopNavItem disabled>Sign In</TopNavItem>
<Button
disabled
variant="ghost"
shape="rounded"
motive="tertiary"
size={2}
>
<SunIcon />
</Button>
</Box>
);
}

if (is === 'authorized') {
return <UserPopover />;
return (
<Box orientation="row" spacing={[150]}>
<Button
variant="ghost"
size={2}
shape="rounded"
motive="tertiary"
onClick={() =>
theme.setTheme(theme.key === 'dark' ? 'light' : 'dark')
}
>
{theme.key === 'dark' ? <SunIcon /> : <HalfMoonIcon />}
</Button>
<UserPopover />
</Box>
);
}

return (
<Box orientation="row" spacing={[150]}>
<Box orientation="row" spacing={[50, 50]}>
<Link title="Sign Up" href={`/${lang}/register/`}>
<TopNavItem active={pathname === `/${lang}/register`}>
Sign Up
Expand All @@ -35,6 +67,15 @@ const UserSection = () => {
Sign In
</TopNavItem>
</Link>
<Button
variant="ghost"
size={2}
shape="rounded"
motive="tertiary"
onClick={() => theme.setTheme(theme.key === 'dark' ? 'light' : 'dark')}
>
{theme.key === 'dark' ? <SunIcon /> : <HalfMoonIcon />}
</Button>
</Box>
);
};
Expand Down
Loading