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

Dev #45

Merged
merged 4 commits into from
May 25, 2023
Merged

Dev #45

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
17 changes: 6 additions & 11 deletions .eslintrc.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
/** @type {import('@types/eslint').Linter.BaseConfig} */
module.exports = {
extends: [
"@remix-run/eslint-config",
"@remix-run/eslint-config/node",
"@remix-run/eslint-config/jest-testing-library",
"prettier",
],
extends: ["@remix-run/eslint-config", "@remix-run/eslint-config/node", "@remix-run/eslint-config/jest-testing-library", "prettier", "plugin:storybook/recommended", "plugin:storybook/recommended"],
env: {
"cypress/globals": true,
"cypress/globals": true
},
plugins: ["cypress"],
// We're using vitest which has a very similar API to jest
// (so the linting plugins work nicely), but we have to
// set the jest version explicitly.
settings: {
jest: {
version: 28,
},
},
};
version: 28
}
}
};
38 changes: 38 additions & 0 deletions .storybook/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import type { StorybookConfig } from "@storybook/react-vite";
import path from "path";

const config: StorybookConfig = {
stories: ["../app/components/**/*.stories.@(js|ts|jsx|tsx)"],
addons: [
"@storybook/addon-links",
"@storybook/addon-essentials",
"@storybook/addon-interactions",
"@storybook/addon-actions",
"@storybook/addon-styling",
"@storybook/addon-console",
],
framework: {
name: "@storybook/react-vite",
options: {},
},
docs: {
autodocs: "tag",
},
viteFinal: async (config) => {
return {
...config,
define: {
"process.env": process.env,
},
resolve: {
alias: [
{
find: "~",
replacement: path.resolve(__dirname, "../app"),
},
],
},
};
},
};
export default config;
19 changes: 19 additions & 0 deletions .storybook/preview.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { Preview } from "@storybook/react";
import "../app/styles/tailwind.css";
import "@storybook/addon-console";
import { withConsole } from "@storybook/addon-console";

const preview: Preview = {
parameters: {
actions: { argTypesRegex: "^on[A-Z].*" },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
},
decorators: [(storyFn, context) => withConsole()(storyFn)(context)],
};

export default preview;
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@

## Database

This project uses sqlite to store data. Anytime you change the `prisma/schema.prisma` file you must run `npm run migrate` to migrate the changes to the actual database. (**Note**, _you may also need to run this command when installing new Cypress packages_)
This project uses Postgresql to store data. Anytime you change the `prisma/schema.prisma` file you must run `npm run migrate` to migrate the changes to the actual database. (**Note**, _you may also need to run this command when installing new Cypress packages_)

### Connecting to the database

Expand Down
3 changes: 1 addition & 2 deletions app/components/Comments/Comment/Comment.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type { user } from "@prisma/client";
import { useFetcher } from "@remix-run/react";
import React, { ChangeEvent, useEffect, useRef, useState } from "react";
import LikeForm from "~/components/Form/LikeForm";
import React, { useEffect, useRef, useState } from "react";
import EditIcon from "~/components/Icons/EditIcon";
import HeartIcon from "~/components/Icons/HeartIcon";
import ReplyIcon from "~/components/Icons/ReplyIcon";
Expand Down
2 changes: 1 addition & 1 deletion app/components/Form/BottleForm/BottleForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ export default function BottleForm({
imageIsSubmitting={imageIsSubmitting}
/>
<Form method="post" className="flex flex-col">
<div className="my-3 -mx-3 mb-6 flex w-full flex-wrap p-2 sm:p-7 lg:w-2/3">
<div className="-mx-3 my-3 mb-6 flex w-full flex-wrap p-2 sm:p-7 lg:w-2/3">
{submissionSuccessful ? (
<input
type="hidden"
Expand Down
6 changes: 3 additions & 3 deletions app/components/Form/ConfirmForm/ConfirmForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export default function ConfirmForm({ data }: ConfirmFormProps) {
Details
</h6>
<div className="mx-3 mt-6 flex min-w-[350px] justify-center">
<div className="border-1 my-4 flex flex-col rounded-md border-gray-700 py-4 px-6">
<div className="border-1 my-4 flex flex-col rounded-md border-gray-700 px-6 py-4">
<div className="flex">
<div className="flex flex-col border-r-2">
<div className="my-2 mr-4 pr-4 text-left font-semibold">
Expand Down Expand Up @@ -128,7 +128,7 @@ export default function ConfirmForm({ data }: ConfirmFormProps) {
</Collapsible>
<div className="my-2 text-right">
<Link
className="rounded bg-blue-500 py-2 px-4 text-white hover:bg-blue-600 focus:bg-blue-400"
className="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600 focus:bg-blue-400"
to={`/reviews/new/setting?id=${data?.redisId}`}
>
Edit Your Review
Expand Down Expand Up @@ -197,7 +197,7 @@ export default function ConfirmForm({ data }: ConfirmFormProps) {
</Collapsible>
<div className="my-2 text-right">
<Link
className="rounded bg-blue-500 py-2 px-4 text-white hover:bg-blue-600 focus:bg-blue-400"
className="rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600 focus:bg-blue-400"
to={`/reviews/new/notes?id=${data?.redisId}`}
>
Edit Tasting Notes
Expand Down
120 changes: 120 additions & 0 deletions app/components/Form/LoginForm/LoginForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { type FieldConfig, conform } from "@conform-to/react";
import { Form, Link, useNavigation, useSearchParams } from "@remix-run/react";
import type { Form as ConformForm } from "~/utils/types";

type LoginFormProps = {
accountIdentifier: FieldConfig<any>;
password: FieldConfig<any>;
redirectTo?: string;
form: ConformForm;
};

export default function LoginForm({
accountIdentifier,
password,
redirectTo,
form,
}: LoginFormProps) {
const navigation = useNavigation();
const [searchParams] = useSearchParams();

return (
<Form method="post" className="space-y-6" {...form.props}>
<div>
<label
htmlFor={accountIdentifier.id}
className="block text-sm font-medium text-gray-700"
>
Email or Username
</label>
<div className="mt-1">
<input
autoFocus={true}
aria-invalid={accountIdentifier.error ? true : undefined}
aria-describedby={accountIdentifier.errorId}
className="w-full rounded border border-gray-500 px-2 py-1 text-lg"
{...conform.input(accountIdentifier, { type: "text" })}
/>
{accountIdentifier.error ? (
<div
className="mt-1 w-auto rounded bg-red-200 px-2 py-4 text-red-600 shadow-md"
id={accountIdentifier.errorId}
role="alert"
>
{accountIdentifier.error}
</div>
) : null}
</div>
</div>

<div>
<label
htmlFor={password.id}
className="block text-sm font-medium text-gray-700"
>
Password
</label>
<div className="mt-1">
<input
aria-invalid={password.error ? true : undefined}
aria-describedby={password.errorId}
className="w-full rounded border border-gray-500 px-2 py-1 text-lg"
{...conform.input(password, { type: "password" })}
/>
{password.error ? (
<div
className="mt-1 w-auto rounded bg-red-200 px-2 py-4 text-red-600 shadow-md"
id={password.errorId}
role="alert"
>
{password.error}
</div>
) : null}
</div>
</div>

<input type="hidden" name="redirectTo" value={redirectTo} />
<button
type="submit"
className="w-full rounded bg-blue-500 px-4 py-2 text-white hover:bg-blue-600 focus:bg-blue-400"
disabled={
navigation.state === "submitting" || navigation.state === "loading"
}
aria-disabled={
navigation.state === "submitting" || navigation.state === "loading"
}
>
Log in
</button>
<div className="flex items-center justify-between">
<div className="flex items-center">
<input
id="remember"
name="remember"
type="checkbox"
className="h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
/>
<label
htmlFor="remember"
className="ml-2 block text-sm text-gray-900"
>
Remember me
</label>
</div>
<div className="text-center text-sm text-gray-500">
Don't have an account?{" "}
<Link
prefetch="intent"
className="text-blue-500 underline"
to={{
pathname: "/join",
search: searchParams.toString(),
}}
>
Sign up
</Link>
</div>
</div>
</Form>
);
}
3 changes: 3 additions & 0 deletions app/components/Form/LoginForm/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import LoginForm from "./LoginForm";

export default LoginForm;
58 changes: 58 additions & 0 deletions app/components/Form/RegisterForm/RegisterForm.stories.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { unstable_createRemixStub as createRemixStub } from "@remix-run/testing";
import type { Meta, StoryObj } from "@storybook/react";
import RegisterForm from "./RegisterForm";

const meta: Meta<typeof RegisterForm> = {
title: "components/Form/RegisterForm",
component: RegisterForm,
decorators: [
(Story) => {
const RemixStub = createRemixStub([{ path: "/", element: <Story /> }]);
return <RemixStub />;
},
],
tags: ["autodocs"],
args: {
email: {
id: "email",
name: "email",
errorId: "email-error",
defaultValue: "[email protected]",
},
username: {
id: "username",
name: "username",
errorId: "username-error",
defaultValue: "petereck123",
},
password: {
id: "password",
name: "password",
errorId: "password-error",
defaultValue: "password123",
},
confirmPassword: {
id: "email",
name: "email",
errorId: "email-error",
defaultValue: "password123",
},
},
};

export default meta;

type Story = StoryObj<typeof meta>;

export const Primary: Story = {
render: () => (
<RegisterForm
email={meta.args?.email!}
username={meta.args?.username!}
password={meta.args?.password!}
confirmPassword={meta.args?.confirmPassword!}
searchParams={meta.args?.searchParams!}
form={meta.args?.form!}
/>
),
};
Loading