mirror of
https://github.com/muerwre/vault-frontend.git
synced 2025-06-21 17:18:28 +07:00
NodeLayout
This commit is contained in:
parent
684a4f4474
commit
b154277de8
23 changed files with 332 additions and 65 deletions
|
@ -1,10 +1,11 @@
|
|||
import React, { FC, useState, useCallback } from 'react';
|
||||
import { NavLink } from 'react-router-dom';
|
||||
import { INode } from '~/redux/types';
|
||||
import * as styles from './styles.scss';
|
||||
import { URLS } from '~/constants/urls';
|
||||
import { getImageSize } from '~/utils/dom';
|
||||
import classNames = require('classnames');
|
||||
import { URLS } from '~/constants/urls';
|
||||
|
||||
import * as styles from './styles.scss';
|
||||
|
||||
interface IProps {
|
||||
node: INode;
|
||||
|
@ -13,20 +14,23 @@ interface IProps {
|
|||
// title?: string;
|
||||
// is_hero?: boolean;
|
||||
// is_stamp?: boolean;
|
||||
onSelect: (id: INode['id']) => void;
|
||||
is_text?: boolean;
|
||||
}
|
||||
|
||||
const Cell: FC<IProps> = ({ node: { id, title, brief }, is_text = false }) => {
|
||||
const Cell: FC<IProps> = ({ node: { id, title, brief }, onSelect, is_text = false }) => {
|
||||
const [is_loaded, setIsLoaded] = useState(false);
|
||||
|
||||
const onImageLoad = useCallback(() => {
|
||||
setIsLoaded(true);
|
||||
}, [setIsLoaded]);
|
||||
|
||||
const onClick = useCallback(() => onSelect(id), [onSelect, id]);
|
||||
|
||||
return (
|
||||
<NavLink
|
||||
to={URLS.NODE_URL(id)}
|
||||
<div
|
||||
className={classNames(styles.cell, 'vert-1', 'hor-1', { is_text: false })}
|
||||
onClick={onClick}
|
||||
>
|
||||
<div className={styles.face}>{title && <div className={styles.title}>{title}</div>}</div>
|
||||
|
||||
|
@ -41,7 +45,7 @@ const Cell: FC<IProps> = ({ node: { id, title, brief }, is_text = false }) => {
|
|||
<img src={getImageSize(brief.thumbnail, 'medium')} onLoad={onImageLoad} alt="" />
|
||||
</div>
|
||||
)}
|
||||
</NavLink>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -3,17 +3,20 @@ import { Cell } from '~/components/flow/Cell';
|
|||
|
||||
import * as styles from './styles.scss';
|
||||
import { IFlowState } from '~/redux/flow/reducer';
|
||||
import { INode } from '~/redux/types';
|
||||
|
||||
type IProps = Partial<IFlowState> & {};
|
||||
type IProps = Partial<IFlowState> & {
|
||||
onSelect: (id: INode['id']) => void;
|
||||
};
|
||||
|
||||
export const FlowGrid: FC<IProps> = ({ nodes }) => (
|
||||
export const FlowGrid: FC<IProps> = ({ nodes, onSelect }) => (
|
||||
<div>
|
||||
<div className={styles.grid_test}>
|
||||
<div className={styles.hero}>HERO</div>
|
||||
<div className={styles.stamp}>STAMP</div>
|
||||
|
||||
{nodes.map(node => (
|
||||
<Cell key={node.id} node={node} />
|
||||
<Cell key={node.id} node={node} onSelect={onSelect} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
import React, { FC } from 'react';
|
||||
import * as styles from './styles.scss';
|
||||
import { Icon } from '../Icon';
|
||||
import { describeArc } from '~/utils/dom';
|
||||
|
||||
interface IProps {
|
||||
size?: number;
|
||||
|
@ -7,31 +9,9 @@ interface IProps {
|
|||
|
||||
export const LoaderCircle: FC<IProps> = ({ size = 24 }) => (
|
||||
<div className={styles.wrap}>
|
||||
<svg width={size} height={size} viewBox="0 0 24 24">
|
||||
<g strokeWidth={0.5}>
|
||||
{
|
||||
[...new Array(8)].map((el, i) => (
|
||||
<path
|
||||
d="M11,2 L11,6 C11,6.55228475 11.4477153,7 12,7 C12.5522847,7 13,6.55228475 13,6 L13,2 C13,1.44771525 12.5522847,1 12,1 C11.4477153,1 11,1.44771525 11,2 Z"
|
||||
opacity={0.125 * (8 - i)}
|
||||
transform={`rotate(${Math.floor(45 * i)} 12 12)`}
|
||||
// style={{
|
||||
// animationDelay: `${-100 * (8 - i)}ms`,
|
||||
// }}
|
||||
key={i}
|
||||
/>
|
||||
))
|
||||
}
|
||||
</g>
|
||||
<svg className={styles.icon} width={size} height={size}>
|
||||
<path d={describeArc(size / 2, size / 2, size / 2, 0, 90)} />
|
||||
<path d={describeArc(size / 2, size / 2, size / 2, 180, 270)} />
|
||||
</svg>
|
||||
</div>
|
||||
);
|
||||
|
||||
/*
|
||||
<div className={styles.wrap}>
|
||||
<svg className={styles.icon} width={size} height={size}>
|
||||
<path d={describeArc(size / 2, size / 2, size / 2, 0, 90)} />
|
||||
<path d={describeArc(size / 2, size / 2, size / 2, 180, 270)} />
|
||||
</svg>
|
||||
</div>
|
||||
*/
|
||||
|
|
|
@ -4,16 +4,26 @@
|
|||
}
|
||||
|
||||
@keyframes spin {
|
||||
0% { transform: rotate(0); }
|
||||
100% { transform: rotate(360deg); }
|
||||
0% {
|
||||
transform: rotate(0);
|
||||
}
|
||||
100% {
|
||||
transform: rotate(360deg);
|
||||
}
|
||||
}
|
||||
|
||||
@keyframes fade {
|
||||
0% { opacity: 1; transform: scale(1); }
|
||||
100% { opacity: 0.1; transform: scale(4); }
|
||||
0% {
|
||||
opacity: 1;
|
||||
transform: scale(1);
|
||||
}
|
||||
100% {
|
||||
opacity: 0.1;
|
||||
transform: scale(4);
|
||||
}
|
||||
}
|
||||
|
||||
.wrap {
|
||||
animation: spin infinite steps(9, end) 1s;
|
||||
animation: spin infinite 1s linear;
|
||||
display: inline-flex;
|
||||
}
|
||||
|
|
18
src/components/node/NodeComments/index.tsx
Normal file
18
src/components/node/NodeComments/index.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
import React, { FC } from 'react';
|
||||
import range from 'ramda/es/range';
|
||||
import { Comment } from '../Comment';
|
||||
import { INode } from '~/redux/types';
|
||||
|
||||
interface IProps {
|
||||
comments?: any;
|
||||
}
|
||||
|
||||
const NodeComments: FC<IProps> = ({ comments }) => (
|
||||
<div>
|
||||
{range(1, 6).map(el => (
|
||||
<Comment key={el} />
|
||||
))}
|
||||
</div>
|
||||
);
|
||||
|
||||
export { NodeComments };
|
21
src/components/node/NodeImageBlock/index.tsx
Normal file
21
src/components/node/NodeImageBlock/index.tsx
Normal file
|
@ -0,0 +1,21 @@
|
|||
import React, { FC } from 'react';
|
||||
import { ImageSwitcher } from '../ImageSwitcher';
|
||||
import * as styles from './styles.scss';
|
||||
|
||||
interface IProps {}
|
||||
|
||||
const NodeImageBlock: FC<IProps> = ({}) => (
|
||||
<div>
|
||||
<ImageSwitcher total={5} current={2} />
|
||||
|
||||
<div className={styles.image_container}>
|
||||
<img
|
||||
className={styles.image}
|
||||
src="http://37.192.131.144/full/attached/2019/08/e4fb2a1d0a2e20d499aaa1f5f83a7115.jpg"
|
||||
alt=""
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
||||
export { NodeImageBlock };
|
15
src/components/node/NodeImageBlock/styles.scss
Normal file
15
src/components/node/NodeImageBlock/styles.scss
Normal file
|
@ -0,0 +1,15 @@
|
|||
.image_container {
|
||||
width: 100%;
|
||||
background: $node_image_bg;
|
||||
border-radius: $panel_radius 0 0 $panel_radius;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.image {
|
||||
max-height: 800px;
|
||||
opacity: 1;
|
||||
width: 100%;
|
||||
border-radius: $radius $radius 0 0;
|
||||
}
|
||||
}
|
11
src/components/node/NodeImageBlockPlaceholder/index.tsx
Normal file
11
src/components/node/NodeImageBlockPlaceholder/index.tsx
Normal file
|
@ -0,0 +1,11 @@
|
|||
import React, { FC } from 'react';
|
||||
import * as styles from './styles.scss';
|
||||
import { LoaderCircle } from '~/components/input/LoaderCircle';
|
||||
|
||||
const NodeImageBlockPlaceholder: FC<{}> = () => (
|
||||
<div className={styles.placeholder}>
|
||||
<LoaderCircle size={64} />
|
||||
</div>
|
||||
);
|
||||
|
||||
export { NodeImageBlockPlaceholder };
|
14
src/components/node/NodeImageBlockPlaceholder/styles.scss
Normal file
14
src/components/node/NodeImageBlockPlaceholder/styles.scss
Normal file
|
@ -0,0 +1,14 @@
|
|||
.placeholder {
|
||||
height: 33vw;
|
||||
background: transparentize(black, 0.8);
|
||||
border: $radius $radius 0 0;
|
||||
@include outer_shadow();
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
svg {
|
||||
fill: transparentize(white, 0.95);
|
||||
}
|
||||
}
|
18
src/components/node/NodeTags/index.tsx
Normal file
18
src/components/node/NodeTags/index.tsx
Normal file
|
@ -0,0 +1,18 @@
|
|||
import React, { FC } from 'react';
|
||||
import { Tags } from '../Tags';
|
||||
|
||||
interface IProps {}
|
||||
|
||||
const NodeTags: FC<IProps> = ({}) => (
|
||||
<Tags
|
||||
tags={[
|
||||
{ title: 'Избранный', feature: 'red' },
|
||||
{ title: 'Плейлист', feature: 'green' },
|
||||
{ title: 'Просто' },
|
||||
{ title: '+ фото', feature: 'black' },
|
||||
{ title: '+ с музыкой', feature: 'black' },
|
||||
]}
|
||||
/>
|
||||
);
|
||||
|
||||
export { NodeTags };
|
Loading…
Add table
Add a link
Reference in a new issue