diff --git a/app/oer/page.tsx b/app/oer/page.tsx
new file mode 100644
index 00000000..84535b99
--- /dev/null
+++ b/app/oer/page.tsx
@@ -0,0 +1,40 @@
+import { Suspense } from 'react';
+import { dehydrate } from 'react-query/core';
+
+import Hydrate from '../../src/components/HydrateClient';
+import Wrapper from '../../src/components/common/Wrapper';
+import OERInformation from '../../src/components/pages/OERInformation';
+import { APP_AUTHOR } from '../../src/config/constants';
+import getQueryClient from '../../src/config/get-query-client';
+import LIBRARY from '../../src/langs/constants';
+import en from '../../src/langs/en.json';
+import { buildSeo } from '../seo';
+
+export async function generateMetadata() {
+ // todo: get lang from location and crawler
+ // question: how to get language from
+ // @ts-ignore
+ const t = (s: string): string => en[s];
+
+ return buildSeo({
+ title: t(LIBRARY.OER_INFORMATION_PAGE_TITLE),
+ description: t(LIBRARY.OER_INFORMATION_PAGE_DESCRIPTION),
+ author: APP_AUTHOR,
+ });
+}
+
+const Page = async () => {
+ const queryClient = getQueryClient();
+ const dehydratedState = dehydrate(queryClient);
+
+ return (
+
+
+
+
+
+
+
+ );
+};
+export default Page;
diff --git a/src/components/collection/Badges.tsx b/src/components/collection/Badges.tsx
index 43464ea7..770ade12 100644
--- a/src/components/collection/Badges.tsx
+++ b/src/components/collection/Badges.tsx
@@ -1,18 +1,11 @@
-import truncate from 'lodash.truncate';
+import { Stack } from '@mui/material';
-import { useEffect, useState } from 'react';
-
-import { Email, Facebook, Twitter } from '@mui/icons-material';
-import { IconButton, Stack } from '@mui/material';
-
-import {
- MAIL_BREAK_LINE,
- TWITTER_MESSAGE_MAX_LENGTH,
-} from '../../config/constants';
import { useLibraryTranslation } from '../../config/i18n';
import LIBRARY from '../../langs/constants';
-import { openInNewTab } from '../../utils/helpers';
import { removeTagsFromString } from '../../utils/text';
+import EmailButton from '../common/EmailButton';
+import FacebookButton from '../common/FacebookButton';
+import TwitterButton from '../common/TwitterButton';
type Props = {
name?: string;
@@ -21,48 +14,20 @@ type Props = {
const Badges = ({ name, description }: Props) => {
const { t } = useLibraryTranslation();
- const [pageLocation, setPageLocation] = useState();
- const parsedDescription = removeTagsFromString(description);
-
- useEffect(() => {
- setPageLocation(window?.location.href);
- }, []);
- const shareOnTwitter = () => {
- const message = truncate(
- `${t(LIBRARY.SHARE_TWITTER_MESSAGE, {
- name,
- })} ${pageLocation} : ${parsedDescription}`,
- { length: TWITTER_MESSAGE_MAX_LENGTH, separator: /,? +/ },
- );
- openInNewTab(`https://twitter.com/intent/tweet?text=${message}`);
- };
-
- const shareOnFacebook = () => {
- const link = pageLocation;
- openInNewTab(`https://www.facebook.com/sharer/sharer.php?u=${link}`);
- };
-
- const subject = `${t(LIBRARY.SHARE_FACEBOOK_SUBJECT, { name })}`;
- const message = `${t(LIBRARY.SHARE_FACEBOOK_SUBJECT, {
- name,
- })} ${pageLocation}${MAIL_BREAK_LINE}${MAIL_BREAK_LINE}${parsedDescription}`;
- const mailString = `mailto:?subject=${subject}&body=${message}`;
+ const parsedDescription = removeTagsFromString(description);
const iconSize = 'medium';
return (
-
-
-
-
-
-
-
-
-
-
-
+
+
+
);
};
diff --git a/src/components/collection/ItemCollection.tsx b/src/components/collection/ItemCollection.tsx
index 8423ab3a..06d6e407 100644
--- a/src/components/collection/ItemCollection.tsx
+++ b/src/components/collection/ItemCollection.tsx
@@ -1,25 +1,13 @@
import React from 'react';
-import {
- Box,
- Container,
- SxProps,
- Theme,
- Typography,
- styled,
-} from '@mui/material';
+import { Container, SxProps, Theme, Typography } from '@mui/material';
import { DiscriminatedItem } from '@graasp/sdk';
import { SECTION_TITLE_ID } from '../../config/selectors';
+import StyledContainer from '../layout/StyledContainer';
import CollectionsGrid from './CollectionsGrid';
-const StyledContainer = styled(Box)(({ theme }) => ({
- backgroundColor: 'white',
- ':nth-child(even)': { backgroundColor: '#fafafa' },
- padding: theme.spacing(4, 3, 8, 3),
-}));
-
type ItemCollectionProps = {
id: string;
collectionGridId?: string;
diff --git a/src/components/collection/oer/VideoWithCC.tsx b/src/components/collection/oer/VideoWithCC.tsx
new file mode 100644
index 00000000..b8caf588
--- /dev/null
+++ b/src/components/collection/oer/VideoWithCC.tsx
@@ -0,0 +1,89 @@
+import { List, ListItem, Stack } from '@mui/material';
+
+import { CCLicenseAdaptions } from '@graasp/sdk';
+
+import { useLibraryTranslation } from '../../../config/i18n';
+import LIBRARY from '../../../langs/constants';
+import CreativeCommons from '../../common/CreativeCommons';
+
+type Props = {
+ ccLicenseAdaption?: CCLicenseAdaptions;
+ url: string;
+ title: string;
+ production?: string;
+ duration?: string;
+ edition?: string;
+};
+
+const VideoWithCC = ({
+ url,
+ title,
+ ccLicenseAdaption = CCLicenseAdaptions.CC_BY_SA,
+ production,
+ duration,
+ edition,
+}: Props): JSX.Element => {
+ const { t } = useLibraryTranslation();
+
+ return (
+
+
+
+
+ {production && (
+
+
+ {t(LIBRARY.OER_INFORMATION_VIDEO_DESCRIPTION_PRODUCTION)}
+
+ : {production}
+
+ )}
+ {duration && (
+
+
+ {t(LIBRARY.OER_INFORMATION_VIDEO_DESCRIPTION_DURATION)}
+
+ : {duration}
+
+ )}
+ {edition && (
+
+
+ {t(LIBRARY.OER_INFORMATION_VIDEO_DESCRIPTION_EDITION)}
+
+ : {edition}
+
+ )}
+
+ {ccLicenseAdaption && (
+
+ )}
+
+
+ );
+};
+
+export default VideoWithCC;
diff --git a/src/components/collection/summary/SummaryDetails.tsx b/src/components/collection/summary/SummaryDetails.tsx
index cdc09bed..a36cec73 100644
--- a/src/components/collection/summary/SummaryDetails.tsx
+++ b/src/components/collection/summary/SummaryDetails.tsx
@@ -18,7 +18,6 @@ import {
DiscriminatedItem,
formatDate,
} from '@graasp/sdk';
-import { CCSharingVariant, CreativeCommons } from '@graasp/ui';
import { CATEGORY_COLORS, UrlSearch } from '../../../config/constants';
import {
@@ -37,6 +36,7 @@ import {
} from '../../../config/selectors';
import LIBRARY from '../../../langs/constants';
import { QueryClientContext } from '../../QueryClientContext';
+import CreativeCommons from '../../common/CreativeCommons';
const DetailCard = styled(Box)(() => ({
border: '1px solid #ddd',
@@ -45,31 +45,6 @@ const DetailCard = styled(Box)(() => ({
height: '100%',
}));
-const convertLicense = (ccLicenseAdaption: string) => {
- // Legacy licenses.
- if (['alike', 'allow'].includes(ccLicenseAdaption)) {
- return {
- requireAccreditation: true,
- allowCommercialUse: true,
- allowSharing: ccLicenseAdaption === 'alike' ? 'alike' : 'yes',
- };
- }
-
- return {
- requireAccreditation: ccLicenseAdaption?.includes('BY'),
- allowCommercialUse: !ccLicenseAdaption?.includes('NC'),
- allowSharing: (() => {
- if (!ccLicenseAdaption || !ccLicenseAdaption.length) {
- return '';
- }
- if (ccLicenseAdaption?.includes('SA')) {
- return 'alike';
- }
- return ccLicenseAdaption?.includes('ND') ? 'no' : 'yes';
- })(),
- };
-};
-
type CategoryChipProps = {
category: Category;
};
@@ -157,12 +132,6 @@ const SummaryDetails: React.FC = ({
?.filter((c) => c.category.type === CategoryType.Language)
?.map((c) => c.category);
- const { allowSharing, allowCommercialUse, requireAccreditation } =
- React.useMemo(
- () => convertLicense(ccLicenseAdaption ?? ''),
- [ccLicenseAdaption],
- );
-
return (
= ({
{isLoading ? (
-
+
) : (
@@ -258,13 +222,7 @@ const SummaryDetails: React.FC = ({
className={ccLicenseAdaption}
>
{ccLicenseAdaption && ccLicenseAdaption.length > 0 ? (
-
+
) : (
{
+ if (!ccLicenseAdaption || !ccLicenseAdaption.length) {
+ return '';
+ }
+ if (ccLicenseAdaption?.includes('SA')) {
+ return 'alike';
+ }
+ return ccLicenseAdaption?.includes('ND') ? 'no' : 'yes';
+};
+
+const convertLicense = (ccLicenseAdaption: string) => {
+ // Legacy licenses.
+ if (['alike', 'allow'].includes(ccLicenseAdaption)) {
+ return {
+ requireAccreditation: true,
+ allowCommercialUse: true,
+ allowSharing: ccLicenseAdaption === 'alike' ? 'alike' : 'yes',
+ };
+ }
+
+ return {
+ requireAccreditation: ccLicenseAdaption?.includes('BY'),
+ allowCommercialUse: !ccLicenseAdaption?.includes('NC'),
+ allowSharing: getAllowSharingProperty(ccLicenseAdaption),
+ };
+};
+
+type Props = {
+ id?: string;
+ ccLicenseAdaption: DiscriminatedItem['settings']['ccLicenseAdaption'];
+ iconSize?: number;
+};
+
+const CreativeCommons = ({
+ id,
+ ccLicenseAdaption,
+ iconSize = 48,
+}: Props): JSX.Element => {
+ const { t } = useLibraryTranslation();
+
+ const { allowSharing, allowCommercialUse, requireAccreditation } =
+ convertLicense(ccLicenseAdaption ?? '');
+
+ if (ccLicenseAdaption && ccLicenseAdaption.length > 0) {
+ return (
+
+ );
+ }
+
+ return (
+
+ {t(LIBRARY.SUMMARY_DETAILS_EMPTY_LICENSE_TEXT)}
+
+ );
+};
+
+export default CreativeCommons;
diff --git a/src/components/common/DiscoverButton.tsx b/src/components/common/DiscoverButton.tsx
new file mode 100644
index 00000000..1df98efd
--- /dev/null
+++ b/src/components/common/DiscoverButton.tsx
@@ -0,0 +1,60 @@
+import Link from 'next/link';
+
+import { ArrowForward } from '@mui/icons-material';
+import { Box, Button, styled } from '@mui/material';
+
+import { LibraryIcon } from '@graasp/ui';
+
+import { ALL_COLLECTIONS_ROUTE } from '../../config/routes';
+
+const StyledButton = styled(Button)(({ theme }) => ({
+ fontSize: '1.2rem',
+ padding: theme.spacing(1, 2),
+ margin: theme.spacing(3),
+ [theme.breakpoints.up('sm')]: {
+ padding: theme.spacing(3, 6),
+ },
+ backgroundColor: 'transparent',
+ textTransform: 'none',
+ ':hover': {
+ transition: 'background-color 500ms linear',
+ backgroundColor: 'rgba(255, 255, 255, 0.15)',
+ },
+ '&:hover > .MuiButton-endIcon': {
+ '@keyframes bounce': {
+ '0%': { transform: 'translateX(0px)' },
+ '30%': { transform: 'translateX(15px)' },
+ '85%': { transform: 'translateX(0px)' },
+ },
+ animationName: 'bounce',
+ animationDuration: '1.2s',
+ animationIterationCount: 'infinite',
+ },
+}));
+
+type Props = {
+ message: string;
+};
+
+const DiscoverButton = ({ message }: Props) => {
+ return (
+ }
+ color="secondary"
+ >
+
+
+ {message}
+
+
+ );
+};
+
+export default DiscoverButton;
diff --git a/src/components/common/EmailButton.tsx b/src/components/common/EmailButton.tsx
new file mode 100644
index 00000000..ef3acf8b
--- /dev/null
+++ b/src/components/common/EmailButton.tsx
@@ -0,0 +1,57 @@
+'use client';
+
+import { useEffect, useState } from 'react';
+
+import { Email } from '@mui/icons-material';
+import { IconProps, Tooltip } from '@mui/material';
+
+import { MAIL_BREAK_LINE } from '../../config/constants';
+import { useLibraryTranslation } from '../../config/i18n';
+import LIBRARY from '../../langs/constants';
+import { removeTagsFromString } from '../../utils/text';
+import StyledIconButton from '../layout/StyledIconButton';
+
+type Props = {
+ iconSize: IconProps['fontSize'];
+ name?: string;
+ description?: string | null;
+ showBorder?: boolean;
+};
+
+const EmailButton = ({
+ name,
+ iconSize,
+ description,
+ showBorder = false,
+}: Props): JSX.Element => {
+ const { t } = useLibraryTranslation();
+ const [pageLocation, setPageLocation] =
+ useState('https://graasp.org');
+
+ useEffect(() => {
+ if (window?.location?.href) {
+ setPageLocation(window?.location?.href);
+ }
+ }, []);
+
+ const parsedDescription = removeTagsFromString(description);
+
+ const subject = `${t(LIBRARY.SHARE_FACEBOOK_SUBJECT, { name })}`;
+ const message = `${t(LIBRARY.SHARE_FACEBOOK_SUBJECT, {
+ name,
+ })} ${pageLocation}${MAIL_BREAK_LINE}${MAIL_BREAK_LINE}${parsedDescription}`;
+
+ const mailString = `mailto:?subject=${subject}&body=${message}`;
+
+ return (
+
+
+
+
+
+
+
+ );
+};
+
+export default EmailButton;
diff --git a/src/components/common/FacebookButton.tsx b/src/components/common/FacebookButton.tsx
new file mode 100644
index 00000000..9d2d51d3
--- /dev/null
+++ b/src/components/common/FacebookButton.tsx
@@ -0,0 +1,50 @@
+'use client';
+
+import { useEffect, useState } from 'react';
+
+import { Facebook } from '@mui/icons-material';
+import { IconProps, Tooltip } from '@mui/material';
+
+import { useLibraryTranslation } from '../../config/i18n';
+import LIBRARY from '../../langs/constants';
+import { openInNewTab } from '../../utils/helpers';
+import StyledIconButton from '../layout/StyledIconButton';
+
+type Props = {
+ iconSize: IconProps['fontSize'];
+ showBorder?: boolean;
+};
+
+const FacebookButton = ({
+ iconSize,
+ showBorder = false,
+}: Props): JSX.Element => {
+ const { t } = useLibraryTranslation();
+ const [pageLocation, setPageLocation] =
+ useState('https://graasp.org');
+
+ useEffect(() => {
+ if (window?.location?.href) {
+ setPageLocation(window?.location?.href);
+ }
+ }, []);
+
+ const shareOnFacebook = () => {
+ openInNewTab(
+ `https://www.facebook.com/sharer/sharer.php?u=${pageLocation}`,
+ );
+ };
+
+ return (
+
+ {/* necessary span for tooltip to how */}
+
+
+
+
+
+
+ );
+};
+
+export default FacebookButton;
diff --git a/src/components/common/TwitterButton.tsx b/src/components/common/TwitterButton.tsx
new file mode 100644
index 00000000..bec0ea56
--- /dev/null
+++ b/src/components/common/TwitterButton.tsx
@@ -0,0 +1,56 @@
+'use client';
+
+import truncate from 'lodash.truncate';
+
+import { useEffect, useState } from 'react';
+
+import { Twitter } from '@mui/icons-material';
+import { IconProps, Tooltip } from '@mui/material';
+
+import { TWITTER_MESSAGE_MAX_LENGTH } from '../../config/constants';
+import { useLibraryTranslation } from '../../config/i18n';
+import LIBRARY from '../../langs/constants';
+import { openInNewTab } from '../../utils/helpers';
+import StyledIconButton from '../layout/StyledIconButton';
+
+type Props = {
+ iconSize: IconProps['fontSize'];
+ message: string;
+ showBorder?: boolean;
+};
+
+const TwitterButton = ({
+ iconSize,
+ message,
+ showBorder = false,
+}: Props): JSX.Element => {
+ const { t } = useLibraryTranslation();
+ const [pageLocation, setPageLocation] =
+ useState('https://graasp.org');
+
+ useEffect(() => {
+ if (window?.location?.href) {
+ setPageLocation(window?.location?.href);
+ }
+ }, []);
+
+ const shareOnTwitter = () => {
+ const msg = truncate(`${message} ${pageLocation}`, {
+ length: TWITTER_MESSAGE_MAX_LENGTH,
+ separator: /,? +/,
+ });
+ openInNewTab(`https://twitter.com/intent/tweet?text=${msg}`);
+ };
+
+ return (
+
+
+
+
+
+
+
+ );
+};
+
+export default TwitterButton;
diff --git a/src/components/layout/DrawerContent.tsx b/src/components/layout/DrawerContent.tsx
index 2bff1b3c..e8a651d2 100644
--- a/src/components/layout/DrawerContent.tsx
+++ b/src/components/layout/DrawerContent.tsx
@@ -7,6 +7,7 @@ import {
AutoAwesome,
BookOutlined,
Favorite,
+ ImportContacts,
Search,
TrendingUp,
} from '@mui/icons-material';
@@ -26,6 +27,7 @@ import { useLibraryTranslation } from '../../config/i18n';
import {
ALL_COLLECTIONS_ROUTE,
MY_LIKED_ITEMS_ROUTE,
+ OER_INFORMATION_ROUTE,
buildMemberRoute,
} from '../../config/routes';
import {
@@ -35,6 +37,7 @@ import {
MOST_LIKED_COLLECTIONS_DRAWER_ITEM_ID,
MOST_LIKED_TITLE_ID,
MY_PUBLICATIONS_DRAWER_ITEM_ID,
+ OER_INFORMATIONS_DRAWER_ITEM_ID,
RECENT_COLLECTIONS_DRAWER_ITEM_ID,
RECENT_PUBLICATIONS_TITLE_ID,
SEARCH_ALL_COLLECTIONS_DRAWER_ITEM_ID,
@@ -78,6 +81,12 @@ const DrawerContent = () => {
const { data: currentMember } = hooks.useCurrentMember();
return (
+ }
+ text={t(LIBRARY.DRAWER_OER_INFORMATION_TEXT)}
+ href={OER_INFORMATION_ROUTE}
+ />
}
diff --git a/src/components/layout/Footer.tsx b/src/components/layout/Footer.tsx
index 498a0552..8ac5f39c 100644
--- a/src/components/layout/Footer.tsx
+++ b/src/components/layout/Footer.tsx
@@ -1,3 +1,5 @@
+'use client';
+
import { useContext, useEffect, useState } from 'react';
import { Grid, styled } from '@mui/material';
diff --git a/src/components/layout/MainWrapper.tsx b/src/components/layout/MainWrapper.tsx
index 04caadb3..f7be1826 100644
--- a/src/components/layout/MainWrapper.tsx
+++ b/src/components/layout/MainWrapper.tsx
@@ -13,8 +13,10 @@ import useHeader from './useHeader';
const MainWrapper = ({
children,
+ backgroundColor,
}: {
children: JSX.Element | JSX.Element[];
+ backgroundColor?: string;
}) => {
const { rightContent } = useHeader();
const { t } = useLibraryTranslation();
@@ -28,6 +30,7 @@ const MainWrapper = ({
drawerOpenAriaLabel={t(LIBRARY.DRAWER_ARIA_OPEN)}
PlatformComponent={}
LinkComponent={HeaderLinkComponent}
+ backgroundColor={backgroundColor}
>
{children}
diff --git a/src/components/layout/StyledBackgroundContainer.tsx b/src/components/layout/StyledBackgroundContainer.tsx
new file mode 100644
index 00000000..cb50f071
--- /dev/null
+++ b/src/components/layout/StyledBackgroundContainer.tsx
@@ -0,0 +1,13 @@
+import { Box, styled } from '@mui/material';
+
+import { GRAASP_COLOR } from '../../config/constants';
+
+const PATTERN_OPACITY = 0.7;
+const SECONDARY_PATTERN_COLOR = '505DD2';
+
+const StyledBackgroundContainer = styled(Box)(() => ({
+ backgroundColor: GRAASP_COLOR,
+ backgroundImage: `url("data:image/svg+xml,%3Csvg width='100' height='20' viewBox='0 0 100 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21.184 20c.357-.13.72-.264 1.088-.402l1.768-.661C33.64 15.347 39.647 14 50 14c10.271 0 15.362 1.222 24.629 4.928.955.383 1.869.74 2.75 1.072h6.225c-2.51-.73-5.139-1.691-8.233-2.928C65.888 13.278 60.562 12 50 12c-10.626 0-16.855 1.397-26.66 5.063l-1.767.662c-2.475.923-4.66 1.674-6.724 2.275h6.335zm0-20C13.258 2.892 8.077 4 0 4V2c5.744 0 9.951-.574 14.85-2h6.334zM77.38 0C85.239 2.966 90.502 4 100 4V2c-6.842 0-11.386-.542-16.396-2h-6.225zM0 14c8.44 0 13.718-1.21 22.272-4.402l1.768-.661C33.64 5.347 39.647 4 50 4c10.271 0 15.362 1.222 24.629 4.928C84.112 12.722 89.438 14 100 14v-2c-10.271 0-15.362-1.222-24.629-4.928C65.888 3.278 60.562 2 50 2 39.374 2 33.145 3.397 23.34 7.063l-1.767.662C13.223 10.84 8.163 12 0 12v2z' fill='%23${SECONDARY_PATTERN_COLOR}' fill-opacity='${PATTERN_OPACITY}' fill-rule='evenodd'/%3E%3C/svg%3E")`,
+}));
+
+export default StyledBackgroundContainer;
diff --git a/src/components/layout/StyledContainer.tsx b/src/components/layout/StyledContainer.tsx
new file mode 100644
index 00000000..24ee2c46
--- /dev/null
+++ b/src/components/layout/StyledContainer.tsx
@@ -0,0 +1,11 @@
+import { Box, styled } from '@mui/material';
+
+const StyledContainer = styled(Box)<{ background?: string }>(
+ ({ theme, background }) => ({
+ backgroundColor: background ?? 'white',
+ ':nth-child(even)': { backgroundColor: background ?? '#fafafa' },
+ padding: theme.spacing(4, 3, 8, 3),
+ }),
+);
+
+export default StyledContainer;
diff --git a/src/components/layout/StyledIconButton.tsx b/src/components/layout/StyledIconButton.tsx
new file mode 100644
index 00000000..33713fda
--- /dev/null
+++ b/src/components/layout/StyledIconButton.tsx
@@ -0,0 +1,29 @@
+import React from 'react';
+
+import { IconButton } from '@mui/material';
+
+const StyledIconButton = ({
+ children,
+ showBorder = false,
+ onClick,
+}: {
+ showBorder?: boolean;
+ children: JSX.Element;
+ onClick?: () => void;
+}) => {
+ return (
+
+ {children}
+
+ );
+};
+
+export default StyledIconButton;
diff --git a/src/components/pages/Home.tsx b/src/components/pages/Home.tsx
index 6849ec17..915993eb 100644
--- a/src/components/pages/Home.tsx
+++ b/src/components/pages/Home.tsx
@@ -1,21 +1,12 @@
'use client';
-import Link from 'next/link';
-
import { useContext } from 'react';
-import { ArrowForward } from '@mui/icons-material';
-import { Box, Button, styled } from '@mui/material';
-
-import { LibraryIcon } from '@graasp/ui';
+import { Box } from '@mui/material';
-import {
- GRAASP_COLOR,
- HOMEPAGE_NB_ELEMENTS_TO_SHOW,
-} from '../../config/constants';
+import { HOMEPAGE_NB_ELEMENTS_TO_SHOW } from '../../config/constants';
import { GRAASPER_ID } from '../../config/env';
import { useLibraryTranslation } from '../../config/i18n';
-import { ALL_COLLECTIONS_ROUTE } from '../../config/routes';
import {
GRAASPER_COLLECTIONS_GRID_ID,
GRAASP_SELECTION_TITLE_ID,
@@ -25,41 +16,10 @@ import {
import LIBRARY from '../../langs/constants';
import { QueryClientContext } from '../QueryClientContext';
import ItemCollection from '../collection/ItemCollection';
+import DiscoverButton from '../common/DiscoverButton';
import HomeHeader from '../layout/HomeHeader';
import MainWrapper from '../layout/MainWrapper';
-
-const PATTERN_OPACITY = 0.7;
-const SECONDARY_PATTERN_COLOR = '505DD2';
-
-const StyledBackgroundContainer = styled(Box)(() => ({
- backgroundColor: GRAASP_COLOR,
- backgroundImage: `url("data:image/svg+xml,%3Csvg width='100' height='20' viewBox='0 0 100 20' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M21.184 20c.357-.13.72-.264 1.088-.402l1.768-.661C33.64 15.347 39.647 14 50 14c10.271 0 15.362 1.222 24.629 4.928.955.383 1.869.74 2.75 1.072h6.225c-2.51-.73-5.139-1.691-8.233-2.928C65.888 13.278 60.562 12 50 12c-10.626 0-16.855 1.397-26.66 5.063l-1.767.662c-2.475.923-4.66 1.674-6.724 2.275h6.335zm0-20C13.258 2.892 8.077 4 0 4V2c5.744 0 9.951-.574 14.85-2h6.334zM77.38 0C85.239 2.966 90.502 4 100 4V2c-6.842 0-11.386-.542-16.396-2h-6.225zM0 14c8.44 0 13.718-1.21 22.272-4.402l1.768-.661C33.64 5.347 39.647 4 50 4c10.271 0 15.362 1.222 24.629 4.928C84.112 12.722 89.438 14 100 14v-2c-10.271 0-15.362-1.222-24.629-4.928C65.888 3.278 60.562 2 50 2 39.374 2 33.145 3.397 23.34 7.063l-1.767.662C13.223 10.84 8.163 12 0 12v2z' fill='%23${SECONDARY_PATTERN_COLOR}' fill-opacity='${PATTERN_OPACITY}' fill-rule='evenodd'/%3E%3C/svg%3E")`,
-}));
-
-const DiscoverButton = styled(Button)(({ theme }) => ({
- fontSize: '1.2rem',
- padding: theme.spacing(1, 2),
- margin: theme.spacing(3),
- [theme.breakpoints.up('sm')]: {
- padding: theme.spacing(3, 6),
- },
- backgroundColor: 'transparent',
- textTransform: 'none',
- ':hover': {
- transition: 'background-color 500ms linear',
- backgroundColor: 'rgba(255, 255, 255, 0.15)',
- },
- '&:hover > .MuiButton-endIcon': {
- '@keyframes bounce': {
- '0%': { transform: 'translateX(0px)' },
- '30%': { transform: 'translateX(15px)' },
- '85%': { transform: 'translateX(0px)' },
- },
- animationName: 'bounce',
- animationDuration: '1.2s',
- animationIterationCount: 'infinite',
- },
-}));
+import StyledBackgroundContainer from '../layout/StyledBackgroundContainer';
const Home = () => {
const { t } = useLibraryTranslation();
@@ -97,23 +57,10 @@ const Home = () => {
title={t(LIBRARY.HOME_RECENT_COLLECTIONS_TITLE)}
/>
-
+
}
- color="secondary"
- >
-
-
- {t(LIBRARY.HOME_VIEW_MORE_IN_LIBRARY_BUTTON)}
-
-
+ message={t(LIBRARY.HOME_VIEW_MORE_IN_LIBRARY_BUTTON)}
+ />
diff --git a/src/components/pages/OERInformation.tsx b/src/components/pages/OERInformation.tsx
new file mode 100644
index 00000000..912c057a
--- /dev/null
+++ b/src/components/pages/OERInformation.tsx
@@ -0,0 +1,135 @@
+'use client';
+
+import Link from 'next/link';
+
+import { Trans } from 'react-i18next';
+
+import { ImportContacts } from '@mui/icons-material';
+import { Box, Container, Divider, Typography } from '@mui/material';
+
+import { useLibraryTranslation } from '../../config/i18n';
+import LIBRARY from '../../langs/constants';
+import VideoWithCC from '../collection/oer/VideoWithCC';
+import DiscoverButton from '../common/DiscoverButton';
+import EmailButton from '../common/EmailButton';
+import FacebookButton from '../common/FacebookButton';
+import TwitterButton from '../common/TwitterButton';
+import MainWrapper from '../layout/MainWrapper';
+import StyledBackgroundContainer from '../layout/StyledBackgroundContainer';
+import StyledBox from '../layout/StyledContainer';
+
+const references = [
+ {
+ href: 'https://www.bpb.de/mediathek/video/234994/oer-erklaert-die-grundlagen/',
+ name: 'OER erklärt – die Grundlagen',
+ },
+ {
+ href: 'https://www.bpb.de/mediathek/video/234998/oer-erklaert-ueber-die-qualitaet-der-materialien/',
+ name: 'OER erklärt – über die Qualität der Materialien',
+ },
+];
+
+const OERInformation = () => {
+ const { t } = useLibraryTranslation();
+
+ return (
+
+
+
+
+
+ {t(LIBRARY.OER_INFORMATION_PAGE_TITLE)}
+
+
+ {t(LIBRARY.OER_INFORMATION_SUBTITLE)}
+
+
+
+ {/* share options */}
+
+
+
+
+
+
+
+
+
+ {/* first section */}
+
+
+
+ {t(LIBRARY.OER_INFORMATION_BASICS_TITLE)}
+
+
+ }}
+ />
+
+
+
+
+
+
+ {/* second section */}
+
+
+
+ {t(LIBRARY.OER_INFORMATION_QUALITY_TITLE)}
+
+
+
+ {t(LIBRARY.OER_INFORMATION_QUALITY_TEXT)}
+
+
+
+
+
+
+ {/* discover button */}
+
+
+
+
+ {/* references */}
+
+
+
+ {t(LIBRARY.OER_INFORMATION_MORE_INFORMATION_TITLE)}
+
+ {references.map(({ name, href }) => (
+
+ {name}
+
+ ))}
+
+
+
+
+ );
+};
+export default OERInformation;
diff --git a/src/config/routes.ts b/src/config/routes.ts
index 541618f5..f59e3b17 100644
--- a/src/config/routes.ts
+++ b/src/config/routes.ts
@@ -2,6 +2,7 @@ export const COLLECTIONS_ROUTE = '/collections';
export const buildCollectionRoute = (id = ':id') => `/collections/${id}`;
export const HOME_ROUTE = '/';
export const ALL_COLLECTIONS_ROUTE = '/all-collections';
+export const OER_INFORMATION_ROUTE = '/oer';
export const MY_LIKED_ITEMS_ROUTE = '/liked';
export const ERROR_ROUTE = '/error';
diff --git a/src/config/selectors.ts b/src/config/selectors.ts
index 064fd231..84e8ff83 100644
--- a/src/config/selectors.ts
+++ b/src/config/selectors.ts
@@ -78,6 +78,7 @@ export const SEARCH_ERROR_MESSAGE_ID = 'searchErrorMessage';
export const LIKE_COLLECTION_NOT_LOGGED_ID = 'likeCollectionLoginMessage';
+export const OER_INFORMATIONS_DRAWER_ITEM_ID = 'eorInformationDrawerItemId';
export const SEARCH_ALL_COLLECTIONS_DRAWER_ITEM_ID =
'searchAllCollectionsDrawerItemId';
export const GRAASPER_SELECTION_DRAWER_ITEM_ID =
diff --git a/src/langs/constants.ts b/src/langs/constants.ts
index 231ce741..f743cbbe 100644
--- a/src/langs/constants.ts
+++ b/src/langs/constants.ts
@@ -128,6 +128,7 @@ export const LIBRARY = {
DRAWER_AUTHENTICATED_USER_LINKS_SECTION:
'DRAWER_AUTHENTICATED_USER_LINKS_SECTION',
DRAWER_ALL_COLLECTIONS_TEXT: 'DRAWER_ALL_COLLECTIONS_TEXT',
+ DRAWER_OER_INFORMATION_TEXT: 'DRAWER_OER_INFORMATION_TEXT',
DRAWER_ARIA_OPEN: 'DRAWER_ARIA_OPEN',
PREVIEW_ALERT_TITLE: 'PREVIEW_ALERT_TITLE',
PREVIEW_ALERT_DESCRIPTION: 'PREVIEW_ALERT_DESCRIPTION',
@@ -139,5 +140,27 @@ export const LIBRARY = {
COPY_MODAL_RECENT_TITLE: 'COPY_MODAL_RECENT_TITLE',
COPY_MODAL_SUBMIT_BUTTON: 'COPY_MODAL_SUBMIT_BUTTON',
COPY_MODAL_MY_GRAASP_BREADCRUMB: 'COPY_MODAL_MY_GRAASP_BREADCRUMB',
+ OER_INFORMATION_BASICS_TEXT: 'OER_INFORMATION_BASICS_TEXT',
+ OER_INFORMATION_QUALITY_TEXT: 'OER_INFORMATION_QUALITY_TEXT',
+ OER_INFORMATION_PAGE_TITLE: 'OER_INFORMATION_PAGE_TITLE',
+ OER_INFORMATION_PAGE_DESCRIPTION: 'OER_INFORMATION_PAGE_DESCRIPTION',
+
+ OER_INFORMATION_SUBTITLE: 'OER_INFORMATION_SUBTITLE',
+ OER_INFORMATION_BASICS_TITLE: 'OER_INFORMATION_BASICS_TITLE',
+ OER_INFORMATION_QUALITY_TITLE: 'OER_INFORMATION_QUALITY_TITLE',
+ OER_INFORMATION_MORE_INFORMATION_TITLE:
+ 'OER_INFORMATION_MORE_INFORMATION_TITLE',
+ SHARE_FACEBOOK_TOOLTIP: 'SHARE_FACEBOOK_TOOLTIP',
+ SHARE_TWITTER_TOOLTIP: 'SHARE_TWITTER_TOOLTIP',
+ SHARE_EMAIL_TOOLTIP: 'SHARE_EMAIL_TOOLTIP',
+ OER_INFORMATION_DISCOVER_MORE_BUTTON_TEXT:
+ 'OER_INFORMATION_DISCOVER_MORE_BUTTON_TEXT',
+ OER_INFORMATION_VIDEO_DESCRIPTION_PRODUCTION:
+ 'OER_INFORMATION_VIDEO_DESCRIPTION_PRODUCTION',
+ OER_INFORMATION_VIDEO_DESCRIPTION_DURATION:
+ 'OER_INFORMATION_VIDEO_DESCRIPTION_DURATION',
+ OER_INFORMATION_VIDEO_DESCRIPTION_EDITION:
+ 'OER_INFORMATION_VIDEO_DESCRIPTION_EDITION',
+ DURATION_IN_MINUTES: 'DURATION_IN_MINUTES',
};
export default LIBRARY;
diff --git a/src/langs/en.json b/src/langs/en.json
index 5f6e5ec8..34d0803b 100644
--- a/src/langs/en.json
+++ b/src/langs/en.json
@@ -124,6 +124,7 @@
"SOCIAL_PROFILES": "Social Profiles",
"DRAWER_AUTHENTICATED_USER_LINKS_SECTION": "My links",
"DRAWER_ALL_COLLECTIONS_TEXT": "Search",
+ "DRAWER_OER_INFORMATION_TEXT": "Information about OER",
"DRAWER_ARIA_OPEN": "Open drawer",
"PREVIEW_ALERT_TITLE": "This is a preview",
"PREVIEW_ALERT_DESCRIPTION": "This item is not published. What you are seeing here is only a preview. You can see this because you have access to the item. It cannot be viewed publicly.",
@@ -134,5 +135,22 @@
"COPY_MODAL_HOME_TITLE": "Home",
"COPY_MODAL_RECENT_TITLE": "Recent items",
"COPY_MODAL_SUBMIT_BUTTON": "Submit",
- "COPY_MODAL_MY_GRAASP_BREADCRUMB": "My Graasp"
+ "COPY_MODAL_MY_GRAASP_BREADCRUMB": "My Graasp",
+ "OER_INFORMATION_BASICS_TEXT": "Is your lesson preparation underway and the textbook outdated? OER, or Open Educational Resources on the web, can be a great alternative. Whether it's worksheets, photos, or graphics: Depending on the license, educators not only can use the materials but also adapt them directly for their class. This video explains exactly how that works.",
+ "OER_INFORMATION_QUALITY_TEXT": "So far, there is no quality seal for OER materials. Many educators find this unsettling. Similar to Wikipedia, however, members of online communities oversee OER materials. And as these communities grow larger, more subject matter expertise and pedagogical knowledge come together.",
+ "OER_INFORMATION_PAGE_TITLE": "What are OERs?",
+ "OER_INFORMATION_PAGE_DESCRIPTION": "Information about Open Educational Resources OER",
+ "OER_INFORMATION_SUBTITLE": "Basics and quality of work",
+ "OER_INFORMATION_BASICS_TITLE": "The Basics",
+ "OER_INFORMATION_QUALITY_TITLE": "About the Quality of Materials",
+ "OER_INFORMATION_MORE_INFORMATION_TITLE": "More Information",
+ "SHARE_FACEBOOK_TOOLTIP": "Share on Facebook",
+ "SHARE_TWITTER_TOOLTIP": "Share on Twitter",
+ "SHARE_EMAIL_TOOLTIP": "Share by email",
+ "OER_INFORMATION_DISCOVER_MORE_BUTTON_TEXT": "Discover published Open Education Resources",
+ "OER_INFORMATION_VIDEO_DESCRIPTION_PRODUCTION": "Production",
+ "OER_INFORMATION_VIDEO_DESCRIPTION_DURATION": "Duration",
+ "OER_INFORMATION_VIDEO_DESCRIPTION_EDITION": "Edition",
+ "DURATION_IN_MINUTES_one": "{{count}} minute",
+ "DURATION_IN_MINUTES_other": "{{count}} minutes"
}