-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
8 changed files
with
379 additions
and
27 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { FC } from 'react'; | ||
import { IMember } from '../src/models/Member.js'; | ||
|
||
const MemberCard: FC<{ member: IMember; }> = ({ member }) => { | ||
return ( | ||
<div className='group bg-red-500 rounded-md shadow-lg p-4 w-72 h-72 text-xl'> | ||
<p><span className='font-bold'>Naam:</span> {member.name}</p> | ||
<p><span className='font-bold'>E-mail:</span> {member.email}</p> | ||
<p><span className='font-bold'>Lidnummer:</span> {member.memberId}</p> | ||
<p><span className='font-bold'>Betaalwijze:</span> {member.paymentMethod}</p> | ||
<p><span className='font-bold'>LDC:</span> {member.ldc}</p> | ||
</div> | ||
); | ||
}; | ||
|
||
export default MemberCard; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,223 @@ | ||
import { withIronSessionSsr } from 'iron-session/next'; | ||
import { NextPage } from 'next'; | ||
import { BaseSyntheticEvent, useState } from 'react'; | ||
import { FieldValues, useForm } from 'react-hook-form'; | ||
import Layout from '../../../components/Layout'; | ||
import { useMetaData } from '../../../lib/hooks/useMetaData'; | ||
import { AdminProps } from '../../../src/types/index'; | ||
import { ironOptions } from '../../../src/util/ironConfig'; | ||
import { useRouter } from 'next/router'; | ||
import Toast, { clearMessage } from '../../../components/Toast'; | ||
|
||
const AdminCreateMembers: NextPage<{ user: { email: string, has2faEnabled: boolean; }; }> = ({ user }) => { | ||
const { register, handleSubmit, formState: { errors } } = useForm(); | ||
|
||
const [message, setMessage] = useState<{ | ||
type: 'success' | 'error' | 'info'; | ||
text: string; | ||
}>({ type: 'success', text: '' }); | ||
|
||
const router = useRouter(); | ||
|
||
const onSubmit = async (data: FieldValues, event?: BaseSyntheticEvent): Promise<void> => { | ||
event?.preventDefault(); | ||
|
||
try { | ||
const req = await fetch('/api/members', { | ||
method: 'POST', | ||
headers: { | ||
'Content-Type': 'application/json', | ||
}, | ||
body: JSON.stringify({ | ||
name: data.name, | ||
email: data.email, | ||
paymentMethod: data.paymentmethod, | ||
memberId: data.memberid, | ||
ldc: data.ldc, | ||
}), | ||
}).catch(e => { | ||
console.log(e); | ||
setMessage({ | ||
type: 'error', | ||
text: 'Er was een fout bij het maken van het product.', | ||
}); | ||
}); | ||
|
||
if (req && req.ok) { | ||
setMessage({ | ||
type: 'success', | ||
text: 'Lid succesvol aangemaakt!', | ||
}); | ||
|
||
await router.push('/admin/leden'); | ||
} | ||
} catch (error) { | ||
console.error(error); | ||
setMessage({ | ||
type: 'error', | ||
text: 'Er is een onverwachte fout opgetreden.', | ||
}); | ||
|
||
clearMessage(setMessage); | ||
} | ||
}; | ||
|
||
return ( | ||
<> | ||
{useMetaData( | ||
'Aesculapia Admin | Webshop', | ||
'Aesculapia Admin | Webshop', | ||
'/admin', | ||
)} | ||
<Layout> | ||
<div className='container relative mb-8'> | ||
<div className='top-10 left-14 sm:left-20'> | ||
<div className='flex flex-wrap w-56 sm:w-96'> | ||
<h1 className='text-5xl pb-2 font-bold text-black'> | ||
Maak een lid. | ||
</h1> | ||
<p className='text-xl text-black'> | ||
Maak een product om op de webshop te verkopen. | ||
</p> | ||
</div> | ||
<div className='flex flex-wrap h-auto text-xl mt-3'> | ||
<form | ||
onSubmit={handleSubmit((data, event) => onSubmit(data, event))} | ||
> | ||
<div className='flex flex-wrap -mx-3'> | ||
<div className='w-full md:w-1/2 px-3 mb-6 md:mb-0'> | ||
<label | ||
className='block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2' | ||
htmlFor='grid-member-name' | ||
> | ||
Naam lid | ||
</label> | ||
<input | ||
className='appearance-none block w-full bg-gray-200 text-gray-700 border border-slate-500 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white' | ||
id='grid-member-name' | ||
type='text' | ||
placeholder='Bob Johnson' | ||
minLength={1} | ||
maxLength={64} | ||
required | ||
{...register('name', { required: true })} | ||
/> | ||
</div> | ||
<div className='w-full md:w-1/2 px-3 mb-6 md:mb-0'> | ||
<label | ||
className='block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2' | ||
htmlFor='grid-member-price' | ||
> | ||
</label> | ||
<input | ||
className='appearance-none block w-full bg-gray-200 text-gray-700 border border-slate-500 rounded py-3 px-4 mb-3 leading-tight focus:outline-none focus:bg-white' | ||
id='grid-member-price' | ||
type='text' | ||
placeholder='[email protected]' | ||
required | ||
{...register('email', { required: true })} | ||
/> | ||
</div> | ||
</div> | ||
<div className='flex flex-wrap -mx-3 mb-2'> | ||
<div className='w-full md:w-1/3 px-3 mb-6 md:mb-0'> | ||
<label | ||
className='block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2' | ||
htmlFor='grid-image-url' | ||
> | ||
Betaalwijze | ||
</label> | ||
<input | ||
className='appearance-none block w-96 bg-gray-200 text-gray-700 border border-slate-500 rounded py-3 px-4 leading-tight focus:outline-none focus:bg-white focus:border-gray-500' | ||
id='grid-image-url' | ||
type='text' | ||
placeholder='bancontact, cash' | ||
minLength={1} | ||
maxLength={1024} | ||
required | ||
{...register('paymentmethod', { required: true })} | ||
/> | ||
</div> | ||
</div> | ||
<div className='flex flex-wrap -mx-3 mb-6'> | ||
<div className='w-full md:w-1/2 px-3 mb-6 md:mb-0'> | ||
<label | ||
className='block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2' | ||
htmlFor='grid-lidnummer' | ||
> | ||
Lidnummer | ||
</label> | ||
<input | ||
className='appearance-none block w-full bg-gray-200 text-gray-700 border-slate-500 rounded py-3 px-4 mb-3 leading-tight border-2 focus:border-rose-500 focus:bg-white' | ||
id='grid-lidnummer' | ||
type='text' | ||
placeholder='#12345' | ||
required | ||
{...register('memberid', { required: true })} | ||
/> | ||
</div> | ||
<div className='w-full md:w-1/2 px-3 mb-6 md:mb-0'> | ||
<label | ||
className='block uppercase tracking-wide text-gray-700 text-xs font-bold mb-2' | ||
htmlFor='grid-ldc' | ||
> | ||
LDC | ||
</label> | ||
<input | ||
className='appearance-none block w-full bg-gray-200 text-gray-700 border-slate-500 rounded py-3 px-4 mb-3 leading-tight border-2 focus:border-rose-500 focus:bg-white' | ||
id='grid-ldc' | ||
type='text' | ||
placeholder='A1232452' | ||
required | ||
{...register('ldc', { required: true })} | ||
/> | ||
</div> | ||
</div> | ||
<div className='pb-9'> | ||
<button className='h-10 px-5 text-red-100 transition-colors duration-150 bg-red-700 rounded-lg focus:shadow-outline hover:bg-red-800'> | ||
<input | ||
className='cursor-pointer' | ||
type='submit' | ||
value='Maak' | ||
></input> | ||
</button> | ||
</div> | ||
</form> | ||
</div> | ||
</div> | ||
</div> | ||
{message.text !== '' && ( | ||
<Toast | ||
type={message.type} | ||
title={message.type[0].toUpperCase() + message.type.slice(1)} | ||
description={message.text} | ||
/> | ||
)} | ||
</Layout> | ||
</> | ||
); | ||
}; | ||
|
||
// eslint-disable-next-line require-await | ||
export const getServerSideProps = withIronSessionSsr(async function ({ req, resolvedUrl }): Promise<AdminProps> { | ||
const user = req?.session.user; | ||
|
||
if (!user) { | ||
return { | ||
props: { | ||
user: { email: '', has2faEnabled: false, completed2fa: false }, | ||
}, | ||
redirect: { | ||
destination: `/admin/login?from=${encodeURIComponent(resolvedUrl)}`, | ||
permanent: false, | ||
}, | ||
}; | ||
} | ||
|
||
return { | ||
props: { user: req.session.user }, | ||
}; | ||
}, ironOptions); | ||
|
||
export default AdminCreateMembers; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
import { withIronSessionSsr } from 'iron-session/next'; | ||
import { NextPage } from 'next'; | ||
import { ironOptions } from '../../../src/util/ironConfig'; | ||
import { AdminProps } from '../../../src/types/index'; | ||
import Layout from '../../../components/Layout'; | ||
import { useMetaData } from '../../../lib/hooks/useMetaData'; | ||
import ErrorPage from '../../../components/Error'; | ||
import { IMember, MemberDocument } from '../../../src/models/Member'; | ||
import MemberCard from '../../../components/MemberCard'; | ||
|
||
interface Props { | ||
data: (IMember & { _id: string; })[]; | ||
} | ||
|
||
const AdminMembersIndex: NextPage<Props> = ({ data }) => { | ||
return ( | ||
<> | ||
{useMetaData('Leden', 'Leden', '/admin/leden')} | ||
<Layout> | ||
{!data && <ErrorPage />} | ||
{data && ( | ||
<div className='container mb-12'> | ||
<div className='my-2'> | ||
<h1 className='text-5xl font-bold mb-5'>Leden</h1> | ||
<button className='h-10 px-5 text-red-100 transition-colors duration-150 bg-red-700 rounded-lg focus:shadow-outline hover:bg-red-900' onClick={(): void => { window.location.href = '/admin/leden/create'; }}> | ||
Lid toevoegen | ||
</button> | ||
</div> | ||
<div className='grid grid-cols-1 place-items-center gap-7 sm:grid-cols-2 md:grid-cols-3'> | ||
{data.map((member, i) => { | ||
return ( | ||
<MemberCard | ||
member={member} | ||
key={i} | ||
/> | ||
); | ||
})} | ||
</div> | ||
</div> | ||
)} | ||
</Layout> | ||
</> | ||
); | ||
}; | ||
|
||
export const getServerSideProps = withIronSessionSsr(async function ({ req, res, resolvedUrl }): Promise<AdminProps<MemberDocument>> { | ||
const user = req?.session.user; | ||
|
||
res?.setHeader( | ||
'Cache-Control', | ||
'public, s-maxage=10, stale-while-revalidate=59', | ||
); | ||
|
||
const request = await fetch(`${process.env.NEXT_PUBLIC_DOMAIN}/api/members`, { | ||
method: 'GET', | ||
headers: { 'Content-Type': 'application/json' }, | ||
}); | ||
|
||
const data = await request.json(); | ||
|
||
if (!user) { | ||
return { | ||
props: { | ||
user: { email: '', has2faEnabled: false, completed2fa: false }, | ||
}, | ||
redirect: { | ||
destination: `/admin/login?from=${encodeURIComponent(resolvedUrl)}`, | ||
permanent: false, | ||
}, | ||
}; | ||
} | ||
|
||
return { | ||
props: { | ||
user: req.session.user, | ||
data: data.data, | ||
}, | ||
}; | ||
}, ironOptions); | ||
|
||
export default AdminMembersIndex; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.