Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
P
products_lesson_front
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Pavel Mishakov
products_lesson_front
Commits
dab71996
Commit
dab71996
authored
Mar 07, 2023
by
Pavel Mishakov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
lesson 85 done
parent
ff9d2415
Hide whitespace changes
Inline
Side-by-side
Showing
13 changed files
with
161 additions
and
8 deletions
+161
-8
App.tsx
src/App.tsx
+9
-6
productApi.ts
src/api/productApi.ts
+1
-1
Header.module.css
src/components/Header/Header.module.css
+4
-0
Header.tsx
src/components/Header/Header.tsx
+25
-0
ILayoutProps.ts
src/components/Layout/ILayoutProps.ts
+5
-0
Layout.module.css
src/components/Layout/Layout.module.css
+0
-0
Layout.tsx
src/components/Layout/Layout.tsx
+18
-0
ProductForm.module.css
src/components/ProductForm/ProductForm.module.css
+3
-0
ProductForm.tsx
src/components/ProductForm/ProductForm.tsx
+85
-0
index.css
src/index.css
+4
-0
IProduct.ts
src/interfaces/IProduct.ts
+3
-0
IProductDto.ts
src/interfaces/IProductDto.ts
+3
-0
products.slice.ts
src/store/products/products.slice.ts
+1
-1
No files found.
src/App.tsx
View file @
dab71996
...
...
@@ -6,6 +6,9 @@ import Button from 'react-bootstrap/Button';
import
Form
from
'react-bootstrap/Form'
;
import
'bootstrap/dist/css/bootstrap.min.css'
;
import
{
Col
,
Container
,
Row
}
from
"react-bootstrap"
;
import
Layout
from
"./components/Layout/Layout"
;
import
{
Routes
,
Route
}
from
"react-router-dom"
;
import
ProductForm
from
"./components/ProductForm/ProductForm"
;
const
App
=
()
=>
{
...
...
@@ -25,12 +28,12 @@ const App = () => {
},
[])
return
(
<
>
<
h1
>
{
messageProducts
}
</
h1
>
{
JSON
.
stringify
(
products
)
}
<
h1
>
Product by id:
</
h1
>
{
JSON
.
stringify
(
product
)
}
</
>
<
Layout
>
<
Routes
>
<
Route
path=
{
'/'
}
element=
{
<
h1
>
HOME PAGE
</
h1
>
}
/>
<
Route
path=
{
'/add-product'
}
element=
{
<
ProductForm
/>
}
/
>
</
Routes
>
</
Layout
>
)
}
...
...
src/api/productApi.ts
View file @
dab71996
...
...
@@ -35,7 +35,7 @@ class ProductApi {
}
}
public
createProduct
=
async
(
product
:
IProductDto
):
Promise
<
IResponse
>
=>
{
public
createProduct
=
async
(
product
:
FormData
):
Promise
<
IResponse
>
=>
{
try
{
const
response
=
await
instance
.
post
(
`/products`
,
product
)
return
response
.
data
...
...
src/components/Header/Header.module.css
0 → 100644
View file @
dab71996
.Header__link
{
text-decoration
:
none
;
color
:
black
;
}
\ No newline at end of file
src/components/Header/Header.tsx
0 → 100644
View file @
dab71996
import
React
,
{
FunctionComponent
,
ReactElement
}
from
"react"
;
import
{
NavLink
}
from
"react-router-dom"
;
import
styles
from
'./Header.module.css'
const
Header
:
FunctionComponent
=
():
ReactElement
=>
{
return
(
<
header
className=
{
styles
.
Header
}
>
<
NavLink
className=
{
styles
.
Header__link
}
to=
{
'/add-product'
}
>
Add product
</
NavLink
>
<
NavLink
className=
{
styles
.
Header__link
}
to=
{
'/products'
}
>
Products
</
NavLink
>
</
header
>
)
}
export
default
Header
\ No newline at end of file
src/components/Layout/ILayoutProps.ts
0 → 100644
View file @
dab71996
import
{
ReactNode
}
from
"react"
;
export
default
interface
ILayoutProps
{
children
:
ReactNode
}
\ No newline at end of file
src/components/Layout/Layout.module.css
0 → 100644
View file @
dab71996
src/components/Layout/Layout.tsx
0 → 100644
View file @
dab71996
import
React
,
{
FunctionComponent
,
ReactElement
}
from
"react"
;
import
Header
from
"../Header/Header"
;
import
ILayoutProps
from
"./ILayoutProps"
;
import
styles
from
'./Layout.module.css'
const
Layout
:
FunctionComponent
<
ILayoutProps
>
=
(
props
):
ReactElement
=>
{
return
(
<
div
className=
{
styles
.
Layout
}
>
<
Header
/>
<
main
>
{
props
.
children
}
</
main
>
</
div
>
)
}
export
default
Layout
\ No newline at end of file
src/components/ProductForm/ProductForm.module.css
0 → 100644
View file @
dab71996
.ProductForm__fileInput
{
display
:
none
;
}
\ No newline at end of file
src/components/ProductForm/ProductForm.tsx
0 → 100644
View file @
dab71996
import
React
,
{
ChangeEvent
,
FormEvent
,
FunctionComponent
,
ReactElement
,
useState
}
from
"react"
;
import
{
useDispatch
}
from
"react-redux"
;
import
IProductDto
from
"../../interfaces/IProductDto"
;
import
{
createProduct
}
from
"../../store/products/products.slice"
;
import
{
AppDispatch
}
from
"../../store/store"
;
import
styles
from
'./ProductForm.module.css'
const
ProductForm
:
FunctionComponent
=
():
ReactElement
=>
{
const
dispatch
:
AppDispatch
=
useDispatch
()
const
[
product
,
setProduct
]
=
useState
<
IProductDto
>
({
product
:
''
,
price
:
0
,
description
:
''
,
image
:
undefined
})
const
[
fileName
,
setFileName
]
=
useState
<
string
>
(
''
)
const
inputHandler
=
(
e
:
ChangeEvent
<
HTMLInputElement
>
):
void
=>
{
setProduct
(
prevState
=>
{
return
{...
prevState
,
[
e
.
target
.
name
]:
e
.
target
.
value
}
})
console
.
log
(
product
)
}
const
inputFileHandler
=
(
e
:
ChangeEvent
<
HTMLInputElement
>
):
void
=>
{
setProduct
(
prevState
=>
{
return
{...
prevState
,
image
:
e
.
target
.
files
?
e
.
target
.
files
[
0
]
:
undefined
}
})
setFileName
(
e
.
target
.
files
&&
e
.
target
.
files
[
0
]
?
e
.
target
.
files
[
0
].
name
:
''
)
}
const
submitHandler
=
(
e
:
FormEvent
)
=>
{
e
.
preventDefault
()
const
formData
=
new
FormData
()
Object
.
keys
(
product
).
forEach
((
key
:
any
)
=>
{
//@ts-ignore
formData
.
append
(
key
,
product
[
key
])
})
dispatch
(
createProduct
(
formData
))
}
return
(
<
div
className=
{
styles
.
ProductForm
}
>
<
form
onSubmit=
{
submitHandler
}
>
<
input
name=
{
'product'
}
type=
"text"
placeholder=
"Title"
value=
{
product
.
product
}
onChange=
{
inputHandler
}
/>
<
input
name=
{
'price'
}
type=
"number"
placeholder=
"Price"
value=
{
product
.
price
}
onChange=
{
inputHandler
}
/>
<
input
name=
{
'description'
}
type=
"text"
placeholder=
"Description"
value=
{
product
.
description
}
onChange=
{
inputHandler
}
/>
<
label
>
<
input
className=
{
styles
.
ProductForm__fileInput
}
type=
"file"
name=
{
'image'
}
onChange=
{
inputFileHandler
}
/>
<
h2
>
CHOOSE FILE
</
h2
>
<
span
>
{
fileName
}
</
span
>
</
label
>
<
button
>
SEND
</
button
>
</
form
>
</
div
>
)
}
export
default
ProductForm
\ No newline at end of file
src/index.css
View file @
dab71996
...
...
@@ -7,4 +7,8 @@ body {
font-family
:
Inter
,
system-ui
,
Avenir
,
Helvetica
,
Arial
,
sans-serif
;
line-height
:
1.5
;
font-weight
:
400
;
}
.active
{
color
:
red
!important
;
}
\ No newline at end of file
src/interfaces/IProduct.ts
View file @
dab71996
...
...
@@ -4,6 +4,9 @@ export default interface IProduct {
id
:
string
product
:
string
price
:
number
category_id
:
string
brand_id
:
string
description
:
string
suppliers
?:
ISupplier
[]
image
:
string
}
\ No newline at end of file
src/interfaces/IProductDto.ts
View file @
dab71996
...
...
@@ -2,4 +2,7 @@ export default interface IProductDto {
product
:
string
price
:
number
description
:
string
category_id
?:
string
|
null
brand_id
?:
string
|
null
image
?:
File
}
\ No newline at end of file
src/store/products/products.slice.ts
View file @
dab71996
...
...
@@ -23,7 +23,7 @@ export const getProductById = createAppAsyncThunk(
export
const
createProduct
=
createAppAsyncThunk
(
`
${
namespace
}
/createProduct`
,
async
(
product
:
IProductDto
)
=>
{
async
(
product
:
FormData
)
=>
{
return
productApi
.
createProduct
(
product
)
}
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment