Skip to content

Commit

Permalink
(#80) Re-add working examples (along with previous commit)
Browse files Browse the repository at this point in the history
This reverts commit 5885911.
  • Loading branch information
espen42 committed Oct 11, 2021
1 parent 6eb94c0 commit 5bcfa68
Show file tree
Hide file tree
Showing 18 changed files with 686 additions and 3 deletions.
51 changes: 51 additions & 0 deletions src/components/blocks/header.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import React, {FunctionComponent} from "react"
import { getPublicAssetUrl } from '../../enonic-connection-config';
import Link from "next/link";

type HeaderProps = {
siteTitle?: string,
requestIsFromXp?: boolean
}

const Header: FunctionComponent<HeaderProps> = ({ siteTitle, requestIsFromXp }: HeaderProps) => {
const logoUrl = getPublicAssetUrl('images/xp-shield.svg', requestIsFromXp);

return (
<header
style={{
background: `rebeccapurple`,
marginBottom: `1.45rem`,
}}
>
<div
style={{
margin: `0 auto`,
maxWidth: 960,
padding: `1.45rem 1.0875rem`,
display: `flex`,
justifyContent: 'space-between'
}}
>
<h1 style={{margin: 0}}>
<Link
href="/">
<a style={{
color: `white`,
textDecoration: `none`,
}}
>
{siteTitle}
</a>
</Link>
</h1>
<img src={logoUrl}
width={33}
height={40}
alt={"Enonic XP logo"}
/>
</div>
</header>
)
}

export default Header
44 changes: 44 additions & 0 deletions src/components/blocks/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import React, {FunctionComponent} from "react"

import Link from 'next/link';

import Header from "./header"

type LayoutProps = {
siteTitle?: string,
pageProps: any,
children: any
};

const Layout: FunctionComponent<LayoutProps> = ({siteTitle, pageProps, children}: LayoutProps) => {

return (
<>
<Header siteTitle={siteTitle} requestIsFromXp={pageProps.meta?.requestIsFromXp} />
<div
style={{
margin: `0 auto`,
maxWidth: 960,
padding: `0 1.0875rem 1.45rem`,
}}
>
<main>{children}</main>

<footer>
<br />
<hr />
<br/>
© {new Date().getFullYear()}, Built with
{` `}
<Link href="https://nextjs.org"><a>Next.js</a></Link>
{` `}
Powered by
{` `}
<Link href="https://enonic.com"><a>Enonic XP</a></Link>
</footer>
</div>
</>
)
}

export default Layout;
56 changes: 56 additions & 0 deletions src/components/blocks/seo.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import React, {FunctionComponent} from "react"
import Head from 'next/head';

type Meta = {
name: string,
content: string
};

type SeoProps = {
description?: string,
lang?: string,
meta?: Meta | Meta[],
title: string,
author?: string,
siteTitle?: string,
keywords?: string[],
viewport?: JSX.Element
};

const Seo: FunctionComponent<SeoProps> = ({description, lang, meta, author, title, siteTitle, keywords, viewport}: SeoProps) => (

<Head>
<title>{
siteTitle && title
? `${title} | ${siteTitle}`
: title || siteTitle || ""
}</title>

<meta name="language" content={lang || 'en'} />
{description ? <meta name="description" content={description}/> : null}
{title ? <meta name="og:title" content={title}/> : null}
{description ? <meta name="og:description" content={description}/> : null}
<meta name="og:type" content="website"/>
<meta name="twitter:card" content="summary"/>
{author ? <meta name="twitter:creator" content={author}/> : null}
{author ? <meta name="author" content={author}/> : null}
{title ? <meta name="twitter:title" content={title}/> : null}
{description ? <meta name="twitter:description" content={description}/> : null}
{keywords ? <meta name="keywords" content={
[]
// @ts-ignore
.concat(keywords)
.join(", ")
} /> : null}
{viewport || <meta name="viewport" content="width=device-width, initial-scale=1.0"/>}

{ []
// @ts-ignore
.concat(meta || [])
.map(
(item:Meta, idx) => <meta key={idx} name={item.name} content={item.content} /> )
}
</Head>
);

export default Seo
23 changes: 23 additions & 0 deletions src/components/pagetypes/List.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import React from "react"

import {DisplayableList} from "../../selectors/propsProcessors/processFolder";

const ListPage = ( {displayName, children}: DisplayableList) => {
return (
<>
<h1>{displayName}</h1>
{
children &&
children.map((child, i) => (
<div key={i}>
<a href={child.url}>
{child.displayName}
</a>
</div>
))
}
</>
)
};

export default ListPage
98 changes: 98 additions & 0 deletions src/components/pagetypes/Movie.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
import React from "react"

import styles from "../../styles/Home.module.css";
import {DisplayableMovie} from "../../selectors/propsProcessors/processMovie";


const MoviePage = (movie: DisplayableMovie) => {
return (
<>
<div>
<div style={{
display: 'flex',
alignItems: 'baseline'
}}>
<h2>{movie.displayName}
{movie.release && (
<i style={{
fontStyle: 'normal',
fontWeight: 'normal',
fontSize: '24px',
marginLeft: '10px',
opacity: '0.7'
}}>({new Date(movie.release).getFullYear()})</i>
)}
</h2>
</div>
<div style={{
display: `flex`
}}>
{
movie.photo?.imageUrl &&
<img src={movie.photo.imageUrl}
title={movie.subtitle || undefined}
alt={movie.photo.alt}
className={styles.mainPhoto}/>
}
<div style={{
margin: `0 20px`
}}>
<p><i>{movie.abstract}</i></p>
{movie.cast && (
<>
<h4>Cast</h4>
<div style={{
display: `flex`,
padding: '0 15px'
}}>
{
movie.cast &&
movie.cast.map((cast, i) => {
return (
<div
key={i}
style={{
display: `flex`,
flexDirection: `column`
}}
>
{
cast.actorPhoto &&
<img src={cast.actorPhoto.imageUrl}
title={`${cast.actorName} as ${cast.character}`}
alt={cast.character}
className={styles.castPhoto} />
}
<div
style={{
display: `flex`,
flexDirection: `column`
}}>
<i style={{fontSize: '14px'}}>
{cast.character}
</i>
<a href={cast.actorUrl} style={{fontSize: '14px'}}>
{cast.actorName}
</a>
</div>
</div>
);
})
}
</div>
</>
)}
</div>
</div>
</div>
{
movie.parent &&
<p>
<a href={movie.parent}>Back to Movies</a>
</p>
}
</>
)
}

export default MoviePage;
48 changes: 48 additions & 0 deletions src/components/pagetypes/Person.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from "react"

import styles from "../../styles/Home.module.css";
import {DisplayablePerson} from "../../selectors/propsProcessors/processPerson";


const PersonPage = (person: DisplayablePerson) => {

return (
<>
<div>
<div style={{
display: 'flex',
alignItems: 'baseline'
}}>
<h2>{person.displayName}</h2>
</div>
<div style={{
display: `flex`
}}>
{
// @ts-ignore
person.photo &&
<>
<img src={person.photo.imageUrl}
alt={person.displayName}
className={styles.mainPhoto}/>
</>
}
{
person.bio &&
<p style={{
margin: `0 20px`
}}><i>{person.bio}</i></p>
}
</div>
</div>
{
person.parent &&
<p>
<a href={person.parent}>Back to Persons</a>
</p>
}
</>
)
}

export default PersonPage
8 changes: 6 additions & 2 deletions src/pages/_app.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import '../styles/globals.css'
import type {AppProps} from 'next/app'

import Seo from '../components/blocks/seo'
import Layout from '../components/blocks/layout'
import Head from "next/head";


Expand All @@ -13,8 +15,10 @@ function MyApp({Component, pageProps}: AppProps) {
<base href={pageProps.meta.baseUrl} />
</Head>
}

<Component {...pageProps} />
<Layout siteTitle="Next.js PoC" pageProps={pageProps}>
<Seo title="Poc" siteTitle="NextXP" />
<Component {...pageProps} />
</Layout>
</>
);
}
Expand Down
7 changes: 7 additions & 0 deletions src/selectors/pages.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,16 @@
import { appKey } from '../enonic-connection-config';

// EXAMPLE:
import ListPage from '../components/pagetypes/List';
import PersonPage from '../components/pagetypes/Person';
import MoviePage from '../components/pagetypes/Movie';

// XP content types ('type' from the second data response in fetchContent.ts) mapped to top-level react components that render that content type.
// If content type is not found here, falls back to the default page renderer in pages/Default.tsx
export const pageSelector = {
[`${appKey}:person`]: PersonPage,
[`${appKey}:movie`]: MoviePage,
'base:folder': ListPage
};

export type PageSelector = { [fullContentType:string]: JSX.Element };
8 changes: 7 additions & 1 deletion src/selectors/propsProcessors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,14 +20,20 @@

import { appKey } from '../enonic-connection-config';

export type PropsProcessorFunc = (props: any, requestIsFromXp: boolean) => {}
import {processPersonProps} from "./propsProcessors/processPerson";
import {processFolderProps} from "./propsProcessors/processFolder";
import {processMovieProps} from "./propsProcessors/processMovie";


export type PropsProcessorFunc = (props: any, requestIsFromXp: boolean) => {}

export type PropsProcessorSelector = {
[fullContentType: string]: PropsProcessorFunc
};


export const propsProcessorSelector: PropsProcessorSelector = {
[`${appKey}:person`]: processPersonProps,
[`${appKey}:movie`]: processMovieProps,
'base:folder': processFolderProps,
};
Loading

0 comments on commit 5bcfa68

Please sign in to comment.