Skip to content

feat: update Next.js generator style with tailwind #348

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

Merged
merged 3 commits into from
Dec 2, 2022
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
69 changes: 47 additions & 22 deletions templates/next/components/common/Pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,28 +17,53 @@ const Pagination = ({ collection }: Props) => {
} = view;

return (
<nav aria-label="Page navigation">
<Link href={first ? first : '#'}>
<a className={`btn btn-primary${previous ? '' : ' disabled'}`} aria-label="First page">
<span aria-hidden="true">&lArr;</span> First
</a>
</Link>
<Link href={previous ? previous : '#'}>
<a className={`btn btn-primary${previous ? '' : ' disabled'}`} aria-label="Previous page">
<span aria-hidden="true">&larr;</span> Previous
</a>
</Link>
<Link href={next ? next : '#'}>
<a className={`btn btn-primary${next ? '' : ' disabled'}`} aria-label="Next page">
Next <span aria-hidden="true">&rarr;</span>
</a>
</Link>
<Link href={last ? last : '#'}>
<a className={`btn btn-primary${next ? '' : ' disabled'}`} aria-label="Last page">
Last <span aria-hidden="true">&rArr;</span>
</a>
</Link>
</nav>
<div className="text-center">
<nav
className="text-xs font-bold inline-flex mx-auto divide-x-2 divide-gray-200 flex-row flex-wrap items-center justify-center mb-4 border-2 border-gray-200 rounded-2xl overflow-hidden"
aria-label="Page navigation"
>
<Link href={first ? first : "#"}>
<a
className={`text-black p-3 hover:text-cyan-500 hover:bg-cyan-50 ${
previous ? "" : " text-gray-500 pointer-events-none"
}`}
aria-label="First page"
>
<span aria-hidden="true">&lArr;</span> First
</a>
</Link>
<Link href={previous ? previous : "#"}>
<a
className={`text-black p-3 hover:text-cyan-500 hover:bg-cyan-50 ${
previous ? "" : " text-gray-500 pointer-events-none"
}`}
aria-label="Previous page"
>
<span aria-hidden="true">&larr;</span> Previous
</a>
</Link>
<Link href={next ? next : "#"}>
<a
className={`text-black p-3 hover:text-cyan-500 hover:bg-cyan-50 ${
next ? "" : " text-gray-500 pointer-events-none"
}`}
aria-label="Next page"
>
Next <span aria-hidden="true">&rarr;</span>
</a>
</Link>
<Link href={last ? last : "#"}>
<a
className={`text-black p-3 hover:text-cyan-500 hover:bg-cyan-50 ${
next ? "" : "text-gray-500 pointer-events-none"
}`}
aria-label="Last page"
>
Last <span aria-hidden="true">&rArr;</span>
</a>
</Link>
</nav>
</div>
);
};

Expand Down
2 changes: 1 addition & 1 deletion templates/next/components/common/ReferenceLinks.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ const ReferenceLinks: FunctionComponent<Props> = ({ items }) => {

return (
<Link href={typeof items === "string" ? items : items.href}>
<a>
<a className="text-cyan-700 font-bold">
{typeof items === "string" ? items : items.name}
</a>
</Link>
Expand Down
40 changes: 23 additions & 17 deletions templates/next/components/foo/Form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -50,8 +50,15 @@ export const Form: FunctionComponent<Props> = ({ {{{lc}}} }) => {
};

return (
<div>
<h1>{ {{{lc}}} ? `Edit {{{ucf}}} ${ {{~lc}}['@id']}` : `Create {{{ucf}}}` }</h1>
<div className="container mx-auto px-4 max-w-2xl mt-4">
<Link href="/{{{lc}}}s">
<a className="text-sm text-cyan-500 font-bold hover:text-cyan-700">
{`< Back to list`}
</a>
</Link>
<h1 className="text-3xl my-2">
{ {{{lc}}} ? `Edit {{{ucf}}} ${ {{~lc}}['@id']}` : `Create {{{ucf}}}` }
</h1>
<Formik
initialValues={
{{lc}} ?
Expand Down Expand Up @@ -110,15 +117,15 @@ export const Form: FunctionComponent<Props> = ({ {{{lc}}} }) => {
handleSubmit,
isSubmitting,
}) => (
<form onSubmit={handleSubmit}>
<form className="shadow-md p-4" onSubmit={handleSubmit}>
{{#each formFields}}
<div className="form-group">
<div className="mb-2">
{{#if isRelations}}
<div className="form-control-label">{{name}}</div>
<div className="text-gray-700 block text-sm font-bold">{{name}}</div>
<FieldArray
name="{{name}}"
render={(arrayHelpers) => (
<div id="{{../lc}}_{{name}}">
<div className="mb-2" id="{{../lc}}_{{name}}">
{values.{{name}} && values.{{name}}.length > 0 ? (
values.{{name}}.map((item: any, index: number) => (
<div key={index}>
Expand Down Expand Up @@ -146,7 +153,7 @@ export const Form: FunctionComponent<Props> = ({ {{{lc}}} }) => {
)}
/>
{{else}}
<label className="form-control-label" htmlFor="{{../lc}}_{{name}}">{{name}}</label>
<label className="text-gray-700 block text-sm font-bold" htmlFor="{{../lc}}_{{name}}">{{name}}</label>
<input
name="{{name}}"
id="{{../lc}}_{{name}}"
Expand All @@ -160,13 +167,13 @@ export const Form: FunctionComponent<Props> = ({ {{{lc}}} }) => {
{{#if step}}step="{{{step}}}"{{/if}}
placeholder="{{{description}}}"
{{#if required}}required={true}{{/if}}
className={`form-control${errors.{{name}} && touched.{{name}} ? ' is-invalid' : ''}`}
className={`mt-1 block w-full ${errors.{{name}} && touched.{{name}} ? 'border-red-500' : ''}`}
aria-invalid={errors.{{name}} && touched.{{name~}} ? 'true' : undefined}
onChange={handleChange}
onBlur={handleBlur}
/>
<ErrorMessage
className="invalid-feedback"
className="text-xs text-red-500 pt-1"
component="div"
name="{{name}}"
/>
Expand All @@ -175,8 +182,8 @@ export const Form: FunctionComponent<Props> = ({ {{{lc}}} }) => {
{{/each}}
{status && status.msg && (
<div
className={`alert ${
status.isValid ? "alert-success" : "alert-danger"
className={`border px-4 py-3 my-4 rounded ${
status.isValid ? "text-cyan-700 border-cyan-500 bg-cyan-200/50" : "text-red-700 border-red-400 bg-red-100"
}`}
role="alert"
>
Expand All @@ -185,22 +192,21 @@ export const Form: FunctionComponent<Props> = ({ {{{lc}}} }) => {
)}
<button
type="submit"
className="btn btn-success"
className="inline-block mt-2 bg-cyan-500 hover:bg-cyan-700 text-sm text-white font-bold py-2 px-4 rounded"
disabled={isSubmitting}
>
Submit
</button>
</form>
)}
</Formik>
<Link href="/{{{lc}}}s">
<a className="btn btn-primary">Back to list</a>
</Link>
<div className="flex space-x-2 mt-4 justify-end">
{ {{{lc}}} && (
<button className="btn btn-danger" onClick={handleDelete}>
<a>Delete</a>
<button className="inline-block mt-2 border-2 border-red-400 hover:border-red-700 hover:text-red-700 text-sm text-red-400 font-bold py-2 px-4 rounded" onClick={handleDelete}>
Delete
</button>
)}
</div>
</div>
);
};
46 changes: 28 additions & 18 deletions templates/next/components/foo/List.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,25 +10,29 @@ interface Props {
}

export const List: FunctionComponent<Props> = ({ {{{lc}}}s }) => (
<div>
<h1>{{{ucf}}} List</h1>
<Link href="/{{{lc}}}s/create">
<a className="btn btn-primary">Create</a>
</Link>
<table className="table table-responsive table-striped table-hover">
<thead>
<div className="p-4">
<div className="flex justify-between items-center">
<h1 className="text-3xl mb-2">{{{ucf}}} List</h1>
<Link href="/{{{lc}}}s/create">
<a className="bg-cyan-500 hover:bg-cyan-700 text-white text-sm font-bold py-2 px-4 rounded">
Create
</a>
</Link>
</div>
<table cellPadding={10} className="shadow-md table border-collapse min-w-full leading-normal table-auto text-left my-3">
<thead className="w-full text-xs uppercase font-light text-gray-700 bg-gray-200 py-2 px-4">
<tr>
<th>id</th>
{{#each fields}}
<th>{{name}}</th>
{{/each}}
<th/>
<th colSpan={2} />
</tr>
</thead>
<tbody>
<tbody className="text-sm divide-y divide-gray-200">
{ {{{lc}}}s && ({{{lc}}}s.length !== 0) && {{{lc}}}s.map( ( {{{lc}}} ) => (
{{{lc}}}['@id'] &&
<tr key={ {{{lc}}}['@id'] }>
<tr className="py-2" key={ {{{lc}}}['@id'] }>
<th scope="row">
<ReferenceLinks items={ { href: getPath({{{lc}}}['@id'], '/{{{lc}}}s/[id]'), name: {{{lc}}}['@id'] } } />
</th>
Expand All @@ -49,19 +53,25 @@ export const List: FunctionComponent<Props> = ({ {{{lc}}}s }) => (
{{/if}}
</td>
{{/each}}
<td>
<td className="w-8">
<Link href={ getPath({{{lc}}}['@id'], '/{{{lc}}}s/[id]') }>
<a>
<i className="bi bi-search" aria-hidden="true"></i>
<span className="sr-only">Show</span>
<a className="text-cyan-500">
Show
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" className="w-6 h-6">
<path d="M12 15a3 3 0 100-6 3 3 0 000 6z" />
<path fillRule="evenodd" d="M1.323 11.447C2.811 6.976 7.028 3.75 12.001 3.75c4.97 0 9.185 3.223 10.675 7.69.12.362.12.752 0 1.113-1.487 4.471-5.705 7.697-10.677 7.697-4.97 0-9.186-3.223-10.675-7.69a1.762 1.762 0 010-1.113zM17.25 12a5.25 5.25 0 11-10.5 0 5.25 5.25 0 0110.5 0z" clipRule="evenodd" />
</svg>
</a>
</Link>
</td>
<td>
<td className="w-8">
<Link href={ getPath({{{lc}}}["@id"], '/{{{lc}}}s/[id]/edit') }>
<a>
<i className="bi bi-pen" aria-hidden="true" />
<span className="sr-only">Edit</span>
<a className="text-cyan-500">
Edit
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor" className="w-6 h-6">
<path d="M21.731 2.269a2.625 2.625 0 00-3.712 0l-1.157 1.157 3.712 3.712 1.157-1.157a2.625 2.625 0 000-3.712zM19.513 8.199l-3.712-3.712-8.4 8.4a5.25 5.25 0 00-1.32 2.214l-.8 2.685a.75.75 0 00.933.933l2.685-.8a5.25 5.25 0 002.214-1.32l8.4-8.4z" />
<path d="M5.25 5.25a3 3 0 00-3 3v10.5a3 3 0 003 3h10.5a3 3 0 003-3V13.5a.75.75 0 00-1.5 0v5.25a1.5 1.5 0 01-1.5 1.5H5.25a1.5 1.5 0 01-1.5-1.5V8.25a1.5 1.5 0 011.5-1.5h5.25a.75.75 0 000-1.5H5.25z" />
</svg>
</a>
</Link>
</td>
Expand Down
39 changes: 24 additions & 15 deletions templates/next/components/foo/Show.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,20 +30,25 @@ export const Show: FunctionComponent<Props> = ({ {{{lc}}}, text }) => {
};

return (
<div>
<div className="p-4">
<Head>
<title>{`Show {{{ucf}}} ${ {{~lc}}['@id']}`}</title>
<script type="application/ld+json" dangerouslySetInnerHTML={ { __html: text } } />
</Head>
<h1>{`Show {{{ucf}}} ${ {{~lc}}['@id']}`}</h1>
<table className="table table-responsive table-striped table-hover">
<thead>
<Link href="/{{{lc}}}s">
<a className="text-sm text-cyan-500 font-bold hover:text-cyan-700">
{`< Back to list`}
</a>
</Link>
<h1 className="text-3xl mb-2">{`Show {{{ucf}}} ${ {{~lc}}['@id']}`}</h1>
<table cellPadding={10} className="shadow-md table border-collapse min-w-full leading-normal table-auto text-left my-3">
<thead className="w-full text-xs uppercase font-light text-gray-700 bg-gray-200 py-2 px-4">
<tr>
<th>Field</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tbody className="text-sm divide-y divide-gray-200">
{{#each fields}}
<tr>
<th scope="row">{{name}}</th>
Expand All @@ -67,19 +72,23 @@ export const Show: FunctionComponent<Props> = ({ {{{lc}}}, text }) => {
</tbody>
</table>
{error && (
<div className="alert alert-danger" role="alert">
<div className="border px-4 py-3 my-4 rounded text-red-700 border-red-400 bg-red-100" role="alert">
{error}
</div>
)}
<Link href="/{{{lc}}}s">
<a className="btn btn-primary">Back to list</a>
</Link>{" "}
<Link href={getPath({{{lc}}}["@id"], '/{{{lc}}}s/[id]/edit')}>
<a className="btn btn-warning">Edit</a>
</Link>
<button className="btn btn-danger" onClick={handleDelete}>
Delete
</button>
<div className="flex space-x-2 mt-4 items-center justify-end">
<Link href={getPath({{{lc}}}["@id"], '/{{{lc}}}s/[id]/edit')}>
<a className="inline-block mt-2 border-2 border-cyan-500 bg-cyan-500 hover:border-cyan-700 hover:bg-cyan-700 text-xs text-white font-bold py-2 px-4 rounded">
Edit
</a>
</Link>
<button
className="inline-block mt-2 border-2 border-red-400 hover:border-red-700 hover:text-red-700 text-xs text-red-400 font-bold py-2 px-4 rounded"
onClick={handleDelete}
>
Delete
</button>
</div>
</div>
);
};
2 changes: 1 addition & 1 deletion tests/create.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,5 +16,5 @@ test('resource create', async ({ page, queries: { getByLabelText, getByRole, get
await expect(getByText('reviews')).toBeVisible();

await expect(getByRole('button', { name: 'Submit' })).toBeVisible();
await expect(getByRole('link', { name: 'Back to list' })).toBeVisible();
await expect(getByRole('link', { name: /Back to list/ })).toBeVisible();
});
2 changes: 1 addition & 1 deletion tests/edit.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,5 @@ test('resource edit', async ({ page, within, queries: { getAllByRole, getByLabel

await expect(getByRole('button', { name: 'Submit' })).toBeVisible();
await expect(getByRole('button', { name: 'Delete' })).toBeVisible();
await expect(getByRole('link', { name: 'Back to list' })).toBeVisible();
await expect(getByRole('link', { name: /Back to list/ })).toBeVisible();
});
2 changes: 1 addition & 1 deletion tests/show.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ test('resource show', async ({ page, within, queries: { getAllByRole, getByRole,

await expect(getByRoleWithinRow('rowheader')).toHaveText('isbn');

await expect(getByRole('link', { name: 'Back to list' })).toBeVisible();
await expect(getByRole('link', { name: /Back to list/ })).toBeVisible();
await expect(getByRole('link', { name: 'Edit' })).toBeVisible();
await expect(getByRole('button', { name: 'Delete' })).toBeVisible();
});