Improved user feedback system, improved Product detail view

This commit is contained in:
2024-09-20 12:57:19 +02:00
parent 58fcae647a
commit 88c43d62c6
24 changed files with 1113 additions and 602 deletions

234
misc/.$database.drawio.bkp Normal file
View File

@@ -0,0 +1,234 @@
<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.7.8 Chrome/128.0.6613.36 Electron/32.0.1 Safari/537.36" version="24.7.8">
<diagram name="Page-1" id="WevClHWmhzPAQ7FDN5po">
<mxGraphModel dx="819" dy="473" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
<mxCell id="-XxvrMC6G6SQ8Xm1xsTM-4" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;u&gt;id:&amp;nbsp;&lt;/u&gt;&lt;u style=&quot;background-color: initial;&quot;&gt;Number&lt;/u&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="130.04000000000002" y="330" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="-XxvrMC6G6SQ8Xm1xsTM-5" value="&lt;blockquote style=&quot;margin: 0px; border: none; padding: 0px;&quot;&gt;&lt;b&gt;&lt;u&gt;Products&lt;/u&gt;&lt;/b&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=center;fillColor=#cce5ff;strokeColor=#36393d;" parent="1" vertex="1">
<mxGeometry x="130.04000000000002" y="300" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="-XxvrMC6G6SQ8Xm1xsTM-21" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;name: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="130.04000000000002" y="420" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="-XxvrMC6G6SQ8Xm1xsTM-22" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;price: Number&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="130.04000000000002" y="540" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="-XxvrMC6G6SQ8Xm1xsTM-23" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;i&gt;categoryId: Number&lt;/i&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="130.04000000000002" y="510" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="-XxvrMC6G6SQ8Xm1xsTM-24" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;discount: Number&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="130.04000000000002" y="570" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-2" value="&lt;blockquote style=&quot;margin: 0px; border: none; padding: 0px;&quot;&gt;&lt;b&gt;&lt;u&gt;Accounts&lt;/u&gt;&lt;/b&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=center;fillColor=#cce5ff;strokeColor=#36393d;" parent="1" vertex="1">
<mxGeometry x="949.9100000000001" y="300" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-3" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;u&gt;id:&amp;nbsp;&lt;/u&gt;&lt;u style=&quot;background-color: initial;&quot;&gt;Number&lt;/u&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="949.9100000000001" y="330" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-4" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;username: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="949.9100000000001" y="360" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-5" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;password: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="949.9100000000001" y="390" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-6" value="&lt;blockquote style=&quot;margin: 0px; border: none; padding: 0px;&quot;&gt;&lt;b&gt;&lt;u&gt;OrderItems&lt;/u&gt;&lt;/b&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=center;fillColor=#cce5ff;strokeColor=#36393d;" parent="1" vertex="1">
<mxGeometry x="419.91" y="240" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-7" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;u&gt;id:&amp;nbsp;&lt;/u&gt;&lt;u style=&quot;background-color: initial;&quot;&gt;Number&lt;/u&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="419.91" y="270" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-8" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;i&gt;usernameId: Number&lt;/i&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="689.9100000000001" y="330" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-9" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;totalPrice: Number&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="689.9100000000001" y="360" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-17" value="&lt;blockquote style=&quot;margin: 0px; border: none; padding: 0px;&quot;&gt;&lt;b&gt;&lt;u&gt;Categories&lt;/u&gt;&lt;/b&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=center;fillColor=#cce5ff;strokeColor=#36393d;" parent="1" vertex="1">
<mxGeometry x="419.91" y="480" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-18" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;u&gt;id:&amp;nbsp;&lt;/u&gt;&lt;u style=&quot;background-color: initial;&quot;&gt;Number&lt;/u&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="419.91" y="510" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-19" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;name: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="419.91" y="540" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-20" value="" style="endArrow=open;endSize=12;startArrow=diamondThin;startSize=14;startFill=0;edgeStyle=orthogonalEdgeStyle;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="-XxvrMC6G6SQ8Xm1xsTM-23" target="xvubMpEdOjOFzFZ-NZdf-18" edge="1">
<mxGeometry x="389.35999999999996" y="350" as="geometry">
<mxPoint x="450.04" y="519.9999999999998" as="sourcePoint" />
<mxPoint x="330.04" y="639.9999999999998" as="targetPoint" />
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-21" value="0..n" style="resizable=0;align=left;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" parent="xvubMpEdOjOFzFZ-NZdf-20" connectable="0" vertex="1">
<mxGeometry x="-1" relative="1" as="geometry">
<mxPoint x="-30" y="-35" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-22" value="1" style="resizable=0;align=right;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" parent="xvubMpEdOjOFzFZ-NZdf-20" connectable="0" vertex="1">
<mxGeometry x="1" relative="1" as="geometry">
<mxPoint x="-10" y="-25" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-23" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;i&gt;productId:&amp;nbsp;&lt;/i&gt;&lt;i style=&quot;background-color: initial;&quot;&gt;Number&lt;/i&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="419.91" y="330" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-24" value="" style="endArrow=open;endSize=12;startArrow=diamondThin;startSize=14;startFill=0;edgeStyle=orthogonalEdgeStyle;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="xvubMpEdOjOFzFZ-NZdf-8" target="xvubMpEdOjOFzFZ-NZdf-3" edge="1">
<mxGeometry x="389.35999999999996" y="350" as="geometry">
<mxPoint x="828.9100000000001" y="489.9999999999998" as="sourcePoint" />
<mxPoint x="708.9100000000001" y="609.9999999999998" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-25" value="0..n" style="resizable=0;align=left;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" parent="xvubMpEdOjOFzFZ-NZdf-24" connectable="0" vertex="1">
<mxGeometry x="-1" relative="1" as="geometry">
<mxPoint y="-25" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-26" value="1" style="resizable=0;align=right;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" parent="xvubMpEdOjOFzFZ-NZdf-24" connectable="0" vertex="1">
<mxGeometry x="1" relative="1" as="geometry">
<mxPoint x="-9" y="-35" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-27" value="" style="endArrow=open;endSize=12;startArrow=diamondThin;startSize=14;startFill=0;edgeStyle=orthogonalEdgeStyle;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="xvubMpEdOjOFzFZ-NZdf-23" target="-XxvrMC6G6SQ8Xm1xsTM-4" edge="1">
<mxGeometry x="389.35999999999996" y="350" as="geometry">
<mxPoint x="309.91" y="414.44" as="sourcePoint" />
<mxPoint x="438.91" y="414.44" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-28" value="1" style="resizable=0;align=left;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" parent="xvubMpEdOjOFzFZ-NZdf-27" connectable="0" vertex="1">
<mxGeometry x="-1" relative="1" as="geometry">
<mxPoint x="-20" y="-25" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-29" value="1" style="resizable=0;align=right;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" parent="xvubMpEdOjOFzFZ-NZdf-27" connectable="0" vertex="1">
<mxGeometry x="1" relative="1" as="geometry">
<mxPoint x="20" y="-25" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-36" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;street: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="949.9100000000001" y="480" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-37" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;firstName: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="949.9100000000001" y="420" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-38" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;lastName: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="949.9100000000001" y="450" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-40" value="&lt;blockquote style=&quot;margin: 0px; border: none; padding: 0px;&quot;&gt;&lt;b&gt;&lt;u&gt;Orders&lt;/u&gt;&lt;/b&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=center;fillColor=#cce5ff;strokeColor=#36393d;" parent="1" vertex="1">
<mxGeometry x="689.9100000000001" y="270" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-41" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;u&gt;orderId: Number&lt;/u&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="689.9100000000001" y="300" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-42" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;i&gt;orderId:&amp;nbsp;&lt;/i&gt;&lt;i style=&quot;background-color: initial;&quot;&gt;Number&lt;/i&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="419.91" y="300" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-43" value="" style="endArrow=open;endSize=12;startArrow=diamondThin;startSize=14;startFill=0;edgeStyle=orthogonalEdgeStyle;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="xvubMpEdOjOFzFZ-NZdf-42" target="xvubMpEdOjOFzFZ-NZdf-41" edge="1">
<mxGeometry x="389.35999999999996" y="350" as="geometry">
<mxPoint x="629.9100000000001" y="390" as="sourcePoint" />
<mxPoint x="729.9100000000001" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-44" value="1..n" style="resizable=0;align=left;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" parent="xvubMpEdOjOFzFZ-NZdf-43" connectable="0" vertex="1">
<mxGeometry x="-1" relative="1" as="geometry">
<mxPoint x="5" y="-25" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-45" value="1" style="resizable=0;align=right;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" parent="xvubMpEdOjOFzFZ-NZdf-43" connectable="0" vertex="1">
<mxGeometry x="1" relative="1" as="geometry">
<mxPoint x="-9" y="-25" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-47" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;quantity: Number&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="419.91" y="360" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-1" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;icon: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="419.91" y="570" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-2" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;creator: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="130.04000000000002" y="360" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-3" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;distributor: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="130.04" y="390" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-4" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;rating: Number&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="130.04000000000002" y="600" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-5" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;imageUrl: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="130.04" y="480" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-6" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;description: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="130.04" y="450" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-7" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;shippingProgress: Number&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="689.9100000000001" y="390" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-8" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;houseNumber: Number&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="949.91" y="510" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-9" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;postalCode: Number&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="949.91" y="540" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-10" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;city: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="949.9100000000001" y="570" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-11" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#2072B8;" parent="1" vertex="1">
<mxGeometry x="1090" y="335" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-12" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#2072B8;" parent="1" vertex="1">
<mxGeometry x="830" y="305" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-13" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#2072B8;" parent="1" vertex="1">
<mxGeometry x="560" y="275" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-14" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#2072B8;" parent="1" vertex="1">
<mxGeometry x="270" y="335" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-15" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#2072B8;" parent="1" vertex="1">
<mxGeometry x="559.87" y="515" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-16" value="1" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;rotation=0;gradientColor=#223548;strokeColor=none;gradientDirection=east;fillColor=#5b738b;rounded=0;pointerEvents=0;fontFamily=Helvetica;fontSize=16;fontColor=#FFFFFF;spacingTop=4;spacingBottom=4;spacingLeft=4;spacingRight=4;points=[];fontStyle=1" parent="1" vertex="1">
<mxGeometry x="1084.71" y="365" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-17" value="1" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;rotation=0;gradientColor=#223548;strokeColor=none;gradientDirection=east;fillColor=#5b738b;rounded=0;pointerEvents=0;fontFamily=Helvetica;fontSize=16;fontColor=#FFFFFF;spacingTop=4;spacingBottom=4;spacingLeft=4;spacingRight=4;points=[];fontStyle=1" parent="1" vertex="1">
<mxGeometry x="554.58" y="545" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-18" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#2072B8;" parent="1" vertex="1">
<mxGeometry x="720" y="475" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-19" value="Primary Key" style="text;strokeColor=none;align=left;fillColor=none;html=1;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="739.9100000000001" y="470" width="110" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-20" value="1" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;rotation=0;gradientColor=#223548;strokeColor=none;gradientDirection=east;fillColor=#5b738b;rounded=0;pointerEvents=0;fontFamily=Helvetica;fontSize=16;fontColor=#FFFFFF;spacingTop=4;spacingBottom=4;spacingLeft=4;spacingRight=4;points=[];fontStyle=1" parent="1" vertex="1">
<mxGeometry x="714.71" y="545" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-21" value="Unique" style="text;strokeColor=none;align=left;fillColor=none;html=1;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="739.91" y="540" width="110" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-24" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#CCCCCC;" parent="1" vertex="1">
<mxGeometry x="560" y="305" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-25" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#CCCCCC;" parent="1" vertex="1">
<mxGeometry x="560" y="335" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-26" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#CCCCCC;" parent="1" vertex="1">
<mxGeometry x="830" y="335" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-27" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#CCCCCC;" parent="1" vertex="1">
<mxGeometry x="270" y="515" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-28" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#CCCCCC;" parent="1" vertex="1">
<mxGeometry x="720" y="510" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-29" value="Foreign Key" style="text;strokeColor=none;align=left;fillColor=none;html=1;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="739.9100000000001" y="505" width="110" height="30" as="geometry" />
</mxCell>
<mxCell id="sa5D8W8LL20ZiN9_dg2E-1" value="1" style="resizable=0;align=right;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" connectable="0" vertex="1" parent="1">
<mxGeometry x="309.99999999999994" y="500" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>
</mxfile>

View File

@@ -1,6 +1,6 @@
<mxfile host="Electron" modified="2024-09-04T09:39:26.183Z" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.6.4 Chrome/124.0.6367.207 Electron/30.0.6 Safari/537.36" etag="fozS5r_BxbeOsm9uWpcX" version="24.6.4" type="device">
<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/24.7.8 Chrome/128.0.6613.36 Electron/32.0.1 Safari/537.36" version="24.7.8">
<diagram name="Page-1" id="WevClHWmhzPAQ7FDN5po">
<mxGraphModel dx="1793" dy="1184" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
<mxGraphModel dx="819" dy="473" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
<root>
<mxCell id="0" />
<mxCell id="1" parent="0" />
@@ -11,145 +11,223 @@
<mxGeometry x="130.04000000000002" y="300" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="-XxvrMC6G6SQ8Xm1xsTM-21" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;name: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="130.04000000000002" y="360" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="-XxvrMC6G6SQ8Xm1xsTM-22" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;price: Number&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="130.04000000000002" y="420" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="-XxvrMC6G6SQ8Xm1xsTM-22" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;price: Number&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="130.04000000000002" y="540" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="-XxvrMC6G6SQ8Xm1xsTM-23" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;i&gt;categoryId: Number&lt;/i&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="130.04000000000002" y="390" width="160" height="30" as="geometry" />
<mxGeometry x="130.04000000000002" y="510" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="-XxvrMC6G6SQ8Xm1xsTM-24" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;discount: Number&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="130.04000000000002" y="450" width="160" height="30" as="geometry" />
<mxGeometry x="130.04000000000002" y="570" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-2" value="&lt;blockquote style=&quot;margin: 0px; border: none; padding: 0px;&quot;&gt;&lt;b&gt;&lt;u&gt;User&lt;/u&gt;&lt;/b&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=center;fillColor=#cce5ff;strokeColor=#36393d;" vertex="1" parent="1">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-2" value="&lt;blockquote style=&quot;margin: 0px; border: none; padding: 0px;&quot;&gt;&lt;b&gt;&lt;u&gt;Accounts&lt;/u&gt;&lt;/b&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=center;fillColor=#cce5ff;strokeColor=#36393d;" parent="1" vertex="1">
<mxGeometry x="949.9100000000001" y="300" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-3" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;u&gt;id:&amp;nbsp;&lt;/u&gt;&lt;u style=&quot;background-color: initial;&quot;&gt;Number&lt;/u&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-3" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;u&gt;id:&amp;nbsp;&lt;/u&gt;&lt;u style=&quot;background-color: initial;&quot;&gt;Number&lt;/u&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="949.9100000000001" y="330" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-4" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;username: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-4" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;username: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="949.9100000000001" y="360" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-5" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;password: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-5" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;password: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="949.9100000000001" y="390" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-6" value="&lt;blockquote style=&quot;margin: 0px; border: none; padding: 0px;&quot;&gt;&lt;b&gt;&lt;u&gt;OrderedItem&lt;/u&gt;&lt;/b&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=center;fillColor=#cce5ff;strokeColor=#36393d;" vertex="1" parent="1">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-6" value="&lt;blockquote style=&quot;margin: 0px; border: none; padding: 0px;&quot;&gt;&lt;b&gt;&lt;u&gt;OrderItems&lt;/u&gt;&lt;/b&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=center;fillColor=#cce5ff;strokeColor=#36393d;" parent="1" vertex="1">
<mxGeometry x="419.91" y="240" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-7" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;u&gt;id:&amp;nbsp;&lt;/u&gt;&lt;u style=&quot;background-color: initial;&quot;&gt;Number&lt;/u&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-7" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;u&gt;id:&amp;nbsp;&lt;/u&gt;&lt;u style=&quot;background-color: initial;&quot;&gt;Number&lt;/u&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="419.91" y="270" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-8" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;i&gt;usernameId: Number&lt;/i&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-8" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;i&gt;usernameId: Number&lt;/i&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="689.9100000000001" y="330" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-9" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;totalPrice: Number&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-9" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;totalPrice: Number&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="689.9100000000001" y="360" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-17" value="&lt;blockquote style=&quot;margin: 0px; border: none; padding: 0px;&quot;&gt;&lt;b&gt;&lt;u&gt;Categories&lt;/u&gt;&lt;/b&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=center;fillColor=#cce5ff;strokeColor=#36393d;" vertex="1" parent="1">
<mxGeometry x="130.04000000000002" y="170" width="160" height="30" as="geometry" />
<mxCell id="xvubMpEdOjOFzFZ-NZdf-17" value="&lt;blockquote style=&quot;margin: 0px; border: none; padding: 0px;&quot;&gt;&lt;b&gt;&lt;u&gt;Categories&lt;/u&gt;&lt;/b&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=center;fillColor=#cce5ff;strokeColor=#36393d;" parent="1" vertex="1">
<mxGeometry x="419.91" y="480" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-18" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;u&gt;id:&amp;nbsp;&lt;/u&gt;&lt;u style=&quot;background-color: initial;&quot;&gt;Number&lt;/u&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
<mxGeometry x="130.04000000000002" y="200" width="160" height="30" as="geometry" />
<mxCell id="xvubMpEdOjOFzFZ-NZdf-18" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;u&gt;id:&amp;nbsp;&lt;/u&gt;&lt;u style=&quot;background-color: initial;&quot;&gt;Number&lt;/u&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="419.91" y="510" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-19" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;name: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
<mxGeometry x="130.04000000000002" y="230" width="160" height="30" as="geometry" />
<mxCell id="xvubMpEdOjOFzFZ-NZdf-19" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;name: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="419.91" y="540" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-20" value="" style="endArrow=open;endSize=12;startArrow=diamondThin;startSize=14;startFill=0;edgeStyle=orthogonalEdgeStyle;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="xvubMpEdOjOFzFZ-NZdf-18" target="-XxvrMC6G6SQ8Xm1xsTM-23">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-20" value="" style="endArrow=open;endSize=12;startArrow=diamondThin;startSize=14;startFill=0;edgeStyle=orthogonalEdgeStyle;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="-XxvrMC6G6SQ8Xm1xsTM-23" target="xvubMpEdOjOFzFZ-NZdf-18" edge="1">
<mxGeometry x="389.35999999999996" y="350" as="geometry">
<mxPoint x="450.04" y="519.9999999999998" as="sourcePoint" />
<mxPoint x="330.04" y="639.9999999999998" as="targetPoint" />
<Array as="points">
<mxPoint x="90.04000000000002" y="215" />
<mxPoint x="90.04000000000002" y="405" />
</Array>
<Array as="points" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-21" value="0..n" style="resizable=0;align=left;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" connectable="0" vertex="1" parent="xvubMpEdOjOFzFZ-NZdf-20">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-21" value="0..n" style="resizable=0;align=left;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" parent="xvubMpEdOjOFzFZ-NZdf-20" connectable="0" vertex="1">
<mxGeometry x="-1" relative="1" as="geometry">
<mxPoint x="-30" y="-35" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-22" value="1" style="resizable=0;align=right;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" connectable="0" vertex="1" parent="xvubMpEdOjOFzFZ-NZdf-20">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-22" value="1" style="resizable=0;align=right;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" parent="xvubMpEdOjOFzFZ-NZdf-20" connectable="0" vertex="1">
<mxGeometry x="1" relative="1" as="geometry">
<mxPoint x="-10" y="-35" as="offset" />
<mxPoint x="-10" y="-25" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-23" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;i&gt;productId:&amp;nbsp;&lt;/i&gt;&lt;i style=&quot;background-color: initial;&quot;&gt;Number&lt;/i&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-23" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;i&gt;productId:&amp;nbsp;&lt;/i&gt;&lt;i style=&quot;background-color: initial;&quot;&gt;Number&lt;/i&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="419.91" y="330" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-24" value="" style="endArrow=open;endSize=12;startArrow=diamondThin;startSize=14;startFill=0;edgeStyle=orthogonalEdgeStyle;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="xvubMpEdOjOFzFZ-NZdf-8" target="xvubMpEdOjOFzFZ-NZdf-3">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-24" value="" style="endArrow=open;endSize=12;startArrow=diamondThin;startSize=14;startFill=0;edgeStyle=orthogonalEdgeStyle;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="xvubMpEdOjOFzFZ-NZdf-8" target="xvubMpEdOjOFzFZ-NZdf-3" edge="1">
<mxGeometry x="389.35999999999996" y="350" as="geometry">
<mxPoint x="828.9100000000001" y="489.9999999999998" as="sourcePoint" />
<mxPoint x="708.9100000000001" y="609.9999999999998" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-25" value="0..n" style="resizable=0;align=left;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" connectable="0" vertex="1" parent="xvubMpEdOjOFzFZ-NZdf-24">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-25" value="0..n" style="resizable=0;align=left;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" parent="xvubMpEdOjOFzFZ-NZdf-24" connectable="0" vertex="1">
<mxGeometry x="-1" relative="1" as="geometry">
<mxPoint y="-25" as="offset" />
<mxPoint x="10" y="-25" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-26" value="1" style="resizable=0;align=right;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" connectable="0" vertex="1" parent="xvubMpEdOjOFzFZ-NZdf-24">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-26" value="1" style="resizable=0;align=right;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" parent="xvubMpEdOjOFzFZ-NZdf-24" connectable="0" vertex="1">
<mxGeometry x="1" relative="1" as="geometry">
<mxPoint x="-9" y="-35" as="offset" />
<mxPoint x="-9" y="-25" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-27" value="" style="endArrow=open;endSize=12;startArrow=diamondThin;startSize=14;startFill=0;edgeStyle=orthogonalEdgeStyle;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="xvubMpEdOjOFzFZ-NZdf-23" target="-XxvrMC6G6SQ8Xm1xsTM-4">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-27" value="" style="endArrow=open;endSize=12;startArrow=diamondThin;startSize=14;startFill=0;edgeStyle=orthogonalEdgeStyle;entryX=1;entryY=0.5;entryDx=0;entryDy=0;exitX=0;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="xvubMpEdOjOFzFZ-NZdf-23" target="-XxvrMC6G6SQ8Xm1xsTM-4" edge="1">
<mxGeometry x="389.35999999999996" y="350" as="geometry">
<mxPoint x="309.91" y="414.44" as="sourcePoint" />
<mxPoint x="438.91" y="414.44" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-28" value="1" style="resizable=0;align=left;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" connectable="0" vertex="1" parent="xvubMpEdOjOFzFZ-NZdf-27">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-28" value="1" style="resizable=0;align=left;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" parent="xvubMpEdOjOFzFZ-NZdf-27" connectable="0" vertex="1">
<mxGeometry x="-1" relative="1" as="geometry">
<mxPoint x="-30" y="-35" as="offset" />
<mxPoint x="-20" y="-25" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-29" value="1" style="resizable=0;align=right;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" connectable="0" vertex="1" parent="xvubMpEdOjOFzFZ-NZdf-27">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-29" value="1" style="resizable=0;align=right;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" parent="xvubMpEdOjOFzFZ-NZdf-27" connectable="0" vertex="1">
<mxGeometry x="1" relative="1" as="geometry">
<mxPoint x="20" y="-35" as="offset" />
<mxPoint x="20" y="-25" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-36" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;address: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
<mxGeometry x="949.9100000000001" y="420" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-37" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;firstName: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
<mxGeometry x="949.9100000000001" y="450" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-38" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;lastName: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-36" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;street: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="949.9100000000001" y="480" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-40" value="&lt;blockquote style=&quot;margin: 0px; border: none; padding: 0px;&quot;&gt;&lt;b&gt;&lt;u&gt;Order&lt;/u&gt;&lt;/b&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=center;fillColor=#cce5ff;strokeColor=#36393d;" vertex="1" parent="1">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-37" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;firstName: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="949.9100000000001" y="420" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-38" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;lastName: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="949.9100000000001" y="450" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-40" value="&lt;blockquote style=&quot;margin: 0px; border: none; padding: 0px;&quot;&gt;&lt;b&gt;&lt;u&gt;Orders&lt;/u&gt;&lt;/b&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=center;fillColor=#cce5ff;strokeColor=#36393d;" parent="1" vertex="1">
<mxGeometry x="689.9100000000001" y="270" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-41" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;u&gt;orderId: Number&lt;/u&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-41" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;u&gt;orderId: Number&lt;/u&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="689.9100000000001" y="300" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-42" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;i&gt;orderId:&amp;nbsp;&lt;/i&gt;&lt;i style=&quot;background-color: initial;&quot;&gt;Number&lt;/i&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-42" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;&lt;i&gt;orderId:&amp;nbsp;&lt;/i&gt;&lt;i style=&quot;background-color: initial;&quot;&gt;Number&lt;/i&gt;&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="419.91" y="300" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-43" value="" style="endArrow=open;endSize=12;startArrow=diamondThin;startSize=14;startFill=0;edgeStyle=orthogonalEdgeStyle;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" edge="1" parent="1" source="xvubMpEdOjOFzFZ-NZdf-42" target="xvubMpEdOjOFzFZ-NZdf-41">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-43" value="" style="endArrow=open;endSize=12;startArrow=diamondThin;startSize=14;startFill=0;edgeStyle=orthogonalEdgeStyle;entryX=0;entryY=0.5;entryDx=0;entryDy=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;" parent="1" source="xvubMpEdOjOFzFZ-NZdf-42" target="xvubMpEdOjOFzFZ-NZdf-41" edge="1">
<mxGeometry x="389.35999999999996" y="350" as="geometry">
<mxPoint x="629.9100000000001" y="390" as="sourcePoint" />
<mxPoint x="729.9100000000001" y="390" as="targetPoint" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-44" value="0..n" style="resizable=0;align=left;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" connectable="0" vertex="1" parent="xvubMpEdOjOFzFZ-NZdf-43">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-44" value="1..n" style="resizable=0;align=left;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" parent="xvubMpEdOjOFzFZ-NZdf-43" connectable="0" vertex="1">
<mxGeometry x="-1" relative="1" as="geometry">
<mxPoint y="-25" as="offset" />
<mxPoint x="5" y="-25" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-45" value="1" style="resizable=0;align=right;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" connectable="0" vertex="1" parent="xvubMpEdOjOFzFZ-NZdf-43">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-45" value="1" style="resizable=0;align=right;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" parent="xvubMpEdOjOFzFZ-NZdf-43" connectable="0" vertex="1">
<mxGeometry x="1" relative="1" as="geometry">
<mxPoint x="-9" y="-35" as="offset" />
<mxPoint x="-9" y="-25" as="offset" />
</mxGeometry>
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-46" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;totalPrice: Number&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
<mxGeometry x="419.91" y="390" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="xvubMpEdOjOFzFZ-NZdf-47" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;quantity: Number&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" vertex="1" parent="1">
<mxCell id="xvubMpEdOjOFzFZ-NZdf-47" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;quantity: Number&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="419.91" y="360" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-1" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;icon: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="419.91" y="570" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-2" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;creator: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="130.04000000000002" y="360" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-3" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;distributor: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="130.04" y="390" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-4" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;rating: Number&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="130.04000000000002" y="600" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-5" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;imageUrl: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="130.04" y="480" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-6" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;description: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="130.04" y="450" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-7" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;shippingProgress: Number&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="689.9100000000001" y="390" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-8" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;houseNumber: Number&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="949.91" y="510" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-9" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;postalCode: Number&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="949.91" y="540" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-10" value="&lt;blockquote style=&quot;margin: 0px 0px 0px 8px; border: none; padding: 0px;&quot;&gt;city: String&lt;/blockquote&gt;" style="rounded=0;whiteSpace=wrap;html=1;align=left;" parent="1" vertex="1">
<mxGeometry x="949.9100000000001" y="570" width="160" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-11" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#2072B8;" parent="1" vertex="1">
<mxGeometry x="1090" y="335" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-12" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#2072B8;" parent="1" vertex="1">
<mxGeometry x="830" y="305" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-13" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#2072B8;" parent="1" vertex="1">
<mxGeometry x="560" y="275" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-14" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#2072B8;" parent="1" vertex="1">
<mxGeometry x="270" y="335" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-15" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#2072B8;" parent="1" vertex="1">
<mxGeometry x="559.87" y="515" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-16" value="1" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;rotation=0;gradientColor=#223548;strokeColor=none;gradientDirection=east;fillColor=#5b738b;rounded=0;pointerEvents=0;fontFamily=Helvetica;fontSize=16;fontColor=#FFFFFF;spacingTop=4;spacingBottom=4;spacingLeft=4;spacingRight=4;points=[];fontStyle=1" parent="1" vertex="1">
<mxGeometry x="1084.71" y="365" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-17" value="1" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;rotation=0;gradientColor=#223548;strokeColor=none;gradientDirection=east;fillColor=#5b738b;rounded=0;pointerEvents=0;fontFamily=Helvetica;fontSize=16;fontColor=#FFFFFF;spacingTop=4;spacingBottom=4;spacingLeft=4;spacingRight=4;points=[];fontStyle=1" parent="1" vertex="1">
<mxGeometry x="554.58" y="545" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-18" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#2072B8;" parent="1" vertex="1">
<mxGeometry x="720" y="475" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-19" value="Primary Key" style="text;strokeColor=none;align=left;fillColor=none;html=1;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="739.9100000000001" y="470" width="110" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-20" value="1" style="ellipse;whiteSpace=wrap;html=1;aspect=fixed;rotation=0;gradientColor=#223548;strokeColor=none;gradientDirection=east;fillColor=#5b738b;rounded=0;pointerEvents=0;fontFamily=Helvetica;fontSize=16;fontColor=#FFFFFF;spacingTop=4;spacingBottom=4;spacingLeft=4;spacingRight=4;points=[];fontStyle=1" parent="1" vertex="1">
<mxGeometry x="714.71" y="545" width="20" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-21" value="Unique" style="text;strokeColor=none;align=left;fillColor=none;html=1;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="739.91" y="540" width="110" height="30" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-24" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#CCCCCC;" parent="1" vertex="1">
<mxGeometry x="560" y="305" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-25" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#CCCCCC;" parent="1" vertex="1">
<mxGeometry x="560" y="335" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-26" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#CCCCCC;" parent="1" vertex="1">
<mxGeometry x="830" y="335" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-27" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#CCCCCC;" parent="1" vertex="1">
<mxGeometry x="270" y="515" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-28" value="" style="sketch=0;pointerEvents=1;shadow=0;dashed=0;html=1;strokeColor=none;labelPosition=center;verticalLabelPosition=bottom;verticalAlign=top;outlineConnect=0;align=center;shape=mxgraph.office.security.key_permissions;fillColor=#CCCCCC;" parent="1" vertex="1">
<mxGeometry x="720" y="510" width="9.43" height="20" as="geometry" />
</mxCell>
<mxCell id="Mm1_BtgNgvV1z5cDQ8i7-29" value="Foreign Key" style="text;strokeColor=none;align=left;fillColor=none;html=1;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="1" vertex="1">
<mxGeometry x="739.9100000000001" y="505" width="110" height="30" as="geometry" />
</mxCell>
<mxCell id="sa5D8W8LL20ZiN9_dg2E-1" value="1" style="resizable=0;align=right;verticalAlign=top;labelBackgroundColor=#ffffff;fontSize=10;strokeColor=#003366;shadow=1;fillColor=#D4E1F5;fontColor=#003366" connectable="0" vertex="1" parent="1">
<mxGeometry x="309.99999999999994" y="500" as="geometry" />
</mxCell>
</root>
</mxGraphModel>
</diagram>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 71 KiB

After

Width:  |  Height:  |  Size: 102 KiB

View File

@@ -1,8 +1,9 @@
import { Table, Column, Model, BelongsTo, ForeignKey, HasMany } from 'sequelize-typescript';
import { Table, Column, Model, BelongsTo, ForeignKey, HasMany, Unique } from 'sequelize-typescript';
import { Product } from './product.model';
@Table
export class Category extends Model {
@Unique
@Column
name: string

View File

@@ -14,33 +14,22 @@ account.post("/login", (req: Request, res: Response) => {
if (account != null) {
if (account.password == req.body.password) {
// Status: 200 OK
res.status(200).json({
loginSuccessful: true,
account: account,
message: ""
}).send()
res.status(200).json(account).send()
} else {
// Status: 401 Unauthorized
res.status(401).json({
loginSuccessful: false,
account: null,
message: "Wrong password"
}).send()
res.status(401).send()
}
} else {
// Status: 401 Unauthorized
res.status(401).json({
loginSuccessful: false,
userId: -1,
message: "Username doesn't exists"
}).send()
// Status: 400 Bad request
res.status(400).send()
}
}
)
})
// Creating a new user
account.post("/register", (req: Request, res: Response) => {
account.post("/", (req: Request, res: Response) => {
// Check if username is valid
if (!validateString(req.body.username, 4))
{
// Status: 400 Bad request
@@ -48,25 +37,25 @@ account.post("/register", (req: Request, res: Response) => {
message: "Username too short!"
}).send()
}
else if (!validateString(req.body.password, 8))
// Check if password is valid
if (!validateString(req.body.password, 8))
{
// Status: 400 Bad request
res.status(400).json({
message: "Password too short!"
}).send()
}
else
{
Account.create(req.body)
.then(account => {
res.status(200).json(account).send()
}).catch(reason => {
// Status: 400 Bad request
res.status(400).json({
message: reason
}).send()
})
}
// Create account
Account.create(req.body)
.then(account => {
// Status: 201 Created
res.status(201).json(account).send()
}).catch(reason => {
// Status: 409 Conflict
res.status(409).send()
})
})
account.patch("/", (req: Request, res: Response) => {
@@ -75,9 +64,11 @@ account.patch("/", (req: Request, res: Response) => {
where: { id: req.body.id }
})
.then(account => {
res.status(200).send()
// Status: 200 OK
res.status(200).json(account).send()
})
.catch(error => {
// Status: 400 Bad request
res.status(400).json({
message: error
}).send()

View File

@@ -10,7 +10,7 @@ category.get("/", (req: Request, res: Response, next: NextFunction) => {
res.status(200).json(categories).send()
})
.catch(error => {
res.status(400)//.json({ message: error }).send()
res.status(400)
})
})
@@ -36,7 +36,7 @@ category.delete("/:id", (req: Request, res: Response, next: NextFunction) => {
res.status(200).send()
})
.catch(error => {
res.status(406).json({
res.status(400).json({
message: error
}).send()
})

View File

@@ -14,7 +14,7 @@ order.get("/:id", (req: Request, res: Response) => {
]
})
.then(orders => {
res.status(200).send(orders)
res.status(200).json(orders).send()
})
})

View File

@@ -18,7 +18,7 @@ product.get("/", (req: Request, res: Response) => {
product.get("/:productId", (req: Request, res: Response) => {
Product.findByPk(req.params.productId)
.then(product => {
res.status(200).json(product)
res.status(200).json(product).send()
})
})
@@ -26,7 +26,7 @@ product.get("/:productId", (req: Request, res: Response) => {
product.post("/", (req: Request, res: Response) => {
Product.create(req.body)
.then(product => {
res.status(200).send()
res.status(201).json(product).send()
})
.catch(error => {
res.status(400).json({
@@ -41,10 +41,10 @@ product.delete("/:id", (req: Request, res: Response) => {
where: { id: req.params.id }
})
.then(product => {
res.status(200).send()
res.status(200).json(product).send()
})
.catch(error => {
res.status(406).json({
res.status(400).json({
message: error
}).send()
})

File diff suppressed because it is too large Load Diff

View File

@@ -21,7 +21,7 @@
"@vueuse/core": "^11.0.3",
"axios": "^1.7.7",
"body-parser": "^1.20.2",
"concurrently": "^8.2.2",
"concurrently": "^9.0.1",
"cors": "^2.8.5",
"express": "^4.19.2",
"pinia": "^2.2.2",
@@ -33,7 +33,7 @@
"vue": "^3.4.29",
"vue-i18n": "^10.0.0",
"vue-router": "^4.4.3",
"vuetify": "^3.7.1",
"vuetify": "^3.7.2",
"wait-on": "^8.0.0"
},
"devDependencies": {

View File

@@ -14,14 +14,22 @@ defineProps({
</script>
<template>
<v-dialog max-width="800" v-model="showDialog">
<v-card :title="title" >
<v-img v-if="imageUrl != ''" :src="imageUrl" max-height="300" />
<v-card-text>
<slot name="content"></slot>
</v-card-text>
<v-dialog max-width="1000" v-model="showDialog">
<v-card :title="title" :subtitle="subtitle" >
<v-container>
<v-row>
<v-col>
<v-img v-if="imageUrl != ''" :src="imageUrl" max-height="600" />
</v-col>
<v-col>
<v-card-text>
<slot name="content"></slot>
</v-card-text>
</v-col>
</v-row>
</v-container>
<v-card-actions>
<slot name="actions"></slot>
</v-card-actions>

View File

@@ -3,13 +3,17 @@ import { AccountModel } from "../models/accountModel"
const BASE_URL = "http://localhost:3000/accounts"
export async function login(username: string, password: string) {
export async function loginAccount(username: string, password: string) {
return await axios.post(BASE_URL + "/login", {
username: username,
password: password
})
}
export async function register(account: AccountModel) {
return await axios.post(BASE_URL + "/register", account)
export async function registerAccount(account: AccountModel) {
return await axios.post(BASE_URL, account)
}
export async function updateAccount(account: AccountModel) {
return await axios.patch(BASE_URL, account)
}

View File

@@ -1,8 +1,79 @@
export enum BannerStateEnum {
DATABASERESETSUCCESSFUL,
////////// System feedback //////////
// Some error
ERROR,
WRONGLOGIN,
LOGINSUCCESSFUL,
REGISTERSUCCESSFUL,
USERNAMEINUSE
BASKETPRODUCTADDED,
BASKETPRODUCTREMOVED,
////////// API Endpoint /api //////////
// Status: 200 OK
DATABASERESETSUCCESSFUL,
////////// API Endpoint /accounts //////////
// Status: 200 OK
ACCOUNTLOGINSUCCESSFUL,
// Status: 400 Bad request
ACCOUNTLOGINERROR,
// Status: 401 Unauthorized
ACCOUNTLOGINWRONGLOGIN,
// Status: 201 Created
ACCOUNTREGISTERSUCCESSFUL,
// Status: 400 Bad request
ACCOUNTREGISTERERROR,
// Status: 409 Conflict
ACCOUNTREGISTERUSERNAMEINUSE,
// Status: 200 OK
ACCOUNTUPDATESUCCESSFUL,
// No status code, runs in local cache
ACCOUNTLOGOUTSUCCESSFUL,
////////// API Endpoint /categories //////////
// Status: 201 Created
CATEGORYCREATESUCCESSFUL,
// Status: 200 OK
CATEGORYDELETESUCESSFUL,
// Status: 400 Bad request
CATEGORYCREATEERROR,
// Status: 400 Bad request
CATEGORYDELETEERROR,
////////// API Endpoint /orders //////////
// Status: 201 Created
ORDERPLACESUCCESSFUL,
////////// API Endpoint /products //////////
// Status: 201 Created
PRODUCTCREATESUCCESSFUL,
// Status: 400 Bad request
PRODUCTCREATEERROR,
// Status: 200 OK
PRODUCTDELETESUCCESSFUL,
// Status: 400 Bad request
PRODUCTDELETEERROR
}

View File

@@ -2,6 +2,8 @@ import { defineStore } from "pinia";
import { useLocalStorage } from "@vueuse/core";
import { calcProductPrice } from "@/scripts/productScripts";
import { BasketItemModel } from "../models/basketItemModel";
import { useFeedbackStore } from "./feedbackStore";
import { BannerStateEnum } from "../enums/bannerStateEnum";
export const useBasketStore = defineStore('basket', {
state: () => ({
@@ -22,12 +24,18 @@ export const useBasketStore = defineStore('basket', {
actions: {
removeItemFromBasket(item: BasketItemModel) {
const feedbackStore = useFeedbackStore()
feedbackStore.changeBanner(BannerStateEnum.BASKETPRODUCTREMOVED)
this.itemsInBasket = this.itemsInBasket.filter((basketItemModel: BasketItemModel) =>
basketItemModel.productId != item.productId
)
},
addItemToBasket(item: BasketItemModel) {
const feedbackStore = useFeedbackStore()
feedbackStore.changeBanner(BannerStateEnum.BASKETPRODUCTADDED)
// Product is already in the basket, increase number of items
if (this.itemsInBasket.find((basketItem) => basketItem.productId == item.productId)) {
this.itemsInBasket.find((basketItem) => basketItem.productId == item.productId).quantity += item.quantity

View File

@@ -21,37 +21,116 @@ export const useFeedbackStore = defineStore("feedbackStore", {
actions: {
changeBanner(bannerState: BannerStateEnum) {
switch (bannerState) {
////////// System feedback //////////
case BannerStateEnum.ERROR: {
this.title = this.i18n.t('bannerMessages.error'); break;
}
case BannerStateEnum.BASKETPRODUCTADDED: {
this.title = this.i18n.t('bannerMessages.basketProductAdded'); break;
}
case BannerStateEnum.BASKETPRODUCTREMOVED: {
this.title = this.i18n.t("bannerMessages.basketProductRemoved"); break;
}
////////// API Endpoint /api //////////
case BannerStateEnum.DATABASERESETSUCCESSFUL: {
this.title = this.i18n.t('bannerMessages.databaseResetSuccessful'); break;
}
case BannerStateEnum.LOGINSUCCESSFUL: {
////////// API Endpoint /accounts //////////
case BannerStateEnum.ACCOUNTLOGINSUCCESSFUL: {
this.title = this.i18n.t('bannerMessages.loginSuccessful'); break;
}
case BannerStateEnum.WRONGLOGIN: {
case BannerStateEnum.ACCOUNTLOGINWRONGLOGIN: {
this.title = this.i18n.t('bannerMessages.wrongLogin'); break;
}
case BannerStateEnum.REGISTERSUCCESSFUL: {
case BannerStateEnum.ACCOUNTLOGINERROR: {
this.title = this.i18n.t('bannerMessages.error'); break;
}
case BannerStateEnum.ACCOUNTREGISTERSUCCESSFUL: {
this.title = this.i18n.t("bannerMessages.registerSuccessful"); break;
}
case BannerStateEnum.USERNAMEINUSE: {
case BannerStateEnum.ACCOUNTREGISTERUSERNAMEINUSE: {
this.title = this.i18n.t("bannerMessages.usernameInUse"); break;
}
case BannerStateEnum.ACCOUNTUPDATESUCCESSFUL: {
this.title = this.i18n.t("bannerMessages.accountUpdated"); break;
}
case BannerStateEnum.ACCOUNTLOGOUTSUCCESSFUL: {
this.title = this.i18n.t('bannerMessages.logoutSuccessful'); break;
}
////////// API Endpoint /categories //////////
case BannerStateEnum.CATEGORYCREATESUCCESSFUL: {
this.title = this.i18n.t('bannerMessages.categoryCreateSuccessful'); break;
}
case BannerStateEnum.CATEGORYDELETESUCESSFUL: {
this.title = this.i18n.t('bannerMessages.categoryDeleteSuccessful'); break;
}
case BannerStateEnum.CATEGORYCREATEERROR: {
this.title = this.i18n.t('bannerMessages.categoryCreateError'); break;
}
case BannerStateEnum.CATEGORYDELETEERROR: {
this.title = this.i18n.t('bannerMessages.categoryDeleteError'); break;
}
////////// API Endpoint /orders //////////
case BannerStateEnum.ORDERPLACESUCCESSFUL: {
this.title = this.i18n.t('bannerMessages.orderPlaceSuccessfull'); break;
}
////////// API Endpoint /products //////////
case BannerStateEnum.PRODUCTCREATESUCCESSFUL: {
this.title = this.i18n.t('bannerMessages.productCreateSuccessful'); break;
}
case BannerStateEnum.PRODUCTCREATEERROR: {
this.title = this.i18n.t('bannerMessages.productCreateError'); break;
}
case BannerStateEnum.PRODUCTDELETESUCCESSFUL: {
this.title = this.i18n.t('bannerMessages.productDeleteSuccessful'); break;
}
case BannerStateEnum.PRODUCTDELETEERROR: {
this.title = this.i18n.t('bannerMessages.productDeleteError'); break;
}
}
switch (bannerState) {
case BannerStateEnum.ERROR:
case BannerStateEnum.WRONGLOGIN:
case BannerStateEnum.USERNAMEINUSE:
case BannerStateEnum.ACCOUNTLOGINERROR:
case BannerStateEnum.ACCOUNTLOGINWRONGLOGIN:
case BannerStateEnum.ACCOUNTREGISTERERROR:
case BannerStateEnum.ACCOUNTREGISTERUSERNAMEINUSE:
case BannerStateEnum.CATEGORYCREATEERROR:
case BannerStateEnum.CATEGORYDELETEERROR:
case BannerStateEnum.PRODUCTDELETESUCCESSFUL:
case BannerStateEnum.PRODUCTDELETEERROR:
this.color = "red"
this.icon = "mdi-alert-circle"
break;
case BannerStateEnum.DATABASERESETSUCCESSFUL:
case BannerStateEnum.LOGINSUCCESSFUL:
case BannerStateEnum.REGISTERSUCCESSFUL:
case BannerStateEnum.ACCOUNTLOGINSUCCESSFUL:
case BannerStateEnum.ACCOUNTREGISTERSUCCESSFUL:
case BannerStateEnum.ACCOUNTUPDATESUCCESSFUL:
case BannerStateEnum.ACCOUNTLOGOUTSUCCESSFUL:
case BannerStateEnum.CATEGORYCREATESUCCESSFUL:
case BannerStateEnum.CATEGORYDELETESUCESSFUL:
case BannerStateEnum.ORDERPLACESUCCESSFUL:
case BannerStateEnum.PRODUCTCREATESUCCESSFUL:
case BannerStateEnum.PRODUCTCREATEERROR:
this.color = "green"
this.icon = "mdi-check-circle"
break

View File

@@ -3,7 +3,7 @@ import { useLocalStorage } from "@vueuse/core";
import { ThemeEnum } from "../enums/themeEnums";
import { LanguageEnum } from "../enums/languageEnum";
import { AccountModel } from "../models/accountModel";
import { login, register } from "../api/accountApi";
import { loginAccount, registerAccount, updateAccount } from "../api/accountApi";
import { useFeedbackStore } from "./feedbackStore";
import { BannerStateEnum } from "../enums/bannerStateEnum";
@@ -19,44 +19,60 @@ export const useUserStore = defineStore('userStore', {
async login(username: string, password: string) {
const feedbackStore = useFeedbackStore()
await login(username, password)
await loginAccount(username, password)
.then(result => {
if (result.data.loginSuccessful) {
this.userAccount = result.data.account
this.loggedIn = true
this.userAccount = result.data.account
this.loggedIn = true
feedbackStore.changeBanner(BannerStateEnum.LOGINSUCCESSFUL)
}
feedbackStore.changeBanner(BannerStateEnum.ACCOUNTLOGINSUCCESSFUL)
})
.catch(error => {
this.userAccount = new AccountModel()
this.loggedIn = false
feedbackStore.changeBanner(BannerStateEnum.WRONGLOGIN)
if (error.status == 400) {
feedbackStore.changeBanner(BannerStateEnum.ACCOUNTLOGINERROR)
} else if (error.status == 401) {
feedbackStore.changeBanner(BannerStateEnum.ACCOUNTLOGINWRONGLOGIN)
}
})
},
async registerAccount(account: AccountModel) {
async registerAccount(userAccount: AccountModel) {
const feedbackStore = useFeedbackStore()
await register(account)
await registerAccount(userAccount)
.then(res => {
console.log(res)
if (res.status == 200) {
feedbackStore.changeBanner(BannerStateEnum.REGISTERSUCCESSFUL)
if (res.status == 201) {
feedbackStore.changeBanner(BannerStateEnum.ACCOUNTREGISTERSUCCESSFUL)
}
})
.catch((error) => {
console.log(error)
if (error.status == 400) {
feedbackStore.changeBanner(BannerStateEnum.USERNAMEINUSE)
feedbackStore.changeBanner(BannerStateEnum.ACCOUNTREGISTERERROR)
} else if (error.status == 409) {
feedbackStore.changeBanner(BannerStateEnum.ACCOUNTREGISTERUSERNAMEINUSE)
}
})
},
async updateAccount() {
const feedbackStore = useFeedbackStore()
await updateAccount(this.userAccount)
.then(res => {
if (res.status == 200) {
feedbackStore.changeBanner(BannerStateEnum.ACCOUNTUPDATESUCCESSFUL)
}
})
},
logout() {
const feedbackStore = useFeedbackStore()
this.userAccount = new AccountModel()
this.loggedIn = false
feedbackStore.changeBanner(BannerStateEnum.ACCOUNTLOGOUTSUCCESSFUL)
}
}
})

View File

@@ -25,7 +25,8 @@
"productName": "Produkt Name",
"brand": "Marke",
"productPrice": "Einzelpreis",
"category": "Kategorie"
"category": "Kategorie",
"description": "Beschreibung"
},
"offers": "Angebote",
"categories": "Kategorien",
@@ -64,7 +65,20 @@
"error": "Es ist ein Fehler aufgetreten...",
"databaseResetSuccessful": "Datenbank erfolgreich zurück gesetzt!",
"registerSuccessful": "Account erfolgreich erstellt!",
"usernameInUse": "Der Accountname ist bereits vergeben!"
"usernameInUse": "Der Accountname ist bereits vergeben!",
"accountUpdated": "Account erfolgreich aktualisiert",
"logoutSuccessful": "Logout erfolgreich",
"categoryCreateSuccessful": "Kategorie hinzugefügt",
"categoryDeleteSuccessful": "Kategorie gelöscht",
"categoryCreateError": "Fehler beim Erstellen der Kategorie",
"categoryDeleteError": "Fehler beim Löschen der Kategorie",
"orderPlaceSuccessfull": "Bestellung erfolgreich aufgegeben",
"productCreateSuccessful": "Produkt hinzugefügt",
"productCreateError": "Fehler beim Erstellen des Produktes",
"productDeleteSuccessful": "Produkt erfolgreich entfernt",
"productDeleteError": "Fehler beim Entfernen des Produktes",
"basketProductAdded": "Artikel zum Warenkorb hinzugefügt",
"basketProductRemoved": "Artikel aus Warenkorb entfernt"
},
"oclock": "Uhr"
}

View File

@@ -25,7 +25,8 @@
"productName": "Product name",
"brand": "Brand",
"productPrice": "Unit price",
"category": "Category"
"category": "Category",
"description": "Description"
},
"offers": "Offers",
"categories": "Categories",
@@ -64,7 +65,20 @@
"error": "Some error occurred...",
"databaseResetSuccessful": "Database reset successful!",
"usernameInUse": "Username always in use!",
"registerSuccessful": "Account successfully created!"
"registerSuccessful": "Account successfully created!",
"accountUpdated": "Account successfully updated",
"logoutSuccessful": "Logout successful",
"categoryCreateSuccessful": "Category created",
"categoryDeleteSuccessful": "Category deleted",
"categoryCreateError": "Error on creating category",
"categoryDeleteError": "Error on deleting category",
"orderPlaceSuccessfull": "Order successfully placed",
"productCreateSuccessful": "Product created",
"productCreateError": "Error on product creation",
"productDeleteSuccessful": "Product successfully deleted",
"productDeleteError": "Error on product delete",
"basketProductAdded": "Add product to basket",
"basketProductRemoved": "Product removed from basket"
},
"oclock": "o'clock"
}

View File

@@ -0,0 +1,77 @@
<script setup lang="ts">
import { useUserStore } from '@/data/stores/userStore';
const userStore = useUserStore()
</script>
<template>
<v-card title="Account">
<v-container>
<v-row>
<v-col>
<v-text-field
:label="$t('account.username')"
v-model="userStore.userAccount.username"
disabled
/>
</v-col>
<v-col>
<v-text-field
:label="$t('account.password')"
v-model="userStore.userAccount.password"
type="password"
/>
</v-col>
</v-row>
<v-row>
<v-col>
<v-text-field
:label="$t('userInfo.firstName')"
v-model="userStore.userAccount.firstName"
/>
</v-col>
<v-col>
<v-text-field
:label="$t('userInfo.lastName')"
v-model="userStore.userAccount.lastName"
/>
</v-col>
</v-row>
<v-row>
<v-col>
<v-text-field
:label="$t('userInfo.street')"
v-model="userStore.userAccount.street"
/>
</v-col>
<v-col>
<v-text-field
:label="$t('userInfo.houseNumber')"
v-model="userStore.userAccount.houseNumber"
/>
</v-col>
</v-row>
<v-row>
<v-col>
<v-text-field
:label="$t('userInfo.postalCode')"
v-model="userStore.userAccount.postalCode"
/>
</v-col>
<v-col>
<v-text-field
:label="$t('userInfo.city')"
v-model="userStore.userAccount.city"
/>
</v-col>
</v-row>
</v-container>
<v-card-actions>
<v-btn @click="userStore.updateAccount()" >Save</v-btn>
</v-card-actions>
</v-card>
</template>

View File

@@ -1,84 +1,19 @@
<script setup lang="ts">
import { useUserStore } from '@/data/stores/userStore';
const userStore = useUserStore()
import alertBanner from '@/components/alertBanner.vue';
import accountDataCard from './accountDataCard.vue';
</script>
<template>
<v-container max-width="1000">
<v-row>
<v-col>
<v-card title="Account">
<v-container>
<v-row>
<v-col>
<v-text-field
:label="$t('account.username')"
v-model="userStore.userAccount.username"
disabled
/>
</v-col>
<v-col>
<v-text-field
:label="$t('account.password')"
v-model="userStore.userAccount.password"
type="password"
/>
</v-col>
</v-row>
<alert-banner />
</v-col>
</v-row>
<v-row>
<v-col>
<v-text-field
:label="$t('userInfo.firstName')"
v-model="userStore.userAccount.firstName"
/>
</v-col>
<v-col>
<v-text-field
:label="$t('userInfo.lastName')"
v-model="userStore.userAccount.lastName"
/>
</v-col>
</v-row>
<v-row>
<v-col>
<v-text-field
:label="$t('userInfo.street')"
v-model="userStore.userAccount.street"
/>
</v-col>
<v-col>
<v-text-field
:label="$t('userInfo.houseNumber')"
v-model="userStore.userAccount.houseNumber"
/>
</v-col>
</v-row>
<v-row>
<v-col>
<v-text-field
:label="$t('userInfo.postalCode')"
v-model="userStore.userAccount.postalCode"
/>
</v-col>
<v-col>
<v-text-field
:label="$t('userInfo.city')"
v-model="userStore.userAccount.city"
/>
</v-col>
</v-row>
</v-container>
<v-card-actions>
<!-- todo -->
<v-btn >Save</v-btn>
</v-card-actions>
</v-card>
<v-row>
<v-col>
<account-data-card />
</v-col>
</v-row>
</v-container>

View File

@@ -1,12 +1,18 @@
<script setup lang="ts">
import { useBasketStore } from '@/data/stores/basketStore';
import productsTable from './productsTable.vue';
import alertBanner from '@/components/alertBanner.vue';
const basketStore = useBasketStore()
</script>
<template>
<v-container max-width="1000">
<v-row>
<v-col>
<alert-banner />
</v-col>
</v-row>
<v-row>
<v-col>
<v-card :title="$t('menu.basket')" prepend-icon="mdi-cart">

View File

@@ -2,15 +2,13 @@
import productCard from "./productCard.vue"
import productDetails from "./productDetails.vue"
import filterBar from "./filterBar.vue"
import { Ref, ref, watch } from "vue";
import { CategoryModel } from "@/data/models/categoryModel";
import { ref, watch } from "vue";
import { FilterModel } from "@/data/models/filterModel";
import { useProductStore } from "@/data/stores/productStore";
import { useCategoryStore } from "@/data/stores/categoryStore";
import { ProductWithCategoryModel } from "@/data/models/productWithCategoryModel";
import alertBanner from "@/components/alertBanner.vue";
const productStore = useProductStore()
const categoryStore = useCategoryStore()
const showProductDetails = ref(false)
const dialogProduct = ref(new ProductWithCategoryModel())
@@ -34,6 +32,11 @@ watch(() => productStore.onlyDiscounts, async () => { productStore.filterProduct
<template>
<v-container>
<v-row>
<v-col>
<alert-banner />
</v-col>
</v-row>
<v-row>
<v-col>
<filter-bar />

View File

@@ -1,12 +1,11 @@
<script setup lang="ts">
import { VNumberInput } from 'vuetify/labs/VNumberInput'
import { ProductModel } from '@/data/models/productModel';
import { CategoryModel } from '@/data/models/categoryModel';
import { ModelRef, ref } from 'vue';
import { useBasketStore } from '@/data/stores/basketStore';
import { calcProductPrice, productToBasketItem } from '@/scripts/productScripts';
import ActionDialog from '@/components/actionDialog.vue'
import { ProductWithCategoryModel } from '@/data/models/productWithCategoryModel';
import { BasketItemModel } from '@/data/models/basketItemModel';
const showDialog: ModelRef<boolean> = defineModel()
const nrOfArticles = ref(1)
@@ -17,7 +16,10 @@ const props = defineProps({
})
function addProductToBasket() {
// todo basketStore.addItemToBasket(productToBasketItem(props.product, props.productCategory, nrOfArticles.value))
basketStore.addItemToBasket(
new BasketItemModel()
)
basketStore.addItemToBasket(productToBasketItem(props.product, nrOfArticles.value))
nrOfArticles.value = 1
showDialog.value = false
}
@@ -31,17 +33,38 @@ function addProductToBasket() {
v-model="showDialog"
>
<template #content>
<v-row>
<!-- todo <v-col>
<v-icon :icon="productCategory.icon" />
{{ productCategory.name }}
</v-col> -->
</v-row>
<v-row>
<v-col>
<v-icon :icon="product.category.icon" />
{{ product.category.name }}
</v-col>
</v-row>
<v-row>
<v-col class="text-h6">
{{ $t("product.description") }}
</v-col>
</v-row>
<v-row>
<v-col class="text-body-1">
{{ product.description }}
</v-col>
</v-row>
<v-divider class="my-4" />
<v-row>
<v-col>
<div class="d-flex align-center flex-column my-auto">
<div class="text-h3"> {{ product.rating }} <span class="text-h6 ml-n3">/5</span> </div>
<v-rating :model-value="product.rating" color="yellow-darken-3" half-increments disabled />
</div>
</v-col>
</v-row>
<v-divider class="my-4" />
<v-row>
<v-col>
<v-number-input
@@ -56,10 +79,10 @@ function addProductToBasket() {
density="comfortable"
/>
</v-col>
</v-row>
<v-spacer />
<v-col cols="2" class="justify-center d-flex">
<v-row>
<v-col class="d-flex align-center flex-column my-auto text-h3">
{{ calcProductPrice(product, nrOfArticles) }}
</v-col>
</v-row>

View File

@@ -29,7 +29,7 @@ export function calcPrice(price: number, discount: number = 0, quantity: number
*
* @returns BasketItemModel
*/
export function productToBasketItem(product: ProductModel, productCategory: CategoryModel, quantity: number): BasketItemModel {
export function productToBasketItem(product: ProductWithCategoryModel, quantity: number): BasketItemModel {
let result = new BasketItemModel()
result.productId = product.id
@@ -38,8 +38,8 @@ export function productToBasketItem(product: ProductModel, productCategory: Cate
result.brand = product.brand
result.discount = product.discount
result.name = product.name
result.categoryName = productCategory.name
result.categoryIcon = productCategory.icon
result.categoryName = product.category.name
result.categoryIcon = product.category.icon
return result
}