Skip to content

Commit

Permalink
SOROKA-138: cards layout (#19)
Browse files Browse the repository at this point in the history
SOROKA-138: cards layout
  • Loading branch information
AlexRbkv authored Oct 6, 2022
1 parent 7094f06 commit aa9d50c
Showing 14 changed files with 196 additions and 42 deletions.
11 changes: 11 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -12,6 +12,7 @@
"@types/react-dom": "^18.0.6",
"axios": "^0.27.2",
"bootstrap": "^5.2.0",
"ilib": "^14.15.1",
"react": "^18.2.0",
"react-bootstrap": "^2.5.0",
"react-dom": "^18.2.0",
5 changes: 3 additions & 2 deletions src/api/cards.ts
Original file line number Diff line number Diff line change
@@ -9,11 +9,12 @@ export type Property = {
};
};

type CardProperty = {
export type CardProperty = {
id: number;
data: string;
propertyId: number;
propertyName?: string;
propertyName: string;
propertyDataType: string;
};

export type CardData = {
27 changes: 17 additions & 10 deletions src/components/CollectionViewer.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { useMemo, useState } from "react";
import { CardData } from "../api/cards";
import usePagination from "../hooks/usePagination";
import PropertiesParser from "./PropertiesParser";

const PAGE_SIZE = 10;

@@ -23,16 +24,22 @@ type Props = {
};

const simpleSearch = (str: string, lowerCaseSearch: string) => str.toLowerCase().indexOf(lowerCaseSearch) !== -1;
const CardItem = ({ id, name, propertiesList }: CardItemProps) => (
<li key={id} className="collection-detailed__card-item">
<h3>{name}</h3>
<ul className="collection-detailed__properties-list">
{propertiesList?.map(({ propertyName, data, propertyId }) => (
<li key={propertyId} className="collection-detailed__properties-list-item">{`${propertyName}: ${data}`}</li>
))}
</ul>
</li>
);
const CardItem = ({ id, name, propertiesList }: CardItemProps) => {
return (
<li key={id} className="collection-detailed__card-item">
<h3>{name}</h3>
<ul className="collection-detailed__properties-list">
{propertiesList?.map((property) => {
return (
<li key={property.propertyId} className="collection-detailed__properties-list-item">
<PropertiesParser property={property} />
</li>
);
})}
</ul>
</li>
);
};

const CollectionViewer = ({ cards, isLoading, organizations, setFilterValue }: Props) => {
const [searchValue, setSearchValue] = useState("");
51 changes: 51 additions & 0 deletions src/components/DatePropertyParser.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { CALENDAR_TYPE, PROPERTIES_NAMES } from "../utils/constants";
// @ts-ignore
import GregorianDate from "ilib/lib/GregorianDate";
// @ts-ignore
import JulianDate from "ilib/lib/JulianDate";
// @ts-ignore
import DateFmt from "ilib/lib/DateFmt";
import { PropertiesParserProps } from "./PropertiesParser";

const fromJDJulian = (julianday: number) => {
const dateFormat = new DateFmt({ template: "dd.MM.yyyy", calendar: "julian", timezone: "GMT" });
return dateFormat.format(new JulianDate({ julianday, timezone: "GMT" }));
};

const fromJDGregorian = (julianday: number) => {
const dateFormat = new DateFmt({ template: "dd.MM.yyyy", timezone: "GMT" });
return dateFormat.format(new GregorianDate({ julianday, timezone: "GMT" }));
};

const DatePropertyParser = ({ property }: PropertiesParserProps) => {
const data = JSON.parse(property.data)[0];
if (data.calendar === CALENDAR_TYPE.STRING) {
return (
<p>
{`${PROPERTIES_NAMES[property.propertyName]}: `}

{data.startContext ? `${data.startContext} (${fromJDGregorian(data.startJD)})` : fromJDGregorian(data.startJD)}
{data.endJD
? data.endContext
? `- ${data.endContext} (${fromJDGregorian(data.endJD)})`
: `- ${fromJDGregorian(data.endJD)}`
: ""}
</p>
);
} else if (data.calendar === CALENDAR_TYPE.JULIAN) {
return (
<p>
{`${PROPERTIES_NAMES[property.propertyName]}:`}{" "}
{`${fromJDJulian(data.startJD)} ${data.endJD && "- " + fromJDJulian(data.endJD)} (по старому стилю)`}
</p>
);
}
return (
<p>
{`${PROPERTIES_NAMES[property.propertyName]}:`}{" "}
{`${fromJDGregorian(data.startJD)} ${data.endJD && "- " + fromJDGregorian(data.endJD)}`}
</p>
);
};

export default DatePropertyParser;
12 changes: 12 additions & 0 deletions src/components/GeoPropertyParser.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { PROPERTIES_NAMES } from "../utils/constants";
import { PropertiesParserProps } from "./PropertiesParser";

const GeoPropertyParser = ({ property }: PropertiesParserProps) => {
return (
<div>{`${PROPERTIES_NAMES[property.propertyName]}: ${JSON.parse(property.data)[0].location.coordinates[0]}, ${
JSON.parse(property.data)[0].location.coordinates[1]
}`}</div>
);
};

export default GeoPropertyParser;
19 changes: 2 additions & 17 deletions src/components/Menu.tsx
Original file line number Diff line number Diff line change
@@ -33,7 +33,6 @@ export class ExpandableMenuElement extends MenuElement {

const Menu = () => {
const [isNavbarOpen, setIsNavbarOpen] = useState(false);
const [isMenuCabinetOpen, setIsMenuCabinetOpen] = useState(false);
const location = useLocation();
const pathname = location.pathname.slice(1);
useEffect(() => setIsNavbarOpen(false), [location]);
@@ -97,29 +96,15 @@ const Menu = () => {
<div className="menu_container menu-top_container">
<ul className="menu-top flex column content--start items--start">
{mainMenu.map((item, index) => (
<MenuItem
key={index}
item={item}
setIsMenuCabinetOpen={setIsMenuCabinetOpen}
pathname={pathname}
isNavbarOpen={isNavbarOpen}
menuType="main"
/>
<MenuItem key={index} item={item} pathname={pathname} isNavbarOpen={isNavbarOpen} menuType="main" />
))}
</ul>
</div>

<div className="menu_container menu-bottom_container">
<ul className="menu-bottom flex column content--start items--start">
{footerMenu.map((item, index) => (
<MenuItem
key={index}
item={item}
setIsMenuCabinetOpen={setIsMenuCabinetOpen}
pathname={pathname}
isNavbarOpen={isNavbarOpen}
menuType="footer"
/>
<MenuItem key={index} item={item} pathname={pathname} isNavbarOpen={isNavbarOpen} menuType="footer" />
))}
</ul>
</div>
11 changes: 2 additions & 9 deletions src/components/MenuItem.tsx
Original file line number Diff line number Diff line change
@@ -3,22 +3,15 @@ import { ExpandableMenuElement, MenuElement } from "./Menu";

type MenuItemProps = {
item: MenuElement | ExpandableMenuElement;
setIsMenuCabinetOpen: (value: boolean) => void;
pathname: string;
isNavbarOpen: boolean;
menuType: "main" | "footer";
};

const MenuItem = ({ item, setIsMenuCabinetOpen, pathname, isNavbarOpen, menuType }: MenuItemProps) => {
const MenuItem = ({ item, pathname, isNavbarOpen, menuType }: MenuItemProps) => {
return (
<>
<Link
to={item.route}
className="menu_block_contaner"
onClick={() => {
setIsMenuCabinetOpen(false);
}}
>
<Link to={item.route} className="menu_block_contaner">
<div className={`menu-bullet ${item.isSelected(pathname) && isNavbarOpen ? "menu-bullet-active" : ""}`}>
{menuType === "main" ? (
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 100 100">
30 changes: 30 additions & 0 deletions src/components/PropertiesParser.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { CardProperty } from "../api/cards";
import { DATA_TYPES } from "../utils/constants";
import GeoPropertyParser from "./GeoPropertyParser";
import DatePropertyParser from "./DatePropertyParser";
import TextPropertyParser from "./TextPropertyParser";
import RichTextPropertyParser from "./RichTextPropertyParser";

export type PropertiesParserProps = {
property: CardProperty;
};

const PropertiesParser = ({ property }: PropertiesParserProps) => {
const dataType = property.propertyDataType;
switch (dataType) {
case DATA_TYPES.TEXT:
return <TextPropertyParser property={property} />;
case DATA_TYPES.RICH_TEXT:
return <RichTextPropertyParser property={property} />;
case DATA_TYPES.JULIAN_DATE:
return <DatePropertyParser property={property} />;
case DATA_TYPES.GEO_POINT:
return <GeoPropertyParser property={property} />;
case DATA_TYPES.MEDIA:
return <div>в разработке</div>;
default:
return <span>Неизвестное свойство</span>;
}
};

export default PropertiesParser;
13 changes: 13 additions & 0 deletions src/components/RichTextPropertyParser.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { PROPERTIES_NAMES } from "../utils/constants";
import { PropertiesParserProps } from "./PropertiesParser";

const RichTextPropertyParser = ({ property }: PropertiesParserProps) => {
return (
<p>
{`${PROPERTIES_NAMES[property.propertyName]}: `}{" "}
<span dangerouslySetInnerHTML={{ __html: property.data.slice(1, -1) }}></span>
</p>
);
};

export default RichTextPropertyParser;
8 changes: 8 additions & 0 deletions src/components/TextPropertyParser.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import { PROPERTIES_NAMES } from "../utils/constants";
import { PropertiesParserProps } from "./PropertiesParser";

const TextPropertyParser = ({ property }: PropertiesParserProps) => {
return <p>{`${PROPERTIES_NAMES[property.propertyName]}: ${JSON.parse(property.data).value}`}</p>;
};

export default TextPropertyParser;
3 changes: 2 additions & 1 deletion src/containers/CollectionViewerContainer.tsx
Original file line number Diff line number Diff line change
@@ -8,7 +8,8 @@ const getPatchedCards = (cardsList: CardData[], propertiesList: Property[]) => {
...card,
propertiesList: card.propertiesList.map((cardProperty) => ({
...cardProperty,
propertyName: propertiesList.find(({ propertyId }) => propertyId === cardProperty.propertyId)?.name || ""
propertyName: propertiesList.find(({ propertyId }) => propertyId === cardProperty.propertyId)?.name || "",
propertyDataType: propertiesList.find(({ propertyId }) => propertyId === cardProperty.propertyId)?.dataType.name || ""
}))
}));
const patchedWithoutMS = patched.filter((item) => item.organizationId !== 1);
7 changes: 4 additions & 3 deletions src/styles/style.css
Original file line number Diff line number Diff line change
@@ -1564,9 +1564,9 @@ p.team_person{
list-style: none;
padding: 2rem 0;
margin: 0;
display: flex;
flex-direction: column;
gap: 1rem;
display: grid;
grid-template-columns: repeat( auto-fit, minmax(350px, 1fr) );
grid-gap: 1rem;
width: 90%;
}

@@ -1585,6 +1585,7 @@ p.team_person{

.collection-detailed__properties-list-item {
margin-bottom: 0.5rem;
word-wrap: break-word;
}

/* Collection detailed ↑ */
40 changes: 40 additions & 0 deletions src/utils/constants.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
export const DATA_TYPES = {
GEO_POINT: "GEO_POINT",
RICH_TEXT: "RICH_TEXT",
JULIAN_DATE: "JULIAN_DATE",
MEDIA: "MEDIA",
TEXT: "TEXT"
};

export const CALENDAR_TYPE = {
GREGORIAN: 1,
JULIAN: 2,
STRING: 3
};

export const PROPERTIES_NAMES: { [key: string]: string } = {
unknownProperty: "Неизвестное свойство",
address: "Адрес",
legalName: "Юридическое название",
artisticText: "Художественный текст",
tags: "Теги",
sources: "Источники",
quote: "Цитата",
julianDate: "Дата",
geoPoint: "Гео-точка",
annotation: "Аннотация",
media: "Медиа",
bibliography: "Библиографическое описание",
copyrightHolder: "Правообладатель",
creationPlace: "Место создания",
creator: "Создатель",
family: "Родители (семья)",
format: "Формат",
originalText: "Оригинальный текст",
participants: "Участники",
profession: "Профессия",
refutation: "Опровержение",
socialNetworks: "Социальные сети",
storage: "Место хранения",
url: "URL"
};

0 comments on commit aa9d50c

Please sign in to comment.