Skip to content
Open
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
24 changes: 24 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*

node_modules
dist
dist-ssr
*.local

# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
.DS_Store
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
1 change: 1 addition & 0 deletions .husky/pre-commit
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
npm run lint:fix
11 changes: 11 additions & 0 deletions .prettierrc.cjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
module.exports = {
printWidth: 100,
tabWidth: 2,
useTabs: false,
semi: true,
singleQuote: true,
endOfLine: 'lf',
importOrder: ['^react(.*)', '@/(.*)', '^[./]'],
importOrderSeparation: true,
plugins: ['@trivago/prettier-plugin-sort-imports'],
};
56 changes: 55 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1 +1,55 @@
# forms
# React Forms Project

## Overview

This project is a form handling application built with React and TypeScript. The application demonstrates two approaches to managing forms: using uncontrolled components and using React Hook Form. Both approaches allow users to submit data, which is then stored in Redux and displayed on the main page.

## Features

- **Three Routes**:

- **Main Page**: Displays submitted data from both forms.
- **Uncontrolled Form**: A form built with traditional uncontrolled components.
- **React Hook Form**: A form using the React Hook Form library for live validation.

- **Form Data Collection**:

- **Name**: Validated for an initial uppercase letter.
- **Age**: Must be a positive number.
- **Email**: Standard email format validation.
- **Passwords**: Password strength validation with matching confirmation.
- **Gender Selection**: Via radio buttons or a select control.
- **Terms and Conditions**: Must be accepted (checkbox).
- **Image Upload**: Supports PNG/JPEG files, with validation, saved as base64.
- **Country Autocomplete**: Select a country from a list stored in Redux.

- **Validation**:

- **Yup** is used for schema-based validation.
- **Uncontrolled Form**: Validation occurs on submit.
- **React Hook Form**: Live validation as you type.

- **State Management**:

- **Redux** is used to store form data and manage application state.

- **User Experience**:
- After successful form submission, the user is redirected to the main page where the newly entered data is highlighted briefly to indicate success.

## Setup and Installation

1. Clone the repository.
2. Install dependencies with `npm install`.
3. Run the application using `npm run dev`.
4. Lint code with `npm run lint` and format with `npm run format:fix`.

## Tools and Libraries

- **React**: UI library.
- **TypeScript**: Ensures type safety.
- **ESLint & Prettier**: Maintain code quality and consistency.
- **Husky**: Ensures linting on pre-commit.
- **React Hook Form**: Simplifies form handling.
- **Yup**: Provides schema-based form validation.
- **Redux Toolkit**: Manages application state.
- **React Router**: Handles navigation between pages.
51 changes: 51 additions & 0 deletions eslint.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import eslintPluginTs from '@typescript-eslint/eslint-plugin';
import eslintParserTs from '@typescript-eslint/parser';
import eslintPluginPrettier from 'eslint-plugin-prettier';
import eslintPluginReact from 'eslint-plugin-react';
import reactHooks from 'eslint-plugin-react-hooks';
import eslintPluginReactRefresh from 'eslint-plugin-react-refresh';
import globals from 'globals';

export default [
{
files: ['**/*.{ts,tsx}'],
ignores: ['dist'],
languageOptions: {
ecmaVersion: 2020,
globals: globals.browser,
parser: eslintParserTs,
},
plugins: {
'@typescript-eslint': eslintPluginTs,
react: eslintPluginReact,
'react-refresh': eslintPluginReactRefresh,
prettier: eslintPluginPrettier,
'react-hooks': reactHooks,
},
settings: {
react: {
version: 'detect',
},
'import/resolver': {
alias: {
map: [['@/', './']],
extensions: ['.ts', '.tsx', '.js', '.jsx', '.sass'],
},
},
},
rules: {
...reactHooks.configs.recommended.rules,
'react-refresh/only-export-components': ['warn', { allowConstantExport: true }],
'no-restricted-imports': [
'error',
{
patterns: ['.*'],
},
],
'@typescript-eslint/no-explicit-any': 'error',
'no-console': ['error', { allow: ['warn', 'error'] }],
'linebreak-style': ['error', 'unix'],
'no-inline-comments': 'error',
},
},
];
13 changes: 13 additions & 0 deletions index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Forms</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/main.tsx"></script>
</body>
</html>
Loading