Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add variants to Sponsor Listing #383

Merged
merged 1 commit into from
Feb 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -1,19 +1,221 @@
import React from 'react';
import { ComponentParams, ComponentRendering } from '@sitecore-jss/sitecore-jss-nextjs';
import {
ComponentParams,
ComponentRendering,
ImageField,
LinkField,
TextField,
Image as JssImage,
Link as JssLink,
RichText as JssRichText,
Text as JssText,
RichTextField,
} from '@sitecore-jss/sitecore-jss-nextjs';
import {
Flex,
Heading,
Image,
Stack,
Link as ChakraLink,
Card,
CardHeader,
CardBody,
Alert,
AlertIcon,
Box,
Button,
useDisclosure,
Modal,
ModalOverlay,
ModalContent,
ModalCloseButton,
ModalBody,
HStack,
} from '@chakra-ui/react';

interface SponsorListingProps {
rendering: ComponentRendering & { params: ComponentParams };
params: ComponentParams;
fields: Fields;
}

interface Fields {
Title: TextField;
Sponsors: Sponsor[];
}

type SponsorListingWrapperProps = SponsorListingProps & {
children: React.ReactNode | React.ReactNode[];
};

type Sponsor = {
fields: {
SponsorName: TextField;
SponsorLogo: ImageField;
SponsorBio: RichTextField;
SponsorURL: LinkField;
};
};

export const Default = (props: SponsorListingProps): JSX.Element => {
const id = props.params.RenderingIdentifier;

return (
<div className={`component ${props.params.styles}`} id={id ? id : undefined}>
<div className="component-content">
<p>SponsorListing Component</p>
<Alert status="warning">
<AlertIcon />
No variant selected for SponsorListing component
</Alert>
</div>
</div>
);
};
/**
* Wrapper component for the SponsorListing component.
* The inner content of the wrapper depends on the variant.
* @param {SponsorListingWrapperProps} props - Props for the SponsorListingWrapper component.
* @returns {JSX.Element} The rendered SponsorListingWrapper component.
*/
const SponsorListingWrapper = (props: SponsorListingWrapperProps): JSX.Element => {
const id = props.params.RenderingIdentifier;

return (
<div className={`component ${props.params.styles}`} id={id ? id : undefined}>
<div className="component-content">
<Box w={{ base: '100vw', md: '80vw' }} my="20" mx={{ base: '20px', md: 'auto' }}>
<Card variant={'unstyled'}>
<CardHeader>
{/* Rendering Title if it exists */}
{props.fields.Title && (
<Heading as={'h1'} size={'xl'}>
{/* Rendering Title with JssText component */}
<JssText field={props.fields.Title} />
</Heading>
)}
</CardHeader>
<CardBody as={Flex}>
{/* Rendering children components */}
<Stack
direction={{ base: 'column', md: 'row' }}
gap={32}
justifyContent={'space-between'}
w={'full'}
>
{props.children}
</Stack>
</CardBody>
</Card>
</Box>
</div>
</div>
);
};

/**
* FullDetails Variant
*
* This function renders a detailed listing of sponsors with their logos, names, bios, and URLs.
* If no sponsor fields are provided, it renders a default view.
*
* @param props - SponsorListingProps object containing fields for rendering sponsor details.
* @returns A JSX Element representing the detailed listing of sponsors or a default view.
*/
export const FullDetails = (props: SponsorListingProps): JSX.Element => {
// Check if sponsor fields are provided
if (props.fields) {
return (
// Render sponsor listing wrapper with provided props
<SponsorListingWrapper {...props}>
{/* Map through each sponsor and render their details */}
{props.fields.Sponsors.map((sponsor, index) => (
<Stack gap={8} key={index}>
{/* Render sponsor logo */}
<Image as={JssImage} field={sponsor.fields.SponsorLogo} />

{/* Render sponsor name */}
<Heading as={'h2'} size={'lg'}>
<JssText field={sponsor.fields.SponsorName} />
</Heading>

{/* Render sponsor bio */}
<JssRichText field={sponsor.fields.SponsorBio} />

{/* Render sponsor URL as a link */}
<ChakraLink as={JssLink} field={sponsor.fields.SponsorURL}>
Visit sponsor site
</ChakraLink>
</Stack>
))}
</SponsorListingWrapper>
);
}

// If no sponsor fields are provided, render default view
return <Default {...props} />;
};

/**
* LogoOnly Variant
* Rendering variant that displays sponsor logos only, and optionally provides a modal for each logo.
* @param {SponsorListingProps} props - Props object containing data and configurations for the component.
* @returns {JSX.Element} - Returns JSX element representing the LogoOnly component.
*/
export const LogoOnly = (props: SponsorListingProps): JSX.Element => {
const { isOpen, onOpen, onClose } = useDisclosure();

// If props contain fields data, render sponsor logos
if (props.fields) {
return (
<SponsorListingWrapper {...props}>
{props.fields.Sponsors.map((sponsor, index) => (
<React.Fragment key={index}>
{/* Render sponsor logo as a button */}
<Button onClick={onOpen} variant="unstyled">
<JssImage field={sponsor.fields.SponsorLogo} />
</Button>

{/* Render modal for the sponsor */}
{RenderModal(isOpen, onClose, sponsor)}
</React.Fragment>
))}
</SponsorListingWrapper>
);
}

// If props do not contain fields data, render default component
return <Default {...props} />;
};

/**
* Renders a modal component displaying information about a sponsor.
* @param isOpen - A boolean indicating whether the modal is open or closed.
* @param onClose - A function to be called when the modal is closed.
* @param sponsor - An object representing the sponsor's details.
* @returns A modal component displaying sponsor information.
*/
function RenderModal(isOpen: boolean, onClose: () => void, sponsor: Sponsor) {
return (
<Modal isOpen={isOpen} onClose={onClose} size={'6xl'} isCentered>
<ModalOverlay />

<ModalContent>
<ModalCloseButton size="lg" />
<ModalBody p="8">
<HStack>
<JssImage field={sponsor.fields.SponsorLogo} width="1024" />
<Stack gap={8}>
<Heading as={'h2'} size={'lg'}>
<JssText field={sponsor.fields.SponsorName} />
</Heading>
<JssRichText field={sponsor.fields.SponsorBio} />
<ChakraLink as={JssLink} field={sponsor.fields.SponsorURL}>
Visit sponsor site
</ChakraLink>
</Stack>
</HStack>
</ModalBody>
</ModalContent>
</Modal>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
ID: "28203ebd-4849-411c-8b5d-f3e5503e7181"
Parent: "aa2a6eac-c634-4f7d-88d6-847f24c2574d"
Template: "49c111d0-6867-4798-a724-1f103166e6e9"
Path: /sitecore/content/Sugcon2024/EU/Presentation/Headless Variants/Sponsor Listing
SharedFields:
- ID: "087c0553-9162-41f5-98d3-87eb0d80edbb"
Hint: Compatible Renderings
Value: "{25D85B6B-D6A8-411F-89A4-A99C0B8EEA39}"
Languages:
- Language: en
Versions:
- Version: 1
Fields:
- ID: "25bed78c-4957-4165-998a-ca1b52f67497"
Hint: __Created
Value: 20240229T081034Z
- ID: "52807595-0f8f-4b20-8d2a-cb71d28c6103"
Hint: __Owner
Value: |
sitecore\Mark van Aalst
- ID: "5dd74568-4d4b-44c1-b513-0af5f4cda34f"
Hint: __Created by
Value: |
sitecore\Mark van Aalst
- ID: "8cdc337e-a112-42fb-bbb4-4143751e123f"
Hint: __Revision
Value: "9fd9155e-911c-4084-9e49-8f789f7ee3ef"
- ID: "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a"
Hint: __Updated by
Value: |
sitecore\Mark van Aalst
- ID: "d9cf14b1-fa16-4ba6-9288-e8a174d4d522"
Hint: __Updated
Value: 20240229T081113Z
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
ID: "e9201f4a-fd1f-438c-85f9-93f3892d300b"
Parent: "28203ebd-4849-411c-8b5d-f3e5503e7181"
Template: "4d50cdae-c2d9-4de8-b080-8f992bfb1b55"
Path: /sitecore/content/Sugcon2024/EU/Presentation/Headless Variants/Sponsor Listing/FullDetails
SharedFields:
- ID: "ba3f86a2-4a1c-4d78-b63d-91c2779c1b5e"
Hint: __Sortorder
Value: 100
Languages:
- Language: en
Versions:
- Version: 1
Fields:
- ID: "25bed78c-4957-4165-998a-ca1b52f67497"
Hint: __Created
Value: 20240229T081117Z
- ID: "52807595-0f8f-4b20-8d2a-cb71d28c6103"
Hint: __Owner
Value: |
sitecore\Mark van Aalst
- ID: "5dd74568-4d4b-44c1-b513-0af5f4cda34f"
Hint: __Created by
Value: |
sitecore\Mark van Aalst
- ID: "8cdc337e-a112-42fb-bbb4-4143751e123f"
Hint: __Revision
Value: "fd6024a7-71e9-4ef2-9fe3-351a0d993a31"
- ID: "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a"
Hint: __Updated by
Value: |
sitecore\Mark van Aalst
- ID: "d9cf14b1-fa16-4ba6-9288-e8a174d4d522"
Hint: __Updated
Value: 20240229T101828Z
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
---
ID: "e907f4d9-e6f7-4bec-81c2-45516ec1ef6f"
Parent: "28203ebd-4849-411c-8b5d-f3e5503e7181"
Template: "4d50cdae-c2d9-4de8-b080-8f992bfb1b55"
Path: /sitecore/content/Sugcon2024/EU/Presentation/Headless Variants/Sponsor Listing/LogoOnly
SharedFields:
- ID: "ba3f86a2-4a1c-4d78-b63d-91c2779c1b5e"
Hint: __Sortorder
Value: 400
Languages:
- Language: en
Versions:
- Version: 1
Fields:
- ID: "25bed78c-4957-4165-998a-ca1b52f67497"
Hint: __Created
Value: 20240229T081117Z
- ID: "52807595-0f8f-4b20-8d2a-cb71d28c6103"
Hint: __Owner
Value: |
sitecore\Mark van Aalst
- ID: "5dd74568-4d4b-44c1-b513-0af5f4cda34f"
Hint: __Created by
Value: |
sitecore\Mark van Aalst
- ID: "8cdc337e-a112-42fb-bbb4-4143751e123f"
Hint: __Revision
Value: "702292b1-da2d-4e4a-9a7a-79e278ac8623"
- ID: "badd9cf9-53e0-4d0c-bcc0-2d784c282f6a"
Hint: __Updated by
Value: |
sitecore\Mark van Aalst
- ID: "d9cf14b1-fa16-4ba6-9288-e8a174d4d522"
Hint: __Updated
Value: 20240229T101838Z
Loading