Skip to content

Commit a472923

Browse files
committed
PC-103: Create Skeleton for Displaying Item Inside Accordion
1 parent 99f7a15 commit a472923

20 files changed

Lines changed: 510 additions & 43 deletions

app/assets/images/icons/note.svg

Lines changed: 4 additions & 0 deletions
Loading

app/assets/images/icons/noted.svg

Lines changed: 4 additions & 0 deletions
Loading

app/assets/stylesheets/application.bootstrap.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,3 +32,4 @@ $utilities: map-merge(
3232
@import "application/items_pricing_page";
3333
@import 'application/accordion.scss';
3434
@import 'application/checkbox.scss';
35+
@import 'application/form_group.scss';

app/assets/stylesheets/application/accordion.scss

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,13 @@
11
.accordion-button {
2-
background-color: $light !important;
3-
border-radius: 8px !important;
4-
border: 1px solid $primary;
52
padding: 22.4px;
3+
border: 1px solid $primary;
4+
border-radius: 8px !important;
5+
background-color: $light !important;
66
transition: border-radius 0.8s ease-out;
77

88
&:not(.collapsed) {
9-
border-radius: 8px 8px 0 0 !important;
109
border-bottom: 1px solid $teal-blue;
10+
border-radius: 8px 8px 0 0 !important;
1111
}
1212
}
1313

@@ -26,5 +26,14 @@
2626
}
2727

2828
.accordion-bottom-filling {
29-
height: 24px;
30-
}
29+
height: 24px;
30+
}
31+
32+
.pc-accordion-quote {
33+
.accordion-button {
34+
padding: 0;
35+
border: transparent;
36+
background-color: $white !important;
37+
}
38+
39+
}
Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
.pc-item-input {
2+
flex: 1 1 auto;
3+
margin-top: 7px; // reserve place for 1/2 height of label with position-absolute
4+
max-width: 200px;
5+
6+
.form-control {
7+
padding: 7px 12px;
8+
width: 100%;
9+
border: none;
10+
border-radius: 4px;
11+
color: $dark;
12+
13+
&:disabled {
14+
background-color: $white;
15+
}
16+
}
17+
18+
.pc-label {
19+
left: 12px;
20+
font-size: 14px;
21+
font-weight: 700;
22+
line-height: 1;
23+
}
24+
25+
.pc-suffix {
26+
position: absolute;
27+
font-size: 14px;
28+
font-weight: 400;
29+
line-height: 1.7;
30+
31+
&-left {
32+
left: 12px;
33+
}
34+
35+
&-right {
36+
right: 12px;
37+
}
38+
}
39+
40+
}
41+
42+
.pc-item-input.price {
43+
.form-control {
44+
padding-left: 24px;
45+
border-top: 1px solid $primary;
46+
color: $secondary;
47+
}
48+
49+
.pc-suffix-left {
50+
color: $secondary;
51+
}
52+
53+
::placeholder {
54+
color: $secondary;
55+
}
56+
}
57+
58+
.pc-item-input.original-cost {
59+
.form-control {
60+
padding-left: 24px;
61+
border-top: 1px solid $primary;
62+
color: $dark;
63+
}
64+
65+
.pc-suffix-left {
66+
color: $dark;
67+
}
68+
69+
::placeholder {
70+
color: $dark;
71+
}
72+
}
73+
74+
.pc-item-input.open-cost {
75+
.form-control {
76+
padding-left: 24px;
77+
border: 1px solid $secondary;
78+
color: $dark
79+
}
80+
81+
.pc-suffix-right {
82+
font-weight: 600;
83+
color: $dark;
84+
}
85+
86+
::placeholder {
87+
color: $dark
88+
}
89+
}
90+
91+
.pc-item-input.discount,
92+
.pc-item-input.notes {
93+
.form-control {
94+
padding-right: 24px;
95+
border: 1px solid $primary;
96+
color: $dark
97+
}
98+
99+
.pc-suffix-right {
100+
font-weight: 600;
101+
color: $secondary;
102+
}
103+
104+
::placeholder {
105+
color: $dark
106+
}
107+
}
108+
109+
.pc-item-input.notes {
110+
max-width: 100%;
111+
112+
// Form.Check component styles for notes
113+
.form-check {
114+
display: flex;
115+
align-items: center;
116+
117+
.form-check-label {
118+
font-size: 14px;
119+
line-height: 1.6;
120+
color: $gray-light;
121+
}
122+
123+
.form-check-input {
124+
margin-top: 0;
125+
margin-right: 5px;
126+
width: 20px;
127+
height: 20px;
128+
border-color: $primary;
129+
cursor: pointer;
130+
131+
&:focus {
132+
box-shadow: none;
133+
}
134+
135+
&:checked {
136+
border-color: $primary;
137+
background-color: $primary;
138+
}
139+
}
140+
141+
.form-check-input:checked + .form-check-label {
142+
color: $dark;
143+
}
144+
}
145+
}
146+
147+
.pc-item-input.discounted-price {
148+
.form-control {
149+
padding-left: 24px;
150+
border-top: 1px solid $primary;
151+
font-weight: 600;
152+
}
153+
154+
.pc-suffix-left {
155+
font-weight: 600;
156+
color: $dark;
157+
}
158+
159+
::placeholder {
160+
color: $dark;
161+
}
162+
}
163+
164+
// Hide spin for input with type = 'number'
165+
.nospin::-webkit-outer-spin-button,
166+
.nospin::-webkit-inner-spin-button {
167+
margin: 0;
168+
-webkit-appearance: none;
169+
}
170+
171+
.nospin {
172+
-moz-appearance: textfield;
173+
}

app/assets/stylesheets/application/reset.scss

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@ h2,
3434
h3,
3535
h4,
3636
h5,
37-
h6 {
37+
h6,
38+
hr {
3839
margin: 0;
3940
padding: 0;
4041
overflow-wrap: break-word;

app/assets/stylesheets/application/typography.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,11 +35,16 @@ h2,
3535
font-weight: 900;
3636
}
3737

38+
.pc-lh-xl {
39+
line-height: 1.7;
40+
}
41+
3842
// Utility Classes
3943
$custom-colors: (
4044
'gray': $gray,
4145
'gray-light': $gray-light,
4246
'gray-700': $gray-700,
47+
'gray-750': $gray-750,
4348
'blue-light': $blue-light,
4449
'blue-sky': $blue-sky,
4550
'red-light': $red-light,

app/assets/stylesheets/application/variables.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ $danger: #f12711;
1111
$gray: #9e9e9e;
1212
$gray-light: #d9d9d9;
1313
$gray-700: #616161;
14+
$gray-750: #666666;
1415
$blue-light: #e2e6f9;
1516
$blue-sky: #3f84bd;
1617
$red-light: #f5b8b8;

app/controllers/api/v1/categories_controller.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ module Api
22
module V1
33
class CategoriesController < BaseController
44
def index
5-
categories = Category.where(is_disabled: false).order(:name)
5+
categories = Category.where(is_disabled: false).order(:id)
66
render json: CategorySerializer.new(categories).serializable_hash, status: :ok
77
end
88
end

app/javascript/components/pages/ItemsPricing.jsx

Lines changed: 56 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,39 @@
11
import React, { useState } from 'react'
2-
import { Button, Container } from 'react-bootstrap'
2+
import { Button, Container, Form } from 'react-bootstrap'
33
import { useAppHooks } from '../hooks'
4-
import { ItemsPricingTopBar, QuoteCreation, ROUTES } from '../shared'
5-
import { PcAccordion } from '../ui'
4+
import { ItemsPricingTopBar, ItemTotalPrice, QuoteCreation, ROUTES } from '../shared'
5+
import { PcAccordion, PcItemAccordion, PcItemFormGroup, PcItemTextareaControl } from '../ui'
66
import { getCurrentStepId } from '../utils'
77

88
export const ItemsPricing = () => {
99
const { navigate, queryParams, location } = useAppHooks()
10-
const quoteId = queryParams.get('quote_id')
11-
const currentStepId = getCurrentStepId(location.pathname)
12-
const totalPrice = 123 // TODO: get total price from BE
1310

1411
const [selectedCategories, setSelectedCategories] = useState([])
1512
const [expandedAccordions, setExpandedAccordions] = useState([]) // array of IDs
13+
const [isNotesShow, setIsNotesShow] = useState(false)
14+
const [notesValue, setNotesValue] = useState('')
15+
const [includeNotes, setIncludeNotes] = useState(false)
16+
17+
const quoteId = queryParams.get('quote_id')
18+
const currentStepId = getCurrentStepId(location.pathname)
19+
const totalPrice = 123 // TODO: get total price from BE
20+
const notesIcon = notesValue.trim() ? 'noted' : 'note'
1621

1722
const handleToggle = (id) => {
1823
setExpandedAccordions((prev) =>
1924
prev.includes(id) ? prev.filter(item => item !== id) : [...prev, id],
2025
)
2126
}
22-
23-
const expandAll = () => {
24-
setExpandedAccordions(selectedCategories.map(category => category.id))
25-
}
26-
27-
const collapseAll = () => {
28-
setExpandedAccordions([])
29-
}
30-
27+
const expandAll = () => setExpandedAccordions(selectedCategories.map(category => category.id))
28+
const collapseAll = () => setExpandedAccordions([])
3129
const handleDownload = () => {
3230
// await fetchQuotes.update(quoteId, {
3331
// quote: { step: STEPS.COMPLETED },
3432
// })
3533
}
36-
37-
const handleBack = () => {
38-
navigate(ROUTES.CUSTOMER_INFO)
39-
}
34+
const handleBack = () => navigate(ROUTES.CUSTOMER_INFO)
35+
const handleIncludeNotes = (e) => setIncludeNotes(e.target.checked)
36+
const handleNotesValue = (e) => setNotesValue(e.target.value)
4037

4138
return (
4239
<Container className={'wrapper'}>
@@ -60,18 +57,47 @@ export const ItemsPricing = () => {
6057
}
6158
</section>
6259

63-
<section className={'mb-8'}>
60+
<section className={'d-flex flex-column gap-4 mb-8'}>
61+
{selectedCategories.length > 0 && selectedCategories.map((category) => (
62+
<PcAccordion
63+
key={category.id}
64+
categoryName={category.name}
65+
isOpen={expandedAccordions.includes(category.id)}
66+
onToggle={() => handleToggle(category.id)}
67+
>
68+
{/*List of items */}
69+
<div className={'d-flex flex-column gap-5'}>
70+
{/*TODO: Example of Fixed Price. Will be changed after adding logic*/}
71+
<PcItemAccordion
72+
key={'fixed-price'}
73+
itemName={'Decision Success'}
74+
isNotesShow={isNotesShow}
75+
setIsNotesShow={setIsNotesShow}
76+
notesIcon={notesIcon}
77+
>
78+
<ItemTotalPrice name={''} className={'mb-4'} />
6479

65-
<div className={'d-flex flex-column gap-4'}>
66-
{selectedCategories.length > 0 && selectedCategories.map((category) => (
67-
<PcAccordion
68-
key={category.id}
69-
category={category.name}
70-
isOpen={expandedAccordions.includes(category.id)}
71-
onToggle={() => handleToggle(category.id)}
72-
/>
73-
))}
74-
</div>
80+
{isNotesShow &&
81+
<PcItemFormGroup label={'Notes'} itemType={'notes'}>
82+
<PcItemTextareaControl
83+
placeholder={''}
84+
className={'mb-3'}
85+
value={notesValue}
86+
onChange={handleNotesValue}
87+
/>
88+
<Form.Check
89+
type={'checkbox'}
90+
label={`Include notes with quote`}
91+
className={'fs-10'}
92+
checked={includeNotes}
93+
onChange={handleIncludeNotes}
94+
/>
95+
</PcItemFormGroup>
96+
}
97+
</PcItemAccordion>
98+
</div>
99+
</PcAccordion>
100+
))}
75101
</section>
76102

77103
{/* Buttons section */}

0 commit comments

Comments
 (0)