In my code I'm using a stepper with three steps first step is to select the template and the next step is to preview the selected template and put user input text on it. In order to get this done I need to pass the value of the selected template from SelectObituaryTemplate.js to PreviewObituary.js.
How can I get this done?
I have put the code for the buttons in the stepper as well -> StepperControl.js
SelectObituaryTemplates.js
import React, { useState } from 'react'
import ObituaryTemplateCard from '../ObituaryTemplateCard'
const SelectObituaryTemplates = () => {
const [selectedTemplate, setSelectedTemplate] = useState(null);
const handleSelectTemplate = (template) => {
setSelectedTemplate(template);
}
return (
<section className='bg-white'>
<div className='container px-6 py-10 mx-auto'>
<h1 className='text-2xl font-semibold text-center text-gray-800 capitalize lg:text-3xl'>
Obituary Templates
</h1>
<div className='grid grid-cols-1 gap-8 mt-8 xl:mt-12 xl:gap-12 lg:grid-cols-2'>
<ObituaryTemplateCard
template={{
previewTemplateUrl: require("../../assets/obituary_templates/carnations_preview_template.png"),
blankTemplateUrl: require("../../assets/obituary_templates/carnations_blank_template.png")
}}
isSelected={selectedTemplate === 'carnations'}
onSelect={() => handleSelectTemplate('carnations')}
/>
<ObituaryTemplateCard
template={{
previewTemplateUrl: require("../../assets/obituary_templates/rose_preview_template.png"),
blankTemplateUrl: require("../../assets/obituary_templates/rose_blank_template.png")
}}
isSelected={selectedTemplate === 'rose'}
onSelect={() => handleSelectTemplate('rose')}
/>
</div>
</div>
</section>
)
}
export default SelectObituaryTemplates
CreateObituary.js
import React from 'react'
import { useState } from 'react'
import Stepper from '../components/Stepper'
import StepperControl from '../components/StepperControl'
import { UseContextProvider } from '../contexts/StepperContext'
import PreviewObituary from '../components/steps/PreviewObituary'
import SelectObituaryTemplate from '../components/steps/SelectObituaryTemplate'
import ShareObituary from '../components/steps/ShareObituary'
const CreateObituary = ({selectedTemplate}) => {
const [currentStep, setCurrentStep] = useState(1)
const steps = ['Select Obituary Template', 'Details of the Deceased', 'Preview']
const displayStep = (step) => {
switch (step) {
case 1:
return <SelectObituaryTemplate />
case 2:
return <PreviewObituary selectedTemplate={selectedTemplate} />
case 3:
return <ShareObituary />
default:
}
}
const handleClick = (direction) => {
let newStep = currentStep
direction === 'next' ? newStep++ : newStep--
// check if steps are within bounds
newStep > 0 && newStep <= steps.length && setCurrentStep(newStep)
}
return (
<div className='mx-auto rounded-2xl bg-white pb-2 my-6 shadow-xl md:w-3/4'>
{/* Stepper */}
<div className='horizontal container mt-5 '>
<Stepper steps={steps} currentStep={currentStep} />
<div className='my-10 p-10 '>
<UseContextProvider>{displayStep(currentStep)}</UseContextProvider>
</div>
</div>
{/* navigation button */}
{currentStep !== steps.length && (
<StepperControl
handleClick={handleClick}
selectedTemplate={selectedTemplate}
currentStep={currentStep}
steps={steps}
/>
)}
</div>
)
}
export default CreateObituary
PreviewObituary.js
import React, { useState } from 'react'
import CarnationsBlankTemplate from '../../assets/obituary_templates/carnations_blank_template.png'
import RosesBlankTemplate from '../../assets/obituary_templates/rose_blank_template.png'
function PreviewObituary({ selectedTemplate }) {
const [dob, setDob] = useState(null)
const [dod, setDod] = useState(null)
function handleDobChange(event) {
setDob(new Date(event.target.value))
}
function handleDodChange(event) {
setDod(new Date(event.target.value))
}
const [obituaryData, setObituaryData] = React.useState({
firstName: '',
lastName: '',
dateOfBirth: '',
dateOfDeath: '',
})
function handleChange(event) {
const { name, value } = event.target
setObituaryData((prevObituaryData) => ({
...prevObituaryData,
[name]: value,
}))
}
function handleDodCombinedChange(event) {
handleChange(event)
handleDodChange(event)
}
function handleDobCombinedChange(event) {
handleChange(event)
handleDobChange(event)
}
return (
<section className='text-gray-600 body-font'>
<div className='container px-5 py-24 mx-auto flex flex-wrap'>
<div className='flex flex-wrap -m-4'>
<div className='p-4 lg:w-1/2 md:w-full'>
<div className='flex border-2 rounded-lg border-gray-200 border-opacity-50 p-8 sm:flex-row flex-col'>
<div className='flex justify-center items-center gap-4 p-4 sm:p-6 lg:p-8'>
{selectedTemplate === 'carnations' ? (
<img src={CarnationsBlankTemplate} className='w-full' />
) : (
<img src={RosesBlankTemplate} className='w-full' />
)}
</div>
</div>
</div>
<div className='p-4 lg:w-1/2 md:w-full'>
<div className='flex border-2 rounded-lg border-gray-200 border-opacity-50 p-8 sm:flex-row flex-col'>
<form action='' className='mx-auto mb-0 w-full space-y-5'>
<div class='grid grid-cols-1 gap-4 text-center sm:grid-cols-2'>
<div>
<label
for='FirstName'
class='block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-blue-600 focus-within:ring-1 focus-within:ring-blue-600'
>
<span class='text-xs font-medium text-gray-700'>
{' '}
First Name{' '}
</span>
<input
type='text'
placeholder='John'
class='mt-1 w-full border-none p-0 focus:border-transparent focus:outline-none focus:ring-0 sm:text-sm'
name='firstName'
value={obituaryData.firstName}
onChange={handleChange}
/>
</label>
</div>
<div>
<label
for='LastName'
className='block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-blue-600 focus-within:ring-1 focus-within:ring-blue-600'
>
<span class='text-xs font-medium text-gray-700'>
{' '}
Last Name{' '}
</span>
<input
type='text'
placeholder='Doe'
class='mt-1 w-full border-none p-0 focus:border-transparent focus:outline-none focus:ring-0 sm:text-sm'
name='lastName'
value={obituaryData.lastName}
onChange={handleChange}
/>
</label>
</div>
</div>
<div>
<label
for='UserImage'
class='block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-blue-600 focus-within:ring-1 focus-within:ring-blue-600 file:bg-gray-200 file:text-gray-700 file:text-sm file:px-4 file:py-1 file:border-none file:rounded-full'
>
<span class='text-xs font-medium text-gray-700'>
{' '}
Image{' '}
</span>
<input
type='file'
id='UserImage'
className='w-full py-2 mt-2 text-sm text-gray-600 bg-white rounded-lg file:bg-gray-200 file:text-gray-700 file:text-sm file:px-4 file:py-1 file:border-none file:rounded-full'
accept='image/*'
/>
</label>
</div>
<div class='grid grid-cols-1 gap-6 mt-4 sm:grid-cols-2'>
<div>
<label
for='DateOfBirth'
className='block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-blue-600 focus-within:ring-1 focus-within:ring-blue-600'
>
<span class='text-xs font-medium text-gray-700'>
{' '}
Date of Birth{' '}
</span>
<input
type='Date'
class='mt-1 w-full border-none p-0 focus:border-transparent focus:outline-none focus:ring-0 sm:text-sm'
name='dateOfBirth'
value={obituaryData.dateOfBirth}
onChange={handleDobCombinedChange}
/>
</label>
</div>
<div>
<label
for='DateOfDeath'
class='block overflow-hidden rounded-md border border-gray-200 px-3 py-2 shadow-sm focus-within:border-blue-600 focus-within:ring-1 focus-within:ring-blue-600'
>
<span class='text-xs font-medium text-gray-700'>
{' '}
Date of Death{' '}
</span>
<input
type='Date'
class='mt-1 w-full border-none p-0 focus:border-transparent focus:outline-none focus:ring-0 sm:text-sm'
name='dateOfDeath'
value={obituaryData.dateOfDeath}
onChange={handleDodCombinedChange}
/>
</label>
</div>
</div>
<div className='mt-1 -space-y-px bg-white rounded-md shadow-sm'>
<div>
<label htmlFor='Epitaphs' className='sr-only'>
Epitaphs
</label>
<select
id='Epitaphs'
className='relative w-full border-gray-200 rounded-t-md focus:z-10 sm:text-sm'
>
<option>Forever in our hearts</option>
<option>Rest in peace</option>
<option>A life well lived</option>
</select>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
<div>
<h2 className='obituaryText firstName'>{obituaryData.firstName}</h2>
<h2 className='obituaryText lastName'>{obituaryData.lastName}</h2>
{dob && (
<h2 className='obituaryText dateOfBirth'>
{dob.toLocaleDateString('en-US', {
month: 'long',
day: 'numeric',
year: 'numeric',
})}
</h2>
)}
<h2 className='obituaryText'>-</h2>
{dod && (
<h2 className='obituaryText dateOfDeath'>
{dod.toLocaleDateString('en-US', {
month: 'long',
day: 'numeric',
year: 'numeric',
})}
</h2>
)}
</div>
</section>
)
}
export default PreviewObituary
StepperControl.js
export default function StepperControl({ handleClick, currentStep, steps}) {
return (
<div className='container mt-4 mb-8 flex justify-around'>
<button
onClick={() => handleClick()}
className={`cursor-pointer rounded-xl border-2 border-slate-300 bg-white py-2 px-4 font-semibold uppercase text-slate-400 transition duration-200 ease-in-out hover:bg-slate-700 hover:text-white ${
currentStep === 1 ? ' cursor-not-allowed opacity-50 ' : ''
}`}
>
Back
</button>
{currentStep === steps.length - 1 ? (
<button
onClick={() => handleClick('next')}
className='inline-flex w-full items-center justify-center rounded-lg bg-black px-5 py-3 text-white sm:w-auto'
>
Confirm
<svg
xmlns='http://www.w3.org/2000/svg'
class='ml-3 h-5 w-5'
fill='none'
viewBox='0 0 24 24'
stroke='currentColor'
>
<path
stroke-linecap='round'
stroke-linejoin='round'
stroke-width='2'
d='M14 5l7 7m0 0l-7 7m7-7H3'
/>
</svg>
</button>
) : (
<button
onClick={() => handleClick('next')}
className='inline-flex w-full items-center justify-center rounded-lg bg-black px-5 py-3 text-white sm:w-auto'
>
Next
<svg
xmlns='http://www.w3.org/2000/svg'
class='ml-3 h-5 w-5'
fill='none'
viewBox='0 0 24 24'
stroke='currentColor'
>
<path
stroke-linecap='round'
stroke-linejoin='round'
stroke-width='2'
d='M14 5l7 7m0 0l-7 7m7-7H3'
/>
</svg>
</button>
)}
</div>
)
}