>([]);\n const [orcamentoPronto, setOrcamentoPronto] = useState(false);\n const [totalOrcamento, setTotalOrcamento] = useState(0);\n \n \n const isSelected = ()=>selectedItem !== null;\n const { tipos } = useContext(TiposOrcamentoContext)\n \n const addItem = ( key:string , autoSelect:boolean = true):item => {\n \n const newAttr:attrValues= {};\n tipos[key].attr.forEach(t => { newAttr[ t.key ] = t.type===\"grade\"?\"0\":(t.options?t.options[0].value:\"\") });\n const newItem:item = {tipo:key , attr: newAttr, qtd:0, valor_orcamento:0}; \n const newSelected = items.length\n setItems([...items,newItem]);\n if( autoSelect ) {\n setSelectedItem(newItem);\n setSelectedIndex(newSelected)\n }\n return newItem;\n }\n \n const updateGrade = (attrname:string,index:number,value:string) => {\n const newItems = [...items]; \n newItems[index].attr[attrname] = value;\n const itemDef = tipos[newItems[index].tipo]; \n const qtd = itemDef.attr\n .filter(i=>i.type===\"grade\") //obtem todas as opcoes de grade\n .map(a=>newItems[index].attr[a.key]) //pega as quantidades atribuidas a cada grade\n .reduce((soma,valor)=>soma+parseInt(valor),0) //soma todas as quantidades individuais\n newItems[index].qtd = qtd;\n setItems(newItems);\n }\n const updateAttr = (e:ChangeEvent) => {\n \n if (!(e.target instanceof HTMLInputElement) && !(e.target instanceof HTMLSelectElement)) {\n return;\n }\n const newItems = [...items];\n const vIndex:string = e.target.dataset.index || \"0\"\n newItems[parseInt(vIndex)].attr[e.target.name] = e.target instanceof HTMLInputElement?e.target.value:e.target.options[e.target.selectedIndex].value;\n setItems(newItems);\n \n \n\n }\n const selectItem = ( index: number ) => {\n if( index > -1 && index < items.length ) {\n setSelectedIndex(index);\n setSelectedItem(items[index]);\n return items[index];\n \n } else {\n setSelectedIndex(-1);\n setSelectedItem(null); \n return null;\n }\n \n \n }\n\n const removeItem = (index: number):void => {\n if( index > -1 && index < items.length ) {\n items.splice(index,1);\n setItems([...items]);\n setSelectedItem(null);\n setSelectedIndex(-1);\n }\n }\n\n const editarOrcamento = () => {\n setOrcamentoPronto(false);\n }\n\n const calculaOrcamento = () => {\n \n \n const TipoNoOrcamento = new Set( items.map(i=>i.tipo));\n const CalculoPorTipo:CalculoPorTipoInterface = {};\n \n const newItems = [...items]\n\n TipoNoOrcamento.forEach(t=>CalculoPorTipo[t]={qtd:0,unitario:0});\n \n newItems.forEach( _item => {\n CalculoPorTipo[_item.tipo].qtd += _item.qtd\n });\n\n TipoNoOrcamento.forEach( t=>{\n const tabela = tipos[t].bulk_value.filter(bv=>CalculoPorTipo[t].qtd >= bv.qtd)\n \n CalculoPorTipo[t].unitario = tabela.length>1?tabela.slice(-1)[0].valor:0;\n })\n \n //const custoPorItem =\n newItems.map( _item => { \n \n const itemDef = tipos[ _item.tipo ];\n const attrComVarCusto = \n itemDef.attr.filter(i=>i.cost_var === true) //somente atributos com custo variavel (sem contar grade)\n .map( attr=> { \n const opcao_escolhida = _item.attr[attr.key]\n return attr.options && {label:attr.label, ...attr.options.find(opt=>opt.value === opcao_escolhida )};\n }) //retorna somente a variacao da opcao escolhida\n .filter( opt => opt && opt.cost_var !== undefined ) //retorna somente se opcao escolhida tiver custo variavel\n \n \n const var_unitario = attrComVarCusto.reduce((soma, valor)=>soma+(valor !== undefined && valor.cost_var?valor.cost_var:0),0);\n\n const var_grade = itemDef.attr.filter(i=>i.type === \"grade\" && typeof i.cost_var == \"number\" && _item.attr[i.key] !== \"0\")\n .map( grade=>{ \n const custo_var:number = typeof grade.cost_var === \"number\"?grade.cost_var:0; \n const qtd:number = parseInt(_item.attr[grade.key])\n return {\n label:grade.label,\n var_unitario:custo_var,\n var_total:(qtd*custo_var),\n }\n });\n \n \n const custoDoItem = {unitario_original:CalculoPorTipo[_item.tipo].unitario, variacoes:attrComVarCusto, var_unitario: var_unitario, var_grade:var_grade, total:0}\n\n custoDoItem.total = _item.qtd*(custoDoItem.unitario_original + custoDoItem.var_unitario) + custoDoItem.var_grade.reduce((soma, valor)=>soma+(valor !== undefined && valor.var_total?valor.var_total:0),0);\n\n _item.valor_orcamento = custoDoItem.total;\n\n return custoDoItem;\n });\n \n \n setTotalOrcamento( newItems.reduce( (soma,_item) => soma+_item.valor_orcamento , 0 ))\n setItems(newItems); \n setOrcamentoPronto(true);\n /*\n const itemDef = tipos[t];\n const grades = itemDef.attr.filter(i=>i.type===\"grade\");\n\n items\n .filter(i=>i.tipo===t)\n .map(i=>i)\n\n */\n/*\n items.for.map(i=>i.tipo).unique();\n itemDef.attr.filter(i=>i.type===\"grade\").map(a=>props.attr[a.key]).reduce((soma,valor)=>parseInt(soma)+parseInt(valor));\n */\n }\n\n return (\n \n {children}\n \n )\n}","\nconst formatter = new Intl.NumberFormat('pt-BR', {\n style: 'currency',\n currency: 'BRL',\n \n // These options are needed to round to whole numbers if that's what you want.\n minimumFractionDigits: 2, // (this suffices for whole numbers, but will print 2500.10 as $2,500.1)\n maximumFractionDigits: 2, // (causes 2500.99 to be printed as $2,501)\n });\n\nexport function formataMoeda( valor:number ) {\n return formatter.format(valor)\n\n}","import { itemOrcamentoProps } from \"./commonInterfaces\"\nimport '../styles/itemOrcamento.css'\nimport { TiposOrcamentoContext } from '../contexts/TiposOrcamentoContext';\nimport { OrcamentoContext } from '../contexts/OrcamentoContext';\nimport React, {useContext} from 'react';\nimport {formataMoeda} from '../util/util';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome'\nimport {faPen, faTrashAlt} from '@fortawesome/free-solid-svg-icons'\n\n\nexport default function ItemOrcamento(props:itemOrcamentoProps) {\n const {tipos} = useContext(TiposOrcamentoContext)\n const {removeItem,selectItem,orcamentoPronto} = useContext(OrcamentoContext)\n const itemDef = tipos[props.tipo]\n // const qtd = itemDef.attr.filter(i=>i.type===\"grade\").map(a=>props.attr[a.key]).reduce((soma,valor)=>parseInt(soma)+parseInt(valor));\n const clickHandler = orcamentoPronto?undefined:(e:React.MouseEvent)=>{e.stopPropagation();selectItem(props.index);}\n \n return (\n \n {!orcamentoPronto&& props.editmode && (\n \n )}\n \n

\n
\n \n
{itemDef.name}
\n
\n - Qtd:
\n - {props.qtd}
\n { props.attr.cor && (<>- Cor:
\n - {props.attr.cor}
>)}\n
\n \n
\n {orcamentoPronto && (\n \n {formataMoeda(props.valor_orcamento)}\n
\n )}\n\n {!orcamentoPronto && !props.editmode && (\n \n \n \n \n
)}\n \n \n \n )\n}","import '../styles/itemOrcamento.css'\nimport { useState, useContext} from 'react';\nimport { TiposOrcamentoContext, tipo } from '../contexts/TiposOrcamentoContext';\nimport { OrcamentoContext } from '../contexts/OrcamentoContext';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome'\nimport { faPlusCircle, faFileInvoiceDollar } from '@fortawesome/free-solid-svg-icons'\n\n\nexport default function NovoItemOrcamento() {\n const [add , setAdd] = useState(false);\n \n const [selectedTipo,setTipo] = useState(\"\");\n\n const {tipos} = useContext(TiposOrcamentoContext);\n const { addItem, calculaOrcamento } = useContext(OrcamentoContext);\n\n /* const tipos:any = {\n \"bolsa\":{name:\"Bolsas\",img:\"Bolsa.png\"},\n \"camiseta\":{name:\"Camisetas\",img:\"camiseta.png\"},\n \"caneca\":{name:\"Canecas\",img:\"Bolsa.png\"},\n }*/\n \n \n if( !add ) {\n return (\n \n \n \n \n \n \n )\n } else if(selectedTipo === \"\") {\n return (\n \n {Object.keys(tipos).map(el=>{ return (\n \n )})}\n\n \n \n );\n } else {\n const curTipo:tipo = tipos[selectedTipo];\n return (\n \n \n
{curTipo.name}\n
\n
\n \n )\n }\n\n}","import '../styles/FinalizaOrcamento.css'\nimport { useContext} from 'react';\nimport {formataMoeda} from '../util/util';\nimport { OrcamentoContext } from '../contexts/OrcamentoContext';\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome'\nimport {faFileInvoice , faPaperPlane} from '@fortawesome/free-solid-svg-icons'\n\n\nexport default function FinalizaOrcamento() {\n \n const { editarOrcamento, totalOrcamento } = useContext(OrcamentoContext);\n\n /* const tipos:any = {\n \"bolsa\":{name:\"Bolsas\",img:\"Bolsa.png\"},\n \"camiseta\":{name:\"Camisetas\",img:\"camiseta.png\"},\n \"caneca\":{name:\"Canecas\",img:\"Bolsa.png\"},\n }*/\n \n \n \n return (<>\n\n \n Total
\n {formataMoeda(totalOrcamento)}
\n \n \n \n {false && ()} \n \n >\n )\n \n\n} ","import { itemOrcamentoProps } from \"./commonInterfaces\";\nimport {useContext} from 'react';\nimport ItemOrcamento from \"./ItemOrcamento\";\nimport NovoItemOrcamento from \"./NovoItemOrcamento\";\nimport FinalizaOrcamento from \"./FinalizaOrcamento\"\nimport '../styles/listaOrcamento.css'\nimport { OrcamentoContext } from '../contexts/OrcamentoContext';\n\n\n\ninterface ListaOrcamentoProps {\n items?: [item:itemOrcamentoProps];\n}\nexport default function ListaOrcamento(props:ListaOrcamentoProps) {\n const { items, selectedIndex , orcamentoPronto } = useContext(OrcamentoContext);\n return (\n \n \n {items.map( (el,index) => {\n return (\n \n )\n })} \n {!orcamentoPronto && }\n {orcamentoPronto && }\n \n
\n \n )\n}","import { OrcamentoContext } from '../contexts/OrcamentoContext';\nimport {useContext} from 'react';\nimport '../styles/grade.css'\ninterface GradFieldProps {\n label:string;\n value:string | number;\n index:number;\n name:string;\n updateAttr:any;\n}\n\n\nexport default function GradeField( props:GradFieldProps) { \n const { updateGrade } = useContext(OrcamentoContext)\n const changeValue = ( v:number ) => {\n console.log(v)\n const campo = (document.getElementById(props.name) as HTMLInputElement);\n if( !campo ) return null;\n\n const newValue = Math[v>0?\"min\":\"max\"](v>0?100:0, parseInt(campo.value) + v ).toString()\n updateGrade(props.name, parseInt(campo.dataset.index?campo.dataset.index:\"0\") , newValue);\n }\n\n return (\n <>\n \n >\n )\n}","import '../styles/editItem.css'\nimport { TiposOrcamentoContext } from '../contexts/TiposOrcamentoContext';\nimport { OrcamentoContext } from '../contexts/OrcamentoContext';\nimport GradeField from '../components/GradeField'\nimport { FontAwesomeIcon } from '@fortawesome/react-fontawesome'\nimport { faChevronCircleLeft, faTrashAlt } from '@fortawesome/free-solid-svg-icons'\nimport {useContext} from 'react';\n\nexport default function EditItem() {\n const {tipos} = useContext(TiposOrcamentoContext)\n const {selectedItem, isSelected, selectItem, selectedIndex,updateAttr,orcamentoPronto, removeItem} = useContext(OrcamentoContext)\n \n\n if(!orcamentoPronto && isSelected() && selectedItem) {\n \n const itemDef = tipos[selectedItem.tipo]\n const gradeDef = itemDef.attr.filter(el=>el.type===\"grade\")\n const persDef = itemDef.attr.filter(el=>el.type===\"personalizacao\")\n const prodDef = itemDef.attr.filter(el=>el.type===\"produto\")\n \n return (\n \n
{itemDef.name}
\n \n { prodDef.length>0 && (\n )}\n\n\n { gradeDef.length>0 && (\n )}\n\n { persDef.length>0 && (\n )}\n\n\n\n \n\n \n \n \n
\n \n \n )\n } else {\n return (\n \n Selecione um item do orçamento
\n \n \n )\n }\n}","import './styles/global.css';\nimport './App.css';\nimport ListaOrcamento from './components/ListaOrcamento';\nimport { TiposOrcamentoProvider } from './contexts/TiposOrcamentoContext';\nimport {OrcamentoProvider} from './contexts/OrcamentoContext';\nimport EditItem from './components/EditItem';\n\nfunction App() {\n return (\n \n
\n
\n \n
\n \n \n \n \n \n \n \n \n
\n );\n}\n//\"homepage\":\"https://seubrinde.com.br/orcamento\",\nexport default App;\n","const reportWebVitals = onPerfEntry => {\n if (onPerfEntry && onPerfEntry instanceof Function) {\n import('web-vitals').then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {\n getCLS(onPerfEntry);\n getFID(onPerfEntry);\n getFCP(onPerfEntry);\n getLCP(onPerfEntry);\n getTTFB(onPerfEntry);\n });\n }\n};\n\nexport default reportWebVitals;\n","import React from 'react';\nimport ReactDOM from 'react-dom';\nimport './index.css';\nimport App from './App';\nimport reportWebVitals from './reportWebVitals';\n\nReactDOM.render(\n \n \n ,\n document.getElementById('root')\n);\n\n// If you want to start measuring performance in your app, pass a function\n// to log results (for example: reportWebVitals(console.log))\n// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals\nreportWebVitals();\n"],"sourceRoot":""}