├── .babelrc
├── .github
├── ISSUE_TEMPLATE
│ └── bug_report.md
└── workflows
│ ├── deploy.yml
│ └── revoke-firebase-token.yml
├── .gitignore
├── .nvmrc
├── .prettierignore
├── .prettierrc.yml
├── .vscode
└── settings.json
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── dist
└── favicon.svg
├── package-lock.json
├── package.json
├── public
├── data
│ ├── ladies_outerwear.json
│ ├── ladies_tshirts.json
│ ├── mens_outerwear.json
│ ├── mens_tshirts.json
│ ├── sample_error_response.json
│ └── sample_success_response.json
├── favicon.svg
├── icon.png
├── images
│ ├── categories
│ │ ├── ladies_outerwear.jpg
│ │ ├── ladies_tshirts.jpg
│ │ ├── mens_outerwear.jpg
│ │ └── mens_tshirts.jpg
│ ├── icons
│ │ ├── shop-icon-128.png
│ │ ├── shop-icon-192.png
│ │ ├── shop-icon-32.png
│ │ ├── shop-icon-384.png
│ │ └── shop-icon-512.png
│ └── shirts
│ │ ├── 10-11017A.jpg
│ │ ├── 10-11017B.jpg
│ │ ├── 10-11019A.jpg
│ │ ├── 10-11019B.jpg
│ │ ├── 10-13018A.jpg
│ │ ├── 10-13018B.jpg
│ │ ├── 10-13058A.jpg
│ │ ├── 10-13058B.jpg
│ │ ├── 10-13097A.jpg
│ │ ├── 10-13097B.jpg
│ │ ├── 10-13130A.jpg
│ │ ├── 10-13130B.jpg
│ │ ├── 10-13153A.jpg
│ │ ├── 10-13153B.jpg
│ │ ├── 10-13213A.jpg
│ │ ├── 10-13213B.jpg
│ │ ├── 10-13239A.jpg
│ │ ├── 10-13239B.jpg
│ │ ├── 10-13240A.jpg
│ │ ├── 10-13240B.jpg
│ │ ├── 10-13241A.jpg
│ │ ├── 10-13241B.jpg
│ │ ├── 10-13256A.jpg
│ │ ├── 10-13256B.jpg
│ │ ├── 10-13260A.jpg
│ │ ├── 10-13260B.jpg
│ │ ├── 10-13262A.jpg
│ │ ├── 10-13262B.jpg
│ │ ├── 10-13263A.jpg
│ │ ├── 10-13263B.jpg
│ │ ├── 10-13264A.jpg
│ │ ├── 10-13264B.jpg
│ │ ├── 10-13265A.jpg
│ │ ├── 10-13265B.jpg
│ │ ├── 10-13266A.jpg
│ │ ├── 10-13266B.jpg
│ │ ├── 10-13267A.jpg
│ │ ├── 10-13267B.jpg
│ │ ├── 10-13268A.jpg
│ │ ├── 10-13268B.jpg
│ │ ├── 10-13269A.jpg
│ │ ├── 10-13269B.jpg
│ │ ├── 10-13270A.jpg
│ │ ├── 10-13270B.jpg
│ │ ├── 10-13271A.jpg
│ │ ├── 10-13271B.jpg
│ │ ├── 10-13272A.jpg
│ │ ├── 10-13272B.jpg
│ │ ├── 10-13273A.jpg
│ │ ├── 10-13273B.jpg
│ │ ├── 10-13274A.jpg
│ │ ├── 10-13274B.jpg
│ │ ├── 10-13275A.jpg
│ │ ├── 10-13275B.jpg
│ │ ├── 10-13276A.jpg
│ │ ├── 10-13276B.jpg
│ │ ├── 10-13277A.jpg
│ │ ├── 10-13277B.jpg
│ │ ├── 10-13278A.jpg
│ │ ├── 10-13278B.jpg
│ │ ├── 10-13279A.jpg
│ │ ├── 10-13279B.jpg
│ │ ├── 10-13280A.jpg
│ │ ├── 10-13280B.jpg
│ │ ├── 10-13282A.jpg
│ │ ├── 10-13282B.jpg
│ │ ├── 10-13285A.jpg
│ │ ├── 10-13285B.jpg
│ │ ├── 10-13286A.jpg
│ │ ├── 10-13286B.jpg
│ │ ├── 10-13288A.jpg
│ │ ├── 10-13288B.jpg
│ │ ├── 10-13289A.jpg
│ │ ├── 10-13289B.jpg
│ │ ├── 10-13290A.jpg
│ │ ├── 10-13290B.jpg
│ │ ├── 10-13291A.jpg
│ │ ├── 10-13291B.jpg
│ │ ├── 10-13292A.jpg
│ │ ├── 10-13292B.jpg
│ │ ├── 10-14133A.jpg
│ │ ├── 10-14133B.jpg
│ │ ├── 10-14146A.jpg
│ │ ├── 10-14146B.jpg
│ │ ├── 10-14152A.jpg
│ │ ├── 10-14152B.jpg
│ │ ├── 10-14153A.jpg
│ │ ├── 10-14153B.jpg
│ │ ├── 10-14154A.jpg
│ │ ├── 10-14154B.jpg
│ │ ├── 10-14155A.jpg
│ │ ├── 10-14155B.jpg
│ │ ├── 10-14157A.jpg
│ │ ├── 10-14157B.jpg
│ │ ├── 10-14158A.jpg
│ │ ├── 10-14158B.jpg
│ │ ├── 10-14159A.jpg
│ │ ├── 10-14159B.jpg
│ │ ├── 10-14160A.jpg
│ │ ├── 10-14160B.jpg
│ │ ├── 10-14215A.jpg
│ │ ├── 10-14215B.jpg
│ │ ├── 10-14216A.jpg
│ │ ├── 10-14216B.jpg
│ │ ├── 10-14217A.jpg
│ │ ├── 10-14217B.jpg
│ │ ├── 10-15041A.jpg
│ │ ├── 10-15041B.jpg
│ │ ├── 10-15068A.jpg
│ │ ├── 10-15068B.jpg
│ │ ├── 10-15103A.jpg
│ │ ├── 10-15103B.jpg
│ │ ├── 10-23069A.jpg
│ │ ├── 10-23069B.jpg
│ │ ├── 10-23073A.jpg
│ │ ├── 10-23073B.jpg
│ │ ├── 10-23169A.jpg
│ │ ├── 10-23169B.jpg
│ │ ├── 10-23171A.jpg
│ │ ├── 10-23171B.jpg
│ │ ├── 10-23172A.jpg
│ │ ├── 10-23172B.jpg
│ │ ├── 10-23173A.jpg
│ │ ├── 10-23173B.jpg
│ │ ├── 10-23174A.jpg
│ │ ├── 10-23174B.jpg
│ │ ├── 10-23176A.jpg
│ │ ├── 10-23176B.jpg
│ │ ├── 10-23177A.jpg
│ │ ├── 10-23177B.jpg
│ │ ├── 10-23178A.jpg
│ │ ├── 10-23178B.jpg
│ │ ├── 10-23179A.jpg
│ │ ├── 10-23179B.jpg
│ │ ├── 10-23180A.jpg
│ │ ├── 10-23180B.jpg
│ │ ├── 10-23198A.jpg
│ │ ├── 10-23198B.jpg
│ │ ├── 10-23225A.jpg
│ │ ├── 10-23225B.jpg
│ │ ├── 10-23226A.jpg
│ │ ├── 10-23226B.jpg
│ │ ├── 10-23227A.jpg
│ │ ├── 10-23227B.jpg
│ │ ├── 10-23228A.jpg
│ │ ├── 10-23228B.jpg
│ │ ├── 10-23229A.jpg
│ │ ├── 10-23229B.jpg
│ │ ├── 10-23230A.jpg
│ │ ├── 10-23230B.jpg
│ │ ├── 10-24097A.jpg
│ │ ├── 10-24097B.jpg
│ │ ├── 10-24098A.jpg
│ │ ├── 10-24098B.jpg
│ │ ├── 10-24099A.jpg
│ │ ├── 10-24099B.jpg
│ │ ├── 10-24101A.jpg
│ │ ├── 10-24101B.jpg
│ │ ├── 10-24102A.jpg
│ │ ├── 10-24102B.jpg
│ │ ├── 10-25058A.jpg
│ │ └── 10-25058B.jpg
├── logo192.png
├── logo512.png
├── manifest.json
└── robots.txt
├── src
├── App.css
├── App.tsx
├── Store
│ ├── Cart.css
│ ├── Cart.tsx
│ ├── CartContext.tsx
│ ├── CartItem.tsx
│ ├── Category.css
│ ├── Category.tsx
│ ├── Checkout.css
│ ├── Checkout.tsx
│ ├── Confirmation.tsx
│ ├── GooglePay.tsx
│ ├── Header.css
│ ├── Header.tsx
│ ├── Home.css
│ ├── Home.tsx
│ ├── ItemDetails.css
│ ├── ItemDetails.tsx
│ ├── List.css
│ ├── List.tsx
│ ├── ListItem.tsx
│ ├── Status.css
│ ├── StorageProvider.tsx
│ ├── StoreData.tsx
│ └── StoreService.tsx
├── config
│ ├── CategoryDetails.tsx
│ ├── GooglePay.tsx
│ └── ShippingOptions.tsx
├── index.css
├── index.ejs
├── index.tsx
└── interfaces
│ ├── CartItemDetails.tsx
│ ├── CategoryDetails.tsx
│ └── ItemDetails.tsx
├── tsconfig.json
└── webpack.config.cjs
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | "@babel/env",
4 | "@babel/preset-react"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Go to '...'
16 | 2. Click on '....'
17 | 3. Scroll down to '....'
18 | 4. See error
19 |
20 | **Expected behavior**
21 | A clear and concise description of what you expected to happen.
22 |
23 | **Screenshots**
24 | If applicable, add screenshots to help explain your problem.
25 |
26 | **Desktop (please complete the following information):**
27 | - OS: [e.g. iOS]
28 | - Browser [e.g. chrome, safari]
29 | - Version [e.g. 22]
30 |
31 | **Smartphone (please complete the following information):**
32 | - Device: [e.g. iPhone6]
33 | - OS: [e.g. iOS8.1]
34 | - Browser [e.g. stock browser, safari]
35 | - Version [e.g. 22]
36 |
37 | **Additional context**
38 | Add any other context about the problem here.
39 |
--------------------------------------------------------------------------------
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: deploy
2 |
3 | on:
4 | push:
5 | branches:
6 | - google-pay
7 |
8 | jobs:
9 | build:
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - uses: actions/checkout@v2
14 | - name: Use Node.js 10.x
15 | uses: actions/setup-node@v1
16 | with:
17 | node-version: 10.x
18 | - run: npm install --global firebase-tools
19 | - run: npm install
20 | - run: firebase deploy --project ${{secrets.FIREBASE_PROJECT}}
21 | env:
22 | FIREBASE_TOKEN: ${{secrets.FIREBASE_TOKEN}}
23 |
--------------------------------------------------------------------------------
/.github/workflows/revoke-firebase-token.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2024 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # http://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | name: Revoke Firebase Token
16 |
17 | on:
18 | workflow_dispatch:
19 |
20 | jobs:
21 | build:
22 | runs-on: ubuntu-latest
23 | steps:
24 | - name: Revoke Firebase Token
25 | run: curl -H "Content-type:application/x-www-form-urlencoded" -s https://accounts.google.com/o/oauth2/revoke?token=${{secrets.FIREBASE_TOKEN}}
26 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Dependencies
2 | /node_modules
3 | /.pnp
4 | .pnp.js
5 |
6 | # Testing
7 | /coverage
8 |
9 | # Build
10 | /dist/bundle.js
11 | /dist/index.html
12 |
13 | # Misc
14 | .DS_Store
15 |
--------------------------------------------------------------------------------
/.nvmrc:
--------------------------------------------------------------------------------
1 | lts/*
2 |
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | .github/
2 | .vscode/
3 | node_modules/
4 | build/
5 | dist/
6 |
--------------------------------------------------------------------------------
/.prettierrc.yml:
--------------------------------------------------------------------------------
1 | # Copyright 2022 Google LLC
2 | #
3 | # Licensed under the Apache License, Version 2.0 (the "License");
4 | # you may not use this file except in compliance with the License.
5 | # You may obtain a copy of the License at
6 | #
7 | # https://www.apache.org/licenses/LICENSE-2.0
8 | #
9 | # Unless required by applicable law or agreed to in writing, software
10 | # distributed under the License is distributed on an "AS IS" BASIS,
11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | # See the License for the specific language governing permissions and
13 | # limitations under the License.
14 |
15 | arrowParens: avoid
16 | printWidth: 120
17 | quoteProps: consistent
18 | semi: true
19 | singleQuote: true
20 | tabWidth: 2
21 | trailingComma: none
22 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.codeActionsOnSave": {
3 | "source.fixAll.eslint": true
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # How to Contribute
2 |
3 | We'd love to accept your patches and contributions to this project.
4 |
5 | ## Before you begin
6 |
7 | ### Sign our Contributor License Agreement
8 |
9 | Contributions to this project must be accompanied by a
10 | [Contributor License Agreement](https://cla.developers.google.com/about) (CLA).
11 | You (or your employer) retain the copyright to your contribution; this simply
12 | gives us permission to use and redistribute your contributions as part of the
13 | project.
14 |
15 | If you or your current employer have already signed the Google CLA (even if it
16 | was for a different project), you probably don't need to do it again.
17 |
18 | Visit to see your current agreements or to
19 | sign a new one.
20 |
21 | ### Review our Community Guidelines
22 |
23 | This project follows [Google's Open Source Community
24 | Guidelines](https://opensource.google/conduct/).
25 |
26 | ## Contribution process
27 |
28 | ### Code Reviews
29 |
30 | All submissions, including submissions by project members, require review. We
31 | use GitHub pull requests for this purpose. Consult
32 | [GitHub Help](https://help.github.com/articles/about-pull-requests/) for more
33 | information on using pull requests.
34 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
203 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Sample React T-Shirt Store
2 |
3 | The purpose this repository is to showcase the Google Pay integration in a store
4 | built with React.
5 |
6 | A deployed version of this app can be found at this link.
7 |
8 | **Note:** This sample app is not intended for use in a production environment!
9 | Please do not attempt to use it in this manner. For more information on
10 | deploying apps to production, see the
11 | [React documentation](https://create-react-app.dev/docs/deployment/).
12 |
13 | ## Prerequisites
14 |
15 | To configure and run this sample app, you will need the following prerequisites
16 | installed on your workstation:
17 |
18 | * [Node.js and NPM](https://docs.npmjs.com/downloading-and-installing-node-js-and-npm)
19 | * Any prerequisites included in the
20 | [React Documentation](https://reactjs.org/docs/getting-started.html)
21 |
22 | ## Setup
23 |
24 | Once the prerequisites are installed, follow the below steps to set up and use
25 | this sample app:
26 |
27 | 1. Clone this repository
28 | 1. In your terminal, navigate to the repository location
29 |
30 | ```bash
31 | cd /path/to/repo
32 | ```
33 |
34 | 1. Install the Node.js dependencies
35 |
36 | ```bash
37 | npm install .
38 | ```
39 |
40 | 1. Build `index.html` and `bundle.js`
41 |
42 | ```bash
43 | npm run build
44 | ```
45 |
46 | ## Usage
47 |
48 | ### Development server
49 |
50 | To start a development server, follow the below steps:
51 |
52 | 1. In your terminal, run `npm start`
53 | 1. In your web browser, open `http://localhost:3000/`
54 |
55 | The app will automatically reload if you change any of the source files. You
56 | will also see any lint errors in the console.
57 |
58 | ### Build
59 |
60 | This command builds the app and outputs the results to the `dist/` directory.
61 | It bundles React in production mode and optimizes the build for the best
62 | performance. The build is minified and the filenames include the hashes.
63 |
64 | 1. In your terminal, run `npm run build`
65 |
66 | ## Support
67 |
68 | For more information about React, refer to the
69 | [React documentation](https://reactjs.org/).
70 |
71 | For any questions on this sample app, please
72 | [submit an issue](https://github.com/google-pay/angular-store/issues/new) to
73 | this repository.
74 |
--------------------------------------------------------------------------------
/dist/favicon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "react-store",
3 | "version": "0.1.0",
4 | "description": "A sample React app that implements Google Pay.",
5 | "main": "index.js",
6 | "scripts": {
7 | "start": "webpack-dev-server --mode development --hot",
8 | "build": "webpack --mode development"
9 | },
10 | "author": "Nick Alteen",
11 | "devDependencies": {
12 | "@babel/cli": "^7.19.3",
13 | "@babel/core": "^7.20.5",
14 | "@babel/preset-env": "^7.20.2",
15 | "@babel/preset-react": "^7.18.6",
16 | "@testing-library/jest-dom": "^5.16.5",
17 | "@testing-library/react": "^13.4.0",
18 | "@testing-library/user-event": "^14.4.3",
19 | "babel-loader": "^9.1.0",
20 | "css-loader": "^6.7.2",
21 | "ejs-loader": "^0.5.0",
22 | "html-webpack-plugin": "^5.5.0",
23 | "react-refresh": "^0.14.0",
24 | "style-loader": "^3.3.1",
25 | "ts-loader": "^9.4.2",
26 | "typescript": "^4.9.4",
27 | "webpack": "^5.75.0",
28 | "webpack-cli": "^5.0.1",
29 | "webpack-dev-server": "^4.11.1"
30 | },
31 | "dependencies": {
32 | "@emotion/react": "^11.10.5",
33 | "@emotion/styled": "^11.10.5",
34 | "@google-pay/button-react": "^3.0.5",
35 | "@mui/icons-material": "^5.10.16",
36 | "@mui/material": "^5.10.17",
37 | "@types/googlepay": "^0.6.4",
38 | "@types/jest": "^29.2.4",
39 | "@types/node": "^18.11.13",
40 | "@types/react": "^18.0.26",
41 | "@types/react-dom": "^18.0.9",
42 | "dotenv": "^16.0.3",
43 | "handlebars-loader": "^1.7.3",
44 | "query-string": "^8.0.0",
45 | "react": "^18.2.0",
46 | "react-dom": "^18.2.0",
47 | "react-router-dom": "^6.4.5"
48 | }
49 | }
50 |
--------------------------------------------------------------------------------
/public/data/ladies_outerwear.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name":"Ladies+Modern+Stretch+Full+Zip",
4 | "title":"Ladies Modern Stretch Full Zip",
5 | "category":"ladies_outerwear",
6 | "price":41.60,
7 | "description":"With an updated fit and figure-flattering details, this full-zip combines ultra soft cotton with a dash of spandex to retain its shape all day long. <div><br></div><div>Features:</div><div><ul><li>96% cotton, 4% spandex.</li><li>Gently contoured silhouette & longer length design for a style that moves with you.</li><li>Self-fabric hood.</li><li>Dyed-to-match zipper. </li><li>Front slash pockets.</li><li>Open cuffs & hem.</li><li>Available in Mosaic Blue with the white Google logo embroidered at left chest. </li></ul></div>",
8 | "image":"/images/shirts/10-24102B.jpg",
9 | "largeImage":"/images/shirts/10-24102A.jpg"
10 | },
11 | {
12 | "name":"Ladies+Colorblock+Wind+Jacket",
13 | "title":"Ladies Colorblock Wind Jacket",
14 | "category":"ladies_outerwear",
15 | "price":45.90,
16 | "description":"Brighten up your commute on gloomy days. This lightweight jacket features a subtle grid texture and a punch of bright pink at each side panel.<div><br></div><div>Features:</div><div><ul><li>100% polyester dobby shell with jersey lining.</li><li>Packable zip-in hood with contrast pink zipper.</li><li>Cadet collar and elastic cuffs.</li><li>Adjustable toggles at waist can be cinched for a flattering fit.</li><li>Available in grey/dark rose with the white Google logo embroidered at left chest.</li></ul></div>",
17 | "image":"/images/shirts/10-25058B.jpg",
18 | "largeImage":"/images/shirts/10-25058A.jpg"
19 | },
20 | {
21 | "name":"Ladies+Voyage+Fleece+Jacket",
22 | "title":"Ladies Voyage Fleece Jacket",
23 | "category":"ladies_outerwear",
24 | "price":48.00,
25 | "description":"<div>Perhaps the equivalent to that comfort blanket you had years ago is a cozy fleece. This full-zip is the perfect layering piece for those 'in-between' months when mother nature just can't make up her mind. </div><div><br></div><div>Features:</div><div><ul><li>100% polyester anti-pill yarn fleece.</li><li>100% polyester taffeta lining in sleeves.</li><li>Tricot-lined lower pockets with reverse coil zippers.</li><li>Available in purple with the white Google logo embroidered at left chest.</li><li><b>Please note! Sizing runs larger than normal. Consider ordering a size smaller than normal.</b></li></ul></div>",
26 | "image":"/images/shirts/10-24101B.jpg",
27 | "largeImage":"/images/shirts/10-24101A.jpg"
28 | },
29 | {
30 | "name":"Ladies+Pullover+L+S+Hood",
31 | "title":"Ladies Pullover L/S Hood",
32 | "category":"ladies_outerwear",
33 | "price":36.50,
34 | "description":"A longsleeve layering piece with a hood. What more can you ask for between season changes? <div><br></div><div>Features:</div><div><ul><li>85% polyester, 15% cotton.</li><li>Ultra lightweight, tissue jersey fabric.</li><li>Scoop-neck with hood.</li><li>Available in jewel blue with the white Google logo screenprinted across center chest.</li></ul></div>",
35 | "image":"/images/shirts/10-24098B.jpg",
36 | "largeImage":"/images/shirts/10-24098A.jpg"
37 | },
38 | {
39 | "name":"Ladies+Sonoma+Hybrid+Knit+Jacket",
40 | "title":"Ladies Sonoma Hybrid Knit Jacket",
41 | "category":"ladies_outerwear",
42 | "price":84.85,
43 | "description":"A modern styled sport jacket that combines a classic silhouette with moisture-wicking fabrics. Technical features include a reversed coil zipper with reflective stripe, interior media exit port, and built-in media pocket. <div><br></div><div>Additional Features:</div><div><ul><li>94% polyester, 6% spandex.</li><li>Available in black with the white Google logo heat transferred onto right hip along zipper.</li></ul></div>",
44 | "image":"/images/shirts/10-24097B.jpg",
45 | "largeImage":"/images/shirts/10-24097A.jpg"
46 | },
47 | {
48 | "name":"Ladies+Yerba+Knit+Quarter+Zip",
49 | "title":"Ladies Yerba Knit Quarter Zip",
50 | "category":"ladies_outerwear",
51 | "price":64.20,
52 | "description":"This on-trend quarter zip doubles as workout gear. <div><br></div><div>Features:</div><div><ul><li>81% polyester, 19% spandex jersey knit.</li><li>Textured knit fabric features a moisture-wicking finish.</li><li>Exposed contrast reverse coil zipper with contrast inner collar.</li><li>Lightweight design with added stretch.</li><li>Available in heathered indigo with the white Google logo heat transferred vertically onto front right hip.</li></ul></div>",
53 | "image":"/images/shirts/10-24099B.jpg",
54 | "largeImage":"/images/shirts/10-24099A.jpg"
55 | }
56 | ]
57 |
--------------------------------------------------------------------------------
/public/data/ladies_tshirts.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name":"Ladies+Chrome+T-Shirt",
4 | "title":"Ladies Chrome T-Shirt",
5 | "category":"ladies_tshirts",
6 | "price":13.30,
7 | "description":"The best of three fabrics combined into one seductively-soft tee. <div><br></div><div>Features:</div><div><ul><li>50% polyester, 25% combed and ring-spun cotton, 25% rayon.</li><li>Side-seamed.</li><li>Semi-relaxed fit. </li><li>Available in heather blue with the white Google Chrome logo screenprinted at center chest. </li></ul></div>",
8 | "image":"/images/shirts/10-23180B.jpg",
9 | "largeImage":"/images/shirts/10-23180A.jpg"
10 | },
11 | {
12 | "name":"Ladies+Google+New+York+T-Shirt",
13 | "title":"Ladies Google New York T-Shirt",
14 | "category":"ladies_tshirts",
15 | "price":18.35,
16 | "description":"Are you feeling lucky? Inspired by city lights in The Big Apple, this tee features the 'I'm Feeling Lucky New York' phrase at back.<div><br></div><div>Features:</div><div><ul><li>100% cotton.</li><li>American Apparel shirt designed with a ladies fit in mind.</li><li>Available in Black with the Google logo and 'I'm Feeling Lucky' New York printed on back yoke in White.</li><li><b>Sizing runs smaller than normal. Please reference size chart before ordering.</b></li></ul></div>",
17 | "image":"/images/shirts/10-23226B.jpg",
18 | "largeImage":"/images/shirts/10-23226A.jpg"
19 | },
20 | {
21 | "name":"Ladies+Gmail+T-Shirt",
22 | "title":"Ladies Gmail T-Shirt",
23 | "category":"ladies_tshirts",
24 | "price":16.40,
25 | "description":"Show your inbox some love. The new Gmail tee has arrived, complete with a subtle Mvelope design that showcases all of the Gmail icons you use on the daily.<div><br></div><div>Features:</div><div><ul><li>50% polyester, 25% cotton.</li><li>Bella+Canvas.</li><li>Available in vintage red with the new Gmail print screenprinted across center chest.</li></ul></div>",
26 | "image":"/images/shirts/10-23179B.jpg",
27 | "largeImage":"/images/shirts/10-23179A.jpg"
28 | },
29 | {
30 | "name":"Ladies+G+Logo+White+T-Shirt",
31 | "title":"Ladies G Logo White T-Shirt",
32 | "category":"ladies_tshirts",
33 | "price":13.30,
34 | "description":"There's a new G in town and it's here to stay. Get your hands on this comfy white tee with the new Google icon. \n\n<div><br></div><div>Features: </div><div><ul><li>100% combed and ring-spun cotton.</li><li>Side seamed, relaxed fit.</li><li>Bella+Canvas.</li><li>Available in white with the Google 'G' icon screenprinted at front.</li></ul></div>",
35 | "image":"/images/shirts/10-23178B.jpg",
36 | "largeImage":"/images/shirts/10-23178A.jpg"
37 | },
38 | {
39 | "name":"Ladies+Android+Pride+T-Shirt",
40 | "title":"Ladies Android Pride T-Shirt",
41 | "category":"ladies_tshirts",
42 | "price":19.10,
43 | "description":"Stand out proud in this Ladies' Android Pride T-shirt. <div><br></div><div>Features:</div><div><ul><li>100% cotton.</li><li>Available in black and features two Androids holding hands and waving a rainbow flag printed across the front. Google logo screen printed in white on the sleeve. </li><li><b>Sizing runs smaller than normal. Please reference size chart before ordering.</b></li></ul></div>",
44 | "image":"/images/shirts/10-23177B.jpg",
45 | "largeImage":"/images/shirts/10-23177A.jpg"
46 | },
47 | {
48 | "name":"Ladies+Ringspun+Crew+Neck",
49 | "title":"Ladies Ringspun Crew Neck",
50 | "category":"ladies_tshirts",
51 | "price":19.70,
52 | "description":"Cheery colors make the world a happier place. This bright pink tee is ultra soft and features a comfortable, ladies fit.<div><br></div><div>Features:</div><div><ul><li>100% cotton.</li><li>Tagless label for added comfort.</li><li><b>Relaxed fit.</b></li><li>Available in hot pink with the white Google logo screenprinted at center chest.</li></ul></div>",
53 | "image":"/images/shirts/10-23172B.jpg",
54 | "largeImage":"/images/shirts/10-23172A.jpg"
55 | },
56 | {
57 | "name":"Ladies+Tri-Blend+V-Neck+T-Shirt",
58 | "title":"Ladies Tri-Blend V-Neck T-Shirt",
59 | "category":"ladies_tshirts",
60 | "price":35.10,
61 | "description":"A tagless label, ultra soft triblend fabric and v-neck cut are three ingredients for a favorite tee. <div><br></div><div>Features:</div><div><ul><li>25% cotton, 50% polyester, 25% rayon.</li><li>Made in California.</li><li>Available in green with the white Google logo screenprinted at center chest.</li></ul></div>",
62 | "image":"/images/shirts/10-23227B.jpg",
63 | "largeImage":"/images/shirts/10-23227A.jpg"
64 | },
65 | {
66 | "name":"Bella+Ladies+Favorite+Tee",
67 | "title":"Bella Ladies Favorite Tee",
68 | "category":"ladies_tshirts",
69 | "price":10.50,
70 | "description":"This ladies tee features a longer body length perfect for layering up. <div><br></div><div>Features:</div><div><ul><li>100% combed, ringspun cotton.</li><li>Extra soft, lightweight fabric.</li><li><b>Slim fit. Runs small. </b></li><li>Available in aqua with the white Google logo screenprinted at center chest.</li></ul></div>",
71 | "image":"/images/shirts/10-23228B.jpg",
72 | "largeImage":"/images/shirts/10-23228A.jpg"
73 | },
74 | {
75 | "name":"Ladies+Bamboo+T-Shirt",
76 | "title":"Ladies Bamboo T-Shirt",
77 | "category":"ladies_tshirts",
78 | "price":20.65,
79 | "description":"A bamboo tee that's softer than your favorite cotton t-shirt. Your skin will thank you during those long nights of programming. <div><br></div><div>Features:</div><div><ul><li>70% viscose from organic bamboo, 30% organic cotton.</li><li>Available in vintage pink with the white Google logo screen printed at center chest.</li></ul></div>",
80 | "image":"/images/shirts/10-23176B.jpg",
81 | "largeImage":"/images/shirts/10-23176A.jpg"
82 | },
83 | {
84 | "name":"Ladies+L+S+Colorblock+Raglan",
85 | "title":"Ladies L/S Colorblock Raglan",
86 | "category":"ladies_tshirts",
87 | "price":36.95,
88 | "description":"Add a dose of mango to your t-shirt lineup. This scoop neck raglan features a bright pop of color and a scoop neck with v-notch.<div><br></div><div>Features:</div><div><ul><li>60% cotton, 40% polyester.</li><li>Scoop hem.</li><li>Self-fabric cuff bands.</li><li>Available in heather/mango with the white Google logo screenprinted at center chest.</li></ul></div>",
89 | "image":"/images/shirts/10-23173B.jpg",
90 | "largeImage":"/images/shirts/10-23173A.jpg"
91 | },
92 | {
93 | "name":"Bella+Scoop-Neck+Ladies+T-Shirt",
94 | "title":"Bella Scoop-Neck Ladies T-Shirt",
95 | "category":"ladies_tshirts",
96 | "price":13.10,
97 | "description":"A classic that's here to stay is this ladies white baby ribbed tee. Features a feminine scoop cut at the neck and 1x1 baby rib texture. Available in white with the full color Google logo screen printed at center chest.",
98 | "image":"/images/shirts/10-23171B.jpg",
99 | "largeImage":"/images/shirts/10-23171A.jpg"
100 | },
101 | {
102 | "name":"Ladies+Not+For+Sale+T-Shirt",
103 | "title":"Ladies Not For Sale T-Shirt",
104 | "category":"ladies_tshirts",
105 | "price":24.00,
106 | "description":"This Not for Sale t-shirt features just the right amount of 'V' around the neck with the Google logo placed perfectly underneath. Not for Sale focuses efforts on growing social enterprises to benefit those enslaved and vulnerable communities around the world. <div><br></div><div>Features:</div><div><ul><li>Available in black with the Google logo imprinted in white across upper chest.</li><li><b>Sizing runs smaller than normal. Please consider ordering up one or two sizes.</b></li></ul></div>",
107 | "image":"/images/shirts/10-23225B.jpg",
108 | "largeImage":"/images/shirts/10-23225A.jpg"
109 | },
110 | {
111 | "name":"Ladies+Android+L+S+Stretch+T-Shirt",
112 | "title":"Ladies Android L/S Stretch T-Shirt",
113 | "category":"ladies_tshirts",
114 | "price":20.00,
115 | "description":"Sparkle and shine in this ladies long sleeve stretch tee. <div><br></div><div>Features;</div><div><ul><li>95% premium, ring-spun cotton, 5% spandex.</li><li>Available in Black with a glitter Android robot at left chest.</li></ul></div>",
116 | "image":"/images/shirts/10-23198B.jpg",
117 | "largeImage":"/images/shirts/10-23198A.jpg"
118 | },
119 | {
120 | "name":"Ladies+Mountain+View+T-Shirt",
121 | "title":"Ladies Mountain View T-Shirt",
122 | "category":"ladies_tshirts",
123 | "price":17.50,
124 | "description":"The Bay Area city named for its beautiful views of the Santa Cruz Mountains is also home to the Googleplex located at 1600 Amphitheater Parkway. Celebrate the place Google calls home in this ladies scoop neck tee.<div><br></div><div>Features:</div><div><ul><li>100% cotton.</li><li>Available in white with the Mountain View coordinates screenprinted at front and the full color Google logo screenprinted at back yoke.</li></ul></div>",
125 | "image":"/images/shirts/10-23229B.jpg",
126 | "largeImage":"/images/shirts/10-23229A.jpg"
127 | },
128 | {
129 | "name":"Ladies+Blueprint+for+a+Better+Inbox+T-Shirt",
130 | "title":"Ladies Blueprint for a Better Inbox T-Shirt",
131 | "category":"ladies_tshirts",
132 | "price":14.30,
133 | "description":"The \"Blueprint for better Inbox\" now available for the ladies! This USA made American Apparel t-shirt sports a more fitted design and the new Inbox logo. <div><br></div><div>Additional Features: </div><div><ul><li>50% cotton / 50% polyester for a super soft fit.</li><li>Available in royal blue heather with the \"New Inbox: logo screen printed on the center chest. </li><li><b>Sizing runs smaller than normal. Please reference sizing chart prior to ordering.</b></li></ul></div>",
134 | "image":"/images/shirts/10-23169B.jpg",
135 | "largeImage":"/images/shirts/10-23169A.jpg"
136 | },
137 | {
138 | "name":"Ladies+Cotton+Poly+w++Thermal+Tee",
139 | "title":"Ladies Cotton Poly w/ Thermal Tee",
140 | "category":"ladies_tshirts",
141 | "price":15.15,
142 | "description":"This thermal long sleeve t-shirt is lightweight enough for all seasons of the year. <div><br></div><div>Features:</div><div><ul><li>60% cotton, 40% polyester.</li><li>Wide boat neck, thermal sleeves and hight length thermal cuffs.</li><li>Longer body for comfortable fit.</li><li>Available in blue/black with the white Google logo screenprinted at center chest.</li></ul></div>",
143 | "image":"/images/shirts/10-23174B.jpg",
144 | "largeImage":"/images/shirts/10-23174A.jpg"
145 | },
146 | {
147 | "name":"Ladies+YouTube+Favorite+Tee",
148 | "title":"Ladies YouTube Favorite Tee",
149 | "category":"ladies_tshirts",
150 | "price":11.10,
151 | "description":"It's called the 'favorite tee' for a reason. Designed with fashion and comfort in mind, this ladies tee is ultra soft and provides a great fit, every time. <div><br></div><div>Features:</div><div><ul><li>100% combed, ring-spun cotton.</li><li>Designed with a longer length for varying body types. </li><li>Available in asphalt with the full color YouTube logo screen printed across center chest.</li></ul></div>",
152 | "image":"/images/shirts/10-23073B.jpg",
153 | "largeImage":"/images/shirts/10-23073A.jpg"
154 | },
155 | {
156 | "name":"MTV+Ladies+Yellow+T-Shirt",
157 | "title":"MTV Ladies Yellow T-Shirt",
158 | "category":"ladies_tshirts",
159 | "price":16.90,
160 | "description":"They say home is where the heart is. This vibrant tee features the Bay Area address of Google's head office. <div><br></div><div>Features:</div><div><ul><li>100% combed cotton.</li><li>Made in the USA. </li><li>Available in gold with a striking design at front and the white Google logo at back yoke. </li></ul></div>",
161 | "image":"/images/shirts/10-23230B.jpg",
162 | "largeImage":"/images/shirts/10-23230A.jpg"
163 | },
164 | {
165 | "name":"Women+s+Android+Heart+T-Shirt",
166 | "title":"Women's Android Heart T-Shirt",
167 | "category":"ladies_tshirts",
168 | "price":10.60,
169 | "description":"The softest, smoothest, best-looking, organic cotton tee shirt available anywhere. <div><br></div><div>Features:</div><div><ul><li>100% certified organic, combed, ringspun cotton.</li><li>Contoured to flatter women's curves.</li><li>Double-needle stitching on the sleeves and bottom hem.</li><li>TearAway™ label for added comfort. </li><li>Available in Berry with a screened Android robot at front chest.</li></ul></div>",
170 | "image":"/images/shirts/10-23069B.jpg",
171 | "largeImage":"/images/shirts/10-23069A.jpg"
172 | }
173 | ]
174 |
--------------------------------------------------------------------------------
/public/data/mens_outerwear.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name":"Men+s+Tech+Shell+Full-Zip",
4 | "title":"Men's Tech Shell Full-Zip",
5 | "category":"mens_outerwear",
6 | "price":50.20,
7 | "description":"A versatile full-zip that you can wear all day long and even to the gym. This technical shell features moisture-wicking fabric, added stretch and a hidden pocket for your smartphone or media player. <div><br></div><div>Features:</div><div><ul><li>100% polyester.</li><li>Smooth, technical front with textured mesh back.</li><li>Drawstring bottom for adjustable fit.</li><li>Raglan sleeves.</li><li>Available in forest green with the white Google logo embroidered at left chest.</li></ul></div>",
8 | "image":"/images/shirts/10-15068B.jpg",
9 | "largeImage":"/images/shirts/10-15068A.jpg"
10 | },
11 | {
12 | "name":"Anvil+L+S+Crew+Neck+-+Grey",
13 | "title":"Anvil L/S Crew Neck - Grey",
14 | "category":"mens_outerwear",
15 | "price":22.15,
16 | "description":"You'll be swooning over this crew neck as soon as you feel how soft it is. <div><br></div><div>Features:</div><div><ul><li>40% preshrunk ring-spun cotton, 60% polyester terry fleece. </li><li>Available in dark heather charcoal with the white Google logo screen printed across center chest.</li></ul></div>",
17 | "image":"/images/shirts/10-14154B.jpg",
18 | "largeImage":"/images/shirts/10-14154A.jpg"
19 | },
20 | {
21 | "name":"Green+Flex+Fleece+Zip+Hoodie",
22 | "title":"Green Flex Fleece Zip Hoodie",
23 | "category":"mens_outerwear",
24 | "price":45.65,
25 | "description":"Ultra soft. Ultra cozy. Our popular flex fleece hoodie now available in speckled green. <div><br></div><div>Features:</div><div><ul><li>50% cotton / 50% polyester. </li><li>Made in the USA. </li><li>Full-zip. </li><li>Available in green with specks of blue and the white Google logo embroidered at left bicep. </li></ul></div>",
26 | "image":"/images/shirts/10-14157B.jpg",
27 | "largeImage":"/images/shirts/10-14157A.jpg"
28 | },
29 | {
30 | "name":"Android+Nylon+Packable+Jacket",
31 | "title":"Android Nylon Packable Jacket",
32 | "category":"mens_outerwear",
33 | "price":33.60,
34 | "description":"Pack. Pack. Pack it up! This nylon jacket with reflective trim can literally be packed into itself in seconds. Features a waterproof nylon fabric, Android eyes & antennaes on the hood and a carrying strap when jacket is fully packed. Android robot is printed on back above zipper in a reflective, metallic finish.",
35 | "image":"/images/shirts/10-15041B.jpg",
36 | "largeImage":"/images/shirts/10-15041A.jpg"
37 | },
38 | {
39 | "name":"YouTube+Ultimate+Hooded+Sweatshirt",
40 | "title":"YouTube Ultimate Hooded Sweatshirt",
41 | "category":"mens_outerwear",
42 | "price":32.35,
43 | "description":"Stay warm in this cozy hoodie made of 50% cotton and 50% polyester. This comfortable design features set in sleeves, dyed to match draw cord and a front pouch pocket. Available in Charcoal with the full color YouTube logo screen printed across the chest. Unisex sizing.",
44 | "image":"/images/shirts/10-14133B.jpg",
45 | "largeImage":"/images/shirts/10-14133A.jpg"
46 | },
47 | {
48 | "name":"Grey+Heather+Fleece+Zip+Hoodie",
49 | "title":"Grey Heather Fleece Zip Hoodie",
50 | "category":"mens_outerwear",
51 | "price":38.85,
52 | "description":"Cozy up with this full-zip hoodie. <div><br></div><div>Features:</div><div><ul><li>60% combed, ring-spun cotton, 40% polyester.</li><li>Unisex sizing.</li><li>Retail fit.</li><li>Contrast zipper.</li><li>Kangaroo pockets with ribbed cuffs and waistband.</li><li>Available in dark heather with the white Google logo embroidered at left chest.</li></ul></div><div><br></div>",
53 | "image":"/images/shirts/10-14160B.jpg",
54 | "largeImage":"/images/shirts/10-14160A.jpg"
55 | },
56 | {
57 | "name":"Vastrm+Hoodie",
58 | "title":"Vastrm Hoodie",
59 | "category":"mens_outerwear",
60 | "price":200.00,
61 | "description":"The ultimate in fit and fabric, this Vastrm hoodie doesn't disappoint. Made from soft pique fabric, the lightweight full-zip features a halfmoon accent and matching hoodie strings. <div><br></div><div>Additional Features:</div><div><ul><li>100% cotton.</li><li>Hidden phone pocket neatly cradles your digital device. </li><li>Available in charcoal grey with red strings and hood. White Google logo is embroidered at left bicep.</li></ul></div>",
62 | "image":"/images/shirts/10-14153B.jpg",
63 | "largeImage":"/images/shirts/10-14153A.jpg"
64 | },
65 | {
66 | "name":"Recycled+Plastic+Bottle+Hoodie+-+Green",
67 | "title":"Recycled Plastic Bottle Hoodie - Green",
68 | "category":"mens_outerwear",
69 | "price":60.95,
70 | "description":"Ever wonder where all of the disposable water bottles of the world end up? We know some of them are reused for a second purpose. Each of these hoodies contain approximately 9 recycled water bottles that are woven into the fabric.<div><br></div><div>Features: </div><div><ul><li>50% recycled cotton, 50% recycled polyester.</li><li>Full zipper and orange drawstring pulls.</li><li>USA made. </li><li> Available in forest green with the white Google logo embroidered at left bicep.</li></ul></div>",
71 | "image":"/images/shirts/10-14158B.jpg",
72 | "largeImage":"/images/shirts/10-14158A.jpg"
73 | },
74 | {
75 | "name":"Rowan+Pullover+Hood",
76 | "title":"Rowan Pullover Hood",
77 | "category":"mens_outerwear",
78 | "price":60.85,
79 | "description":"In search of the perfect layering piece? This lightweight, triblend pullover is ultra soft and ideal for all seasons.<div><br></div><div>Features:</div><div><ul><li>50% polyester, 38% cotton, 12% rayon triblend.</li><li>Available in black with the white Google logo screenprinted at left bicep.</li></ul></div>",
80 | "image":"/images/shirts/10-14152B.jpg",
81 | "largeImage":"/images/shirts/10-14152A.jpg"
82 | },
83 | {
84 | "name":"Men+s+Voyage+Fleece+Jacket",
85 | "title":"Men's Voyage Fleece Jacket",
86 | "category":"mens_outerwear",
87 | "price":48.00,
88 | "description":"<div>Perhaps the equivalent to that comfort blanket you had years ago is a cozy fleece. This full-zip is the perfect layering piece for those 'in-between' months when mother nature just can't make up her mind. </div><div><br></div><div>Features:</div><div><ul><li>100% polyester anti-pill yarn fleece.</li><li>100% polyester taffeta lining in sleeves.</li><li>Tricot-lined lower pockets with reverse coil zippers.</li><li>Available in black with the white Google logo embroidered at left chest.</li></ul></div>",
89 | "image":"/images/shirts/10-14155B.jpg",
90 | "largeImage":"/images/shirts/10-14155A.jpg"
91 | },
92 | {
93 | "name":"Eco-Jersey+Chrome+Zip+Up+Hoodie",
94 | "title":"Eco-Jersey Chrome Zip Up Hoodie",
95 | "category":"mens_outerwear",
96 | "price":37.75,
97 | "description":"An exceptionally soft, eco-friendly full-zip for picture-perfect layering. <div><br></div><div>Features:</div><div><ul><li>50% polyester, 38% cotton (6.25% recycled), 12% rayon (6.25% organic).</li><li>Low-impact yarn dyed and washed.</li><li>Brushed nickel zipper with natural taping.</li><li>Split front pouch pocket. </li><li>Available in deep pacific blue with the white Google Chrome logo screenprinted at left chest. </li></ul><div><br></div><div><br></div></div>",
98 | "image":"/images/shirts/10-14159B.jpg",
99 | "largeImage":"/images/shirts/10-14159A.jpg"
100 | },
101 | {
102 | "name":"Android+Colorblock+Hooded+Pullover",
103 | "title":"Android Colorblock Hooded Pullover",
104 | "category":"mens_outerwear",
105 | "price":50.20,
106 | "description":"This cozy Android hoodie features a sublimated camo design printed inside hood and along inner sleeves and side panels. Moisture-wicking polyester fabric keeps you cool and dry. <div><br></div><div>Features:</div><div><ul><li>100% polyester.</li><li>Ultra soft, fleece interior. </li><li>Available in smoke/lime green with the white Android robot embroidered at left chest.</li></ul></div>",
107 | "image":"/images/shirts/10-14146B.jpg",
108 | "largeImage":"/images/shirts/10-14146A.jpg"
109 | },
110 | {
111 | "name":"Tri-blend+Full-Zip+Hoodie",
112 | "title":"Tri-blend Full-Zip Hoodie",
113 | "category":"mens_outerwear",
114 | "price":52.20,
115 | "description":"Comfy cool. This canvas tri-blend full-zip hoodie made of a poly/cotton/rayon blend is sure to please the eyes as well as the senses. Made in the USA. Available in Black with the white Google logo embroidered at left chest.",
116 | "image":"/images/shirts/10-14216B.jpg",
117 | "largeImage":"/images/shirts/10-14216A.jpg"
118 | },
119 | {
120 | "name":"Fleece+Full-Zip+Hoodie",
121 | "title":"Fleece Full-Zip Hoodie",
122 | "category":"mens_outerwear",
123 | "price":45.65,
124 | "description":"If you find that the 'spark' is missing from your outfit, you may need to add one of these full-zip hoodies to the mix. Resurfacing from 1989, this colorful full-zip features a sporty fit with ultra soft fleece lining.<div><br><div>Additional Features:</div><div><ul><li>50% polyester and 50% cotton fleece. </li><li>Available in blue with the Google logo embroidered in white at left bicep.</li></ul></div></div>",
125 | "image":"/images/shirts/10-14215B.jpg",
126 | "largeImage":"/images/shirts/10-14215A.jpg"
127 | },
128 | {
129 | "name":"Jacquard-Knit+Full-Zip+Fleece",
130 | "title":"Jacquard-Knit Full-Zip Fleece",
131 | "category":"mens_outerwear",
132 | "price":74.90,
133 | "description":"We love color contrast, especially in Google Blue! This textured jacket features a jacquard texture with contrast stitching and zippers. <div><br></div><div>Additional Features:</div><div><ul><li>100% polyester. </li><li>Audio port access available on inside left pocket.</li><li>Available in Carbon/Olympic Blue with the Google logo embroidered in white on left chest.</li></ul></div>",
134 | "image":"/images/shirts/10-14217B.jpg",
135 | "largeImage":"/images/shirts/10-14217A.jpg"
136 | },
137 | {
138 | "name":"YouTube+Unisex+Flex+Fleece+Zip+Hoodie",
139 | "title":"YouTube Unisex Flex Fleece Zip Hoodie",
140 | "category":"mens_outerwear",
141 | "price":45.25,
142 | "description":"Our popular flex fleece hoodie, now for YouTube fans everywhere.<div><br></div><div>Features:</div><div><ul><li>50% polyester, 50% cotton fleece.</li><li>Sporty, unisex fit.</li><li>Metal zipper.</li><li>Hood.</li><li>Available in dark heather grey with the YouTube logo embroidered at left bicep.</li></ul><div><br></div><div><br></div></div>",
143 | "image":"/images/shirts/10-15103B.jpg",
144 | "largeImage":"/images/shirts/10-15103A.jpg"
145 | }
146 | ]
147 |
--------------------------------------------------------------------------------
/public/data/mens_tshirts.json:
--------------------------------------------------------------------------------
1 | [
2 | {
3 | "name":"YouTube+Organic+Cotton+T-Shirt+-+Grey",
4 | "title":"YouTube Organic Cotton T-Shirt - Grey",
5 | "category":"mens_tshirts",
6 | "price":14.75,
7 | "description":"Stay casual and cool in this 100% organic pre-shrunk cotton T-shirt. Available in charcoal grey with full-color YouTube logo screened on front.",
8 | "image":"/images/shirts/10-13058B.jpg",
9 | "largeImage":"/images/shirts/10-13058A.jpg"
10 | },
11 | {
12 | "name":"Inbox+-+Subtle+Actions+T-Shirt",
13 | "title":"Inbox - Subtle Actions T-Shirt",
14 | "category":"mens_tshirts",
15 | "price":17.05,
16 | "description":"Sometimes even the subtlest of actions can make a big difference. This tee highlights all of the icons & features available in your Gmail inbox!<div><br></div><div>Features:</div><div><ul><li>60% cotton, 40% polyester blend.</li><li>Available in charcoal heather with the inbox icons screenprinted at front chest and inbox tag sewn onto left sleeve.</li></ul></div>",
17 | "image":"/images/shirts/10-13256B.jpg",
18 | "largeImage":"/images/shirts/10-13256A.jpg"
19 | },
20 | {
21 | "name":"Adult+Android+Superhero+T-Shirt",
22 | "title":"Adult Android Superhero T-Shirt",
23 | "category":"mens_tshirts",
24 | "price":14.95,
25 | "description":"Mr. Kent has nothing on Super Droid, especially since this robot has only one weakness-a sweet tooth (considering all of its confectionery-themed versions)! This adorable Bella+Canvas tee features a unisex fit that is sure to please both male and female Android fans.<div><br></div><div>Additional Features:</div><div><ul><li>100% combed, ringspun cotton.</li><li>Unisex fit.</li><li>Tag-free label for added comfort.</li><li>Available in royal blue with the Super Droid robot screen printed at center chest.</li><li><b>Sizes run smaller than normal. Reference men's sizing chart for additional details.</b></li></ul></div>",
26 | "image":"/images/shirts/10-13239B.jpg",
27 | "largeImage":"/images/shirts/10-13239A.jpg"
28 | },
29 | {
30 | "name":"Men+s+Vintage+Heather+T-Shirt",
31 | "title":"Men's Vintage Heather T-Shirt",
32 | "category":"mens_tshirts",
33 | "price":15.8,
34 | "description":"<div>A casual-cool, vintage-inspired tee perfect for all. Just remember that the best part about any classic is that it only improves with age. The more you wash it, the softer it feels. </div><div><br></div><div>Features:</div><div><ul><li>65% polyester, 35% cotton.</li><li>Available in heather navy, blue, purple or green with the white Google logo screened across center chest of each.</li></ul></div>",
35 | "image":"/images/shirts/10-13264B.jpg",
36 | "largeImage":"/images/shirts/10-13264A.jpg"
37 | },
38 | {
39 | "name":"Basic+Black+T-Shirt",
40 | "title":"Basic Black T-Shirt",
41 | "category":"mens_tshirts",
42 | "price":16.9,
43 | "description":"Word on the street is that 'black is the new black.' Embellish your basic fashion statement with the Google logo on an authentic American Apparel t-shirt. <div><br></div><div>Features:</div><div><ul><li>100% organic combed cotton for ultimate softness. </li><li>Flattering fit. </li><li>Available in Black with the Google logo screen printed in White across center chest.</li><li><b>Sizes run smaller than normal.</b> <b>Please reference men's size chart for fit.</b></li></ul></div>",
44 | "image":"/images/shirts/10-13265B.jpg",
45 | "largeImage":"/images/shirts/10-13265A.jpg"
46 | },
47 | {
48 | "name":"Local+Guides+T-Shirt",
49 | "title":"Local Guides T-Shirt",
50 | "category":"mens_tshirts",
51 | "price":15.7,
52 | "description":"Do you live to explore? Are you the first to tell your friends about the best venues, restaurants and hot spots in town? If you're already a local guide, sport your t-shirt with pride. This ultra soft style is comfortable enough to wear all day long - perfect for all of those adventures you'll tell us about later. To learn more about Local Guides, visit us here: https://www.google.com/local/guides/.<div><br></div><div>Features:</div><div><ul><li>52% combed, ring-spun cotton / 48% polyester.</li><li>Retail fit.</li><li>Available in charcoal with the Local Guides logo screenprinted at front chest and Google logo screenprinted in white at left bicep.</li></ul></div>",
53 | "image":"/images/shirts/10-13280B.jpg",
54 | "largeImage":"/images/shirts/10-13280A.jpg"
55 | },
56 | {
57 | "name":"Go+Gopher+T-Shirt+in+Teal",
58 | "title":"Go Gopher T-Shirt in Teal",
59 | "category":"mens_tshirts",
60 | "price":10.95,
61 | "description":"Go anywhere in style when wearing this t-shirt featuring The Go Gopher. Tee is made of 100% combed, ring-spun cotton jersey fabric. Available in teal with the Go Gopher screen printed on center.",
62 | "image":"/images/shirts/10-13213B.jpg",
63 | "largeImage":"/images/shirts/10-13213A.jpg"
64 | },
65 | {
66 | "name":"Android+Ringspun+T-Shirt+-+Green",
67 | "title":"Android Ringspun T-Shirt - Green",
68 | "category":"mens_tshirts",
69 | "price":8.75,
70 | "description":"Display your undying love for Androids everywhere in this 100% certified organic ringspun cotton tee. \n<div><br></div><div>Additional Features: </div><div><ul><li>100% combed, ring-spun cotton. </li><li>Preshrunk for fashion fit. </li><li>Tearaway label. \n</li><li>Available in heather green with the full color Android robot screen printed across center chest.</li></ul></div>",
71 | "image":"/images/shirts/10-13285B.jpg",
72 | "largeImage":"/images/shirts/10-13285A.jpg"
73 | },
74 | {
75 | "name":"Organic+Cotton+Android+walking+with+dog+T-shirt",
76 | "title":"Organic Cotton Android walking with dog T-shirt",
77 | "category":"mens_tshirts",
78 | "price":17.25,
79 | "description":"What’s better than an organic cotton t-shirt with the Android logo? How about a t-shirt with the Android walking a dog. <div><br></div><div>Features:</div><div><ul><li>100% smooth organic cotton.</li><li>Available in black with the Android design screenprinted at front chest.</li><li><b>Sizing runs smaller than normal. Please reference size chart before ordering.</b></li></ul></div>",
80 | "image":"/images/shirts/10-13018B.jpg",
81 | "largeImage":"/images/shirts/10-13018A.jpg"
82 | },
83 | {
84 | "name":"Organic+Cotton+T-Shirt+-+Red",
85 | "title":"Organic Cotton T-Shirt - Red",
86 | "category":"mens_tshirts",
87 | "price":14.4,
88 | "description":"Looking to add a little color to your wardrobe? This striking red tee shirt is made of 100% preshrunk organic cotton, so it's healthy for the environment as well as for your look. <div><br></div><div>Features:</div><div><ul><li>Shoulder-to-shoulder tape.</li><li>Seamless collar.</li><li>Available in red with white Google logo screenprinted at center chest.</li><li><b>**This shirt's cut is more of a generous t-shirt cut. Compared to the American Apparel shirts, sizing would run larger.** </b></li></ul></div>",
89 | "image":"/images/shirts/10-13270B.jpg",
90 | "largeImage":"/images/shirts/10-13270A.jpg"
91 | },
92 | {
93 | "name":"Unisex+Gmail+T-Shirt",
94 | "title":"Unisex Gmail T-Shirt",
95 | "category":"mens_tshirts",
96 | "price":15,
97 | "description":"Show your inbox some love. The new Gmail tee has arrived, complete with a subtle Mvelope design that showcases all of the Gmail icons you use on the daily.<div><br></div><div>Features:</div><div><ul><li>52% cotton / 48% polyester.</li><li>Unisex fit.</li><li>Bella+Canvas.</li><li>Available in dark grey heather with the new Gmail print screenprinted across center chest.</li></ul></div>",
98 | "image":"/images/shirts/10-13282B.jpg",
99 | "largeImage":"/images/shirts/10-13282A.jpg"
100 | },
101 | {
102 | "name":"Android+Soccer+T-Shirt",
103 | "title":"Android Soccer T-Shirt",
104 | "category":"mens_tshirts",
105 | "price":15.2,
106 | "description":"When it comes to futbol formation, the world's most adorable robots are en pointe. Show your love for the game with this limited edition Android tee. <div><br></div><div>Features:</div><div><ul><li>100% cotton.</li><li>Made in the USA.</li><li>Available in navy with the Android robot design screenprinted at front.</li></ul></div>",
107 | "image":"/images/shirts/10-13289B.jpg",
108 | "largeImage":"/images/shirts/10-13289A.jpg"
109 | },
110 | {
111 | "name":"Basic+Google+T-Shirt",
112 | "title":"Basic Google T-Shirt",
113 | "category":"mens_tshirts",
114 | "price":13.3,
115 | "description":"Embellish your basic fashion statement with Google's brightly colored logo. Featuring a flattering and stylish fit for virtually any body type, this tee also boasts an ultra-soft feel. <div><br></div><div>Features:</div><div><ul><li>100% cotton.</li><li>Stretchable, reinforced shoulder construction maintains shape through repeated washings.</li><li>Double-stitched bottom hem ensures durability. </li><li>Available in white with the full color Google logo screenprinted across chest.</li><li><b>Sizes run smaller than normal.</b> <b>Please reference men's size chart for fit.</b></li></ul></div>",
116 | "image":"/images/shirts/10-13262B.jpg",
117 | "largeImage":"/images/shirts/10-13262A.jpg"
118 | },
119 | {
120 | "name":"Tri-Blend+V-Neck+Tee",
121 | "title":"Tri-Blend V-Neck Tee",
122 | "category":"mens_tshirts",
123 | "price":14.95,
124 | "description":"An ultra soft triblend fabric and fashionable v-neck cut make this tee perfect for everyday wear. Available in royal blue with the white Google logo screenprinted at center chest.",
125 | "image":"/images/shirts/10-13273B.jpg",
126 | "largeImage":"/images/shirts/10-13273A.jpg"
127 | },
128 | {
129 | "name":"Heather+Pocket+Tee+-+Light+Blue",
130 | "title":"Heather Pocket Tee - Light Blue",
131 | "category":"mens_tshirts",
132 | "price":23.3,
133 | "description":"Pocket protector or not, you're sure to look pretty cool in this stylish tee. <div><br></div><div>Features:</div><div><ul><li>60% cotton, 40% polyester.</li><li>Tagless label for added comfort.</li><li>Available in light blue with a grey pocket and the white Google logo screenprinted at center pocket.</li></ul></div>",
134 | "image":"/images/shirts/10-13272B.jpg",
135 | "largeImage":"/images/shirts/10-13272A.jpg"
136 | },
137 | {
138 | "name":"Google+Now+Skyline+T-Shirt",
139 | "title":"Google Now Skyline T-Shirt",
140 | "category":"mens_tshirts",
141 | "price":20.2,
142 | "description":"A bright and sunny 360° illustration of San Francisco wrapped around this American Apparel t-shirt. This tee, popular at the Googleplex in Mountain View, CA is now available just for you! <div><br></div><div><ul><li>100% cotton.</li><li>Available in Aqua with the Google Now logo screen printed in Gray across chest.</li><li><b>Sizes run smaller than normal.</b> <b>Please reference men's size chart for fit.</b></li></ul></div>",
143 | "image":"/images/shirts/10-13276B.jpg",
144 | "largeImage":"/images/shirts/10-13276A.jpg"
145 | },
146 | {
147 | "name":"Tri-Blend+G+Logo+Men+s+Polo",
148 | "title":"Tri-Blend G Logo Men's Polo",
149 | "category":"mens_tshirts",
150 | "price":32.7,
151 | "description":"Stock up on this comfy-cool polo featuring the new Google 'G.' <div><br></div><div>Features:</div><div><ul><li>50% polyester / 25% cotton / 25% rayon</li><li>Tri-blend fabric retains shape and elasticity.</li><li>Retail fit. </li><li>Single front pocket.</li><li>Three-button placket.</li><li>Structured collar holds shape through repeated washing.</li><li>Available in black with the Google 'G' icon embroidered at left chest. </li></ul></div>",
152 | "image":"/images/shirts/10-11019B.jpg",
153 | "largeImage":"/images/shirts/10-11019A.jpg"
154 | },
155 | {
156 | "name":"Tri-Blend+Leisure+Shirt",
157 | "title":"Tri-Blend Leisure Shirt",
158 | "category":"mens_tshirts",
159 | "price":32.95,
160 | "description":"Dress it up, or dress it down. We promise you'll fall in love with the versatility of this triblend polo. <div><br></div><div>Features: </div><div><ul><li>50/25/25 polyester/cotton/rayon blend. </li><li>Three-button placket with structured self-fabric collar and left chest pocket. </li><li>Available in black with the Google logo embroidered at right sleeve.</li><li><b>Sizes run smaller than normal. Please reference size chart before ordering.</b></li></ul></div>",
161 | "image":"/images/shirts/10-11017B.jpg",
162 | "largeImage":"/images/shirts/10-11017A.jpg"
163 | },
164 | {
165 | "name":"Wise+Android+T-Shirt",
166 | "title":"Wise Android T-Shirt",
167 | "category":"mens_tshirts",
168 | "price":14.95,
169 | "description":"Take a word from the wise: put on this tee and you'll fall in love! Made of 100% preshrunk certified organic cotton for ultimate softness. Available in black with the Wise Android screen printed on the front chest.",
170 | "image":"/images/shirts/10-13153B.jpg",
171 | "largeImage":"/images/shirts/10-13153A.jpg"
172 | },
173 | {
174 | "name":"Android+Pride+T-Shirt",
175 | "title":"Android Pride T-Shirt",
176 | "category":"mens_tshirts",
177 | "price":19.1,
178 | "description":"<p>Stand out and stand proud in this Android Pride T-shirt. </p><p>Features:</p><p></p><ul><li>100% cotton American Apparel t-shirt.</li><li>Available in black, and features two Androids holding hands and waving a rainbow flag screenprinted at center chest. Google logo is screenprinted in white at sleeve.</li><li><b>Sizing runs smaller than normal. Please reference size chart before ordering.</b></li></ul>",
179 | "image":"/images/shirts/10-13279B.jpg",
180 | "largeImage":"/images/shirts/10-13279A.jpg"
181 | },
182 | {
183 | "name":"Chrome+Unisex+T-Shirt",
184 | "title":"Chrome Unisex T-Shirt",
185 | "category":"mens_tshirts",
186 | "price":11.35,
187 | "description":"Show your love for Google Chrome in this 100% combed ring-spun cotton T-Shirt. <div><br></div><div>Features:</div><div><ul><li>Soft, jersey fabric.</li><li>Unisex fit.</li><li>Available in dark heather grey with the new Google Chrome logo screenprinted at front.</li></ul></div>",
188 | "image":"/images/shirts/10-13286B.jpg",
189 | "largeImage":"/images/shirts/10-13286A.jpg"
190 | },
191 | {
192 | "name":"NY+City+Lights+T-Shirt",
193 | "title":"NY City Lights T-Shirt",
194 | "category":"mens_tshirts",
195 | "price":18.35,
196 | "description":"Are you feeling lucky? This anniversary t-shirt celebrates the Big Apple. <div><br></div><div>Features:</div><div><ul><li>100% cotton American Apparel shirt.</li><li>Available in Black with the Google logo and 'I'm Feeling Lucky' New York printed on back yoke in White.</li><li><b>Sizes run smaller than normal. Please reference men's size chart for fit before ordering.</b></li></ul></div>",
197 | "image":"/images/shirts/10-13271B.jpg",
198 | "largeImage":"/images/shirts/10-13271A.jpg"
199 | },
200 | {
201 | "name":"Omi+Tech+Tee",
202 | "title":"Omi Tech Tee",
203 | "category":"mens_tshirts",
204 | "price":17,
205 | "description":"This performance tee deserves to be one of your wardrobe staples. Micro-polyester mesh fabric is snag-resistant, moisture-wicking and provides UV protection for sunny days. Available in royal blue with the white Google logo transferred onto center chest.",
206 | "image":"/images/shirts/10-13267B.jpg",
207 | "largeImage":"/images/shirts/10-13267A.jpg"
208 | },
209 | {
210 | "name":"YouTube+S+S+Triblend+T-Shirt",
211 | "title":"YouTube S/S Triblend T-Shirt",
212 | "category":"mens_tshirts",
213 | "price":14.9,
214 | "description":"A perfect blend of three fabrics. This fashionably soft tee is perfect for layering or wearing solo. <div><br></div><div>Features:</div><div><ul><li>50% polyester, 25% combed, ring-spun cotton.</li><li>Retail fit.</li><li>Unisex sizing. </li><li>Available in black with the full color YouTube logo screenprinted at center chest. </li></ul></div>",
215 | "image":"/images/shirts/10-13278B.jpg",
216 | "largeImage":"/images/shirts/10-13278A.jpg"
217 | },
218 | {
219 | "name":"Nest+T-Shirt",
220 | "title":"Nest T-Shirt",
221 | "category":"mens_tshirts",
222 | "price":17.4,
223 | "description":"We know energy savings make you smile. Why not put on an even bigger grin with this teal Nest t-shirt? <div><br></div><div>Features:</div><div><ul><li>100% combed cotton.</li><li>Made in the USA.</li><li>Available in teal with the white Nest icon screen printed across chest.</li><li><b>Sizing runs smaller than normal. Please reference size chart before ordering.</b></li></ul></div>",
224 | "image":"/images/shirts/10-13241B.jpg",
225 | "largeImage":"/images/shirts/10-13241A.jpg"
226 | },
227 | {
228 | "name":"98+Short+Sleeve+Tee",
229 | "title":"98 Short Sleeve Tee",
230 | "category":"mens_tshirts",
231 | "price":14.3,
232 | "description":"Classic front. Retro back. This comfy grey tee celebrates Google's heritage, featuring the vintage '98' logo at back.<div><br></div><div>Features:</div><div><ul><li>100% cotton. </li><li>Available in grey with the white Google logo screenprinted at left chest and the vintage '98' screenprinted at back in red, white and blue. </li></ul></div><div><br></div>",
233 | "image":"/images/shirts/10-13291B.jpg",
234 | "largeImage":"/images/shirts/10-13291A.jpg"
235 | },
236 | {
237 | "name":"Cardboard+T-Shirt",
238 | "title":"Cardboard T-Shirt",
239 | "category":"mens_tshirts",
240 | "price":14.2,
241 | "description":"Crazy for Cardboard? Show your love with this super soft t-shirt. If you're new to the virtual reality scene, check out Google Cardboard here: https://www.google.com/get/cardboard/<div><br></div><div>Features:</div><div><ul><li>60% cotton, 40% polyester.</li><li>Available in charcoal with a Cardboard viewer textured metallic heart at front chest and the Cardboard short url screenprinted at back yoke.</li></ul></div>",
242 | "image":"/images/shirts/10-13260B.jpg",
243 | "largeImage":"/images/shirts/10-13260A.jpg"
244 | },
245 | {
246 | "name":"Short+Sleeve+Crew+Neck+Raglan",
247 | "title":"Short Sleeve Crew Neck Raglan",
248 | "category":"mens_tshirts",
249 | "price":13.1,
250 | "description":"This vintage style t-shirt features a soft jersey fabric comfortable enough to sleep in. <div><br></div><div>Features:</div><div><ul><li>60% cotton, 40% polyester.</li><li>Self fabric contrast neckband and sleeves.</li><li>Available in light blue/indigo with the white Google logo screenprinted across center chest.</li></ul></div>",
251 | "image":"/images/shirts/10-13266B.jpg",
252 | "largeImage":"/images/shirts/10-13266A.jpg"
253 | },
254 | {
255 | "name":"MTV+Unisex+Blue+T-Shirt",
256 | "title":"MTV Unisex Blue T-Shirt",
257 | "category":"mens_tshirts",
258 | "price":15.75,
259 | "description":"They say home is where the heart is. This vibrant tee features the Bay Area address of Google's head office. <div><br></div><div>Features:</div><div><ul><li>100% combed cotton. </li><li>Made in the USA.</li><li>Available in royal blue with a striking design at front and the white Google logo at back yoke. </li></ul></div>",
260 | "image":"/images/shirts/10-13292B.jpg",
261 | "largeImage":"/images/shirts/10-13292A.jpg"
262 | },
263 | {
264 | "name":"Organic+Me-To-We+Tee",
265 | "title":"Organic Me-To-We Tee",
266 | "category":"mens_tshirts",
267 | "price":23.6,
268 | "description":"Buy a tee that gives back. Half of the profits from each organic crewneck tee are distributed to the international charity and educational partner, Free the Children. <div><br></div><div>Features:</div><div><ul><li>100% organic cotton.</li><li>For more information on Free the Children & Me to We, visit http://www.freethechildren.com/about-us/our-story/. </li><li>Available in blue with the white Google logo screenprinted at center chest.</li></ul></div>",
269 | "image":"/images/shirts/10-13268B.jpg",
270 | "largeImage":"/images/shirts/10-13268A.jpg"
271 | },
272 | {
273 | "name":"Tri-Blend+Raglan+Long+Sleeve",
274 | "title":"Tri-Blend Raglan Long Sleeve",
275 | "category":"mens_tshirts",
276 | "price":51.2,
277 | "description":"Whether you're stealing second, cheering in the stands, or you just love the look of a classic 'baseball' tee, consider this raglan version for your apparel roster. <div><br></div><div>Features:</div><div><ul><li>50% polyester, 38% cotton, 12% rayon super soft triblend.</li><li>Fashionable fit.</li><li>Machine washable.</li><li>Available in grey/black with the white Google logo screenprinted at center chest.</li></ul></div>",
278 | "image":"/images/shirts/10-13274B.jpg",
279 | "largeImage":"/images/shirts/10-13274A.jpg"
280 | },
281 | {
282 | "name":"Blueprint+for+a+Better+Inbox+T-Shirt",
283 | "title":"Blueprint for a Better Inbox T-Shirt",
284 | "category":"mens_tshirts",
285 | "price":14.3,
286 | "description":"This new \"Blueprint for better Inbox\" t-shirt will be your new favorite t-shirt. It's a USA made American Apparel t-shirt sporting the new logo.<div><br><div>Additional Features: </div><div><ul><li>50% cotton / 50% polyester for a super soft feel </li><li>Unisex fit. </li><li>Available in royal blue heather with the \"New Inbox: logo screen printed on the center chest.</li><li><b style=\"\">Sizing runs smaller than normal. Please reference men's sizing chart prior to ordering.</b></li></ul></div></div>",
287 | "image":"/images/shirts/10-13240B.jpg",
288 | "largeImage":"/images/shirts/10-13240A.jpg"
289 | },
290 | {
291 | "name":"YouTube+Player+T-Shirt+-+Unisex",
292 | "title":"YouTube Player T-Shirt - Unisex",
293 | "category":"mens_tshirts",
294 | "price":17.8,
295 | "description":"<p>The YouTube Player T-Shirt has arrived. This t-shirt, much coveted by YouTube employees, is now available to the public. Channel your inner player and profess your love for YouTube with this clever design. </p><p>Features:</p><p></p><ul><li>100% combed cotton.</li><li>Reinforced shoulder construction to maintain shape. </li><li>Available in red with the Player logo screenprinted at front chest and YouTube logo screenprinted at back yoke.</li><li><b>Sizes run smaller than normal. Please reference size chart before ordering.</b></li></ul><p></p>\n<p><br></p>",
296 | "image":"/images/shirts/10-13097B.jpg",
297 | "largeImage":"/images/shirts/10-13097A.jpg"
298 | },
299 | {
300 | "name":"G+Logo+White+T-Shirt",
301 | "title":"G Logo White T-Shirt",
302 | "category":"mens_tshirts",
303 | "price":13,
304 | "description":"There's a new G in town and it's here to stay. Get your hands on this comfy white tee featuring the new Google icon. <div><br></div><div>Features:</div><div><ul><li>100% combed, ringspun cotton.</li><li>Side-seamed.</li><li>Unisex size, retail fit by Bella+Canvas.</li><li>Available in white with the Google 'G' icon screenprinted at front.</li></ul></div>",
305 | "image":"/images/shirts/10-13275B.jpg",
306 | "largeImage":"/images/shirts/10-13275A.jpg"
307 | },
308 | {
309 | "name":"Android+Concert+T-Shirt",
310 | "title":"Android Concert T-Shirt",
311 | "category":"mens_tshirts",
312 | "price":13.65,
313 | "description":"Back by popular demand! Rock out with this Android Concert t-shirt. <div><br></div><div>Features:</div><div><ul><li>100% combed cotton.</li><li>Made in the USA.</li><li>Available in grey with the Android screen printed in orange at center chest. </li><li><b>Sizing runs smaller than normal. Please reference size chart before ordering.</b></li></ul></div>",
314 | "image":"/images/shirts/10-13130B.jpg",
315 | "largeImage":"/images/shirts/10-13130A.jpg"
316 | },
317 | {
318 | "name":"Men+s+Bamboo+T-Shirt",
319 | "title":"Men's Bamboo T-Shirt",
320 | "category":"mens_tshirts",
321 | "price":20.65,
322 | "description":"'Seriously soft' is one phrase we're not afraid to throw around when it comes to these bamboo tees. Made with 70% viscose from organic bamboo and 30% organic cotton, your skin will thank you during those long nights of programming.<div><br></div><div>Features:</div><div><ul><li> Available in blue with the Google logo screen printed in white across center chest.</li></ul></div>",
323 | "image":"/images/shirts/10-13269B.jpg",
324 | "largeImage":"/images/shirts/10-13269A.jpg"
325 | },
326 | {
327 | "name":"Android+Pay+Crew+Neck+T-Shirt",
328 | "title":"Android Pay Crew Neck T-Shirt",
329 | "category":"mens_tshirts",
330 | "price":19.4,
331 | "description":"Wear. Wash. Repeat. This tee celebrates the most exciting way to pay for life's necessities. For more information on Android Pay, visit our site here; https://www.android.com/pay/.<div><br></div><div>Features:</div><div><ul><li>60/40 cotton/polyester blend.</li><li>Tagless label for added comfort.</li><li>Made in the USA.</li><li>Available in Pepper Black with the Android Pay icon screenprinted at front chest and Android Pay logo text at left sleeve.</li></ul><div><br></div><div><br></div></div>",
332 | "image":"/images/shirts/10-13263B.jpg",
333 | "largeImage":"/images/shirts/10-13263A.jpg"
334 | },
335 | {
336 | "name":"Google+Maps+T-Shirt",
337 | "title":"Google Maps T-Shirt",
338 | "category":"mens_tshirts",
339 | "price":18.35,
340 | "description":"Make a geographical statement with this royal blue American Apparel tee.<div><br></div><div>Features:</div><div><ul><li>100% combed cotton.</li><li>Available in royal with the Google Maps pin and \"I am here\" text on the front, Google Maps logo on the back, and URL on the sleeve. </li><li><b>Sizes run smaller than normal. Please reference size chart before ordering.</b></li></ul></div>",
341 | "image":"/images/shirts/10-13277B.jpg",
342 | "largeImage":"/images/shirts/10-13277A.jpg"
343 | },
344 | {
345 | "name":"Est.+98+Baseball+Tee",
346 | "title":"Est. 98 Baseball Tee",
347 | "category":"mens_tshirts",
348 | "price":17.9,
349 | "description":"Hit a home run in the style stakes with this classic baseball tee. Designed with traditional contrast sleeves and an 'est 98' graphic honoring the year Google was founded. <div><br></div><div>Features:</div><div><ul><li>Unisex fit.</li><li>52% cotton, 48% polyester.</li><li>Available in white with black sleeves and the white Google logo printed at left bicep.</li></ul></div>",
350 | "image":"/images/shirts/10-13290B.jpg",
351 | "largeImage":"/images/shirts/10-13290A.jpg"
352 | },
353 | {
354 | "name":"Mountain+View+T-Shirt",
355 | "title":"Mountain View T-Shirt",
356 | "category":"mens_tshirts",
357 | "price":16.5,
358 | "description":"The Bay Area city named for its beautiful views of the Santa Cruz Mountains is also home to the Googleplex located at 1600 Amphitheater Parkway. Celebrate the place Google calls home in this American Apparel tee.<div><br></div><div>Features:</div><div><ul><li>100% combed cotton.</li><li>Made in Los Angeles.</li><li>Available in white with the Mountain View coordinates screenprinted at front and the full color Google logo screenprinted at back yoke.</li></ul></div>",
359 | "image":"/images/shirts/10-13288B.jpg",
360 | "largeImage":"/images/shirts/10-13288A.jpg"
361 | }
362 | ]
363 |
--------------------------------------------------------------------------------
/public/data/sample_error_response.json:
--------------------------------------------------------------------------------
1 | {
2 | "error": 1,
3 | "errorMessage": "Transaction failed."
4 | }
5 |
--------------------------------------------------------------------------------
/public/data/sample_success_response.json:
--------------------------------------------------------------------------------
1 | {
2 | "success": 1,
3 | "successMessage": "Your order has been received."
4 | }
5 |
--------------------------------------------------------------------------------
/public/favicon.svg:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/public/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/icon.png
--------------------------------------------------------------------------------
/public/images/categories/ladies_outerwear.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/categories/ladies_outerwear.jpg
--------------------------------------------------------------------------------
/public/images/categories/ladies_tshirts.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/categories/ladies_tshirts.jpg
--------------------------------------------------------------------------------
/public/images/categories/mens_outerwear.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/categories/mens_outerwear.jpg
--------------------------------------------------------------------------------
/public/images/categories/mens_tshirts.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/categories/mens_tshirts.jpg
--------------------------------------------------------------------------------
/public/images/icons/shop-icon-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/icons/shop-icon-128.png
--------------------------------------------------------------------------------
/public/images/icons/shop-icon-192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/icons/shop-icon-192.png
--------------------------------------------------------------------------------
/public/images/icons/shop-icon-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/icons/shop-icon-32.png
--------------------------------------------------------------------------------
/public/images/icons/shop-icon-384.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/icons/shop-icon-384.png
--------------------------------------------------------------------------------
/public/images/icons/shop-icon-512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/icons/shop-icon-512.png
--------------------------------------------------------------------------------
/public/images/shirts/10-11017A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-11017A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-11017B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-11017B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-11019A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-11019A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-11019B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-11019B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13018A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13018A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13018B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13018B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13058A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13058A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13058B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13058B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13097A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13097A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13097B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13097B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13130A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13130A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13130B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13130B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13153A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13153A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13153B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13153B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13213A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13213A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13213B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13213B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13239A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13239A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13239B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13239B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13240A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13240A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13240B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13240B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13241A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13241A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13241B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13241B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13256A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13256A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13256B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13256B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13260A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13260A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13260B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13260B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13262A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13262A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13262B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13262B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13263A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13263A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13263B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13263B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13264A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13264A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13264B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13264B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13265A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13265A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13265B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13265B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13266A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13266A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13266B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13266B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13267A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13267A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13267B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13267B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13268A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13268A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13268B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13268B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13269A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13269A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13269B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13269B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13270A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13270A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13270B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13270B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13271A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13271A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13271B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13271B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13272A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13272A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13272B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13272B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13273A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13273A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13273B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13273B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13274A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13274A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13274B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13274B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13275A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13275A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13275B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13275B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13276A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13276A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13276B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13276B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13277A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13277A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13277B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13277B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13278A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13278A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13278B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13278B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13279A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13279A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13279B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13279B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13280A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13280A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13280B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13280B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13282A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13282A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13282B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13282B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13285A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13285A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13285B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13285B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13286A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13286A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13286B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13286B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13288A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13288A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13288B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13288B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13289A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13289A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13289B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13289B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13290A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13290A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13290B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13290B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13291A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13291A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13291B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13291B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13292A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13292A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-13292B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-13292B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14133A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14133A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14133B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14133B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14146A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14146A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14146B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14146B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14152A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14152A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14152B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14152B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14153A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14153A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14153B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14153B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14154A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14154A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14154B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14154B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14155A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14155A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14155B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14155B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14157A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14157A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14157B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14157B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14158A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14158A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14158B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14158B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14159A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14159A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14159B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14159B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14160A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14160A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14160B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14160B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14215A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14215A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14215B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14215B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14216A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14216A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14216B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14216B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14217A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14217A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-14217B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-14217B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-15041A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-15041A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-15041B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-15041B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-15068A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-15068A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-15068B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-15068B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-15103A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-15103A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-15103B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-15103B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23069A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23069A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23069B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23069B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23073A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23073A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23073B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23073B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23169A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23169A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23169B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23169B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23171A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23171A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23171B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23171B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23172A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23172A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23172B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23172B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23173A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23173A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23173B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23173B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23174A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23174A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23174B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23174B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23176A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23176A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23176B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23176B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23177A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23177A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23177B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23177B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23178A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23178A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23178B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23178B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23179A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23179A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23179B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23179B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23180A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23180A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23180B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23180B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23198A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23198A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23198B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23198B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23225A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23225A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23225B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23225B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23226A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23226A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23226B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23226B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23227A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23227A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23227B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23227B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23228A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23228A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23228B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23228B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23229A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23229A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23229B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23229B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23230A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23230A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-23230B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-23230B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-24097A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-24097A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-24097B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-24097B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-24098A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-24098A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-24098B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-24098B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-24099A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-24099A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-24099B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-24099B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-24101A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-24101A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-24101B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-24101B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-24102A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-24102A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-24102B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-24102B.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-25058A.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-25058A.jpg
--------------------------------------------------------------------------------
/public/images/shirts/10-25058B.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/images/shirts/10-25058B.jpg
--------------------------------------------------------------------------------
/public/logo192.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/logo192.png
--------------------------------------------------------------------------------
/public/logo512.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/google-pay/react-store/30a2c7f6b40ed62e8d419ef49b0c72229343b09c/public/logo512.png
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "React Store",
3 | "name": "Sample React Store",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "logo192.png",
12 | "type": "image/png",
13 | "sizes": "192x192"
14 | },
15 | {
16 | "src": "logo512.png",
17 | "type": "image/png",
18 | "sizes": "512x512"
19 | }
20 | ],
21 | "start_url": ".",
22 | "display": "standalone",
23 | "theme_color": "#000000",
24 | "background_color": "#ffffff"
25 | }
26 |
--------------------------------------------------------------------------------
/public/robots.txt:
--------------------------------------------------------------------------------
1 | User-agent: *
2 | Disallow:
3 |
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https: //www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | .App {
18 | text-align: center;
19 | }
20 |
21 | .heading {
22 | flex-grow: 1;
23 | }
24 |
25 | .heading a {
26 | text-decoration: none;
27 | color: inherit;
28 | }
29 |
30 | .App-header {
31 | position: fixed;
32 | top: 0;
33 | text-align: center;
34 | background-color: #ffff;
35 | display: flex;
36 | flex-direction: column;
37 | align-items: center;
38 | justify-content: center;
39 | font-size: 16px;
40 | color: #000;
41 | width: 100vw;
42 | box-shadow: 0 0 5px rgba(0, 0, 0, 0.2);
43 | }
44 |
45 | .App-header .Header {
46 | font-weight: bold;
47 | text-transform: uppercase;
48 | padding: 20px 16px;
49 | display: flex;
50 | position: relative;
51 | }
52 |
53 | .App-header .Header .title {
54 | flex: 1;
55 | flex-basis: 0.01px;
56 | }
57 |
58 | .App-header a {
59 | text-decoration: none;
60 | color: #000;
61 | }
62 |
63 | .App-header>.Navigation {
64 | display: flex;
65 | flex-direction: row;
66 | font-size: 13px;
67 | padding: 0;
68 | margin: 0;
69 | }
70 |
71 | .App-header>.Navigation li {
72 | list-style: none;
73 | margin: 10px;
74 | padding: 2px;
75 | }
76 |
77 | .App-header>.Navigation a {
78 | display: block;
79 | padding: 2px;
80 | font-weight: 500;
81 | }
82 |
83 | .App-header>.Navigation a.active {
84 | border-bottom: 2px solid #000;
85 | }
86 |
87 | .App-header+* {
88 | margin-top: 80px;
89 | }
90 |
--------------------------------------------------------------------------------
/src/App.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { useEffect, useMemo, useState } from 'react';
18 | import { Route, BrowserRouter, Routes } from 'react-router-dom';
19 |
20 | import Cart from './Store/Cart';
21 | import Checkout from './Store/Checkout';
22 | import Confirmation from './Store/Confirmation';
23 | import Header from './Store/Header';
24 | import Home from './Store/Home';
25 | import ItemDetails from './Store/ItemDetails';
26 | import List from './Store/List';
27 |
28 | import { CartContext } from './Store/CartContext';
29 | import { StoreData } from './Store/StoreData';
30 | import { CategoryDetails } from './interfaces/CategoryDetails';
31 | import { CartItemDetails } from './interfaces/CartItemDetails';
32 |
33 | import './App.css';
34 |
35 | /**Builds the base React app */
36 | function App() {
37 | // Products, cart, and other shopping info
38 | const storeData = useMemo(() => new StoreData(), []);
39 |
40 | // T-shirt categories
41 | const [categories, setCategories] = useState([] as CategoryDetails[]);
42 |
43 | // Current user's shopping cart
44 | const [cart, setCart] = useState(storeData.getCart());
45 |
46 | // Updates the user's shopping cart
47 | function updateCart(cart: CartItemDetails[]) {
48 | storeData.setCart(cart);
49 | setCart(cart);
50 | }
51 |
52 | // Create list of categories and details
53 | useEffect(() => {
54 | storeData.getCategories().then(data => setCategories(data));
55 | }, [storeData]);
56 |
57 | // Create the router
58 | return (
59 |
60 |
61 |
62 |
63 | } />
64 | } />
65 | } />
66 | } />
67 | } />
68 | } />
69 |
70 |
71 |
72 | );
73 | }
74 |
75 | export default App;
76 |
--------------------------------------------------------------------------------
/src/Store/Cart.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | .Cart {
18 | margin: 20px;
19 | text-align: center;
20 | }
21 |
22 | .Cart .total {
23 | margin: 20px 0;
24 | font-weight: bold;
25 | text-align: center;
26 | }
27 |
28 | .Cart .total>* {
29 | display: inline-block;
30 | margin: 10px;
31 | }
32 |
33 | .Cart .buttons {
34 | margin: 20px auto;
35 | max-width: 500px;
36 | }
37 |
38 | .Cart .buttons>* {
39 | width: 100%;
40 | }
41 |
42 | .Cart .cart-items {
43 | display: flex;
44 | flex-direction: column;
45 | text-align: left;
46 | margin: 20px auto;
47 | max-width: 800px;
48 | }
49 |
50 | .cart-item-card {
51 | margin: 5px 0;
52 | padding: 10px;
53 | display: flex;
54 | flex-direction: row;
55 | }
56 |
57 | .cart-item-image {
58 | width: 60px;
59 | align-self: flex-start;
60 | margin-top: 5px;
61 | }
62 |
63 | .cart-item-card .cart-item-content {
64 | padding: 10px;
65 | display: flex;
66 | flex-direction: column;
67 | align-self: stretch;
68 | width: 100%;
69 | }
70 |
71 | .cart-item-card .cart-item-content:last-child {
72 | padding-bottom: 10px;
73 | }
74 |
75 | .cart-item-card .first-row {
76 | display: flex;
77 | flex-direction: row;
78 | justify-content: stretch;
79 | }
80 |
81 | .cart-item-card .first-row .title {
82 | flex-grow: 1;
83 | }
84 |
85 | .cart-item-card .first-row .title a {
86 | color: #000;
87 | text-decoration: none;
88 | }
89 |
90 | .cart-item-card .first-row .remove {
91 | color: rgba(0, 0, 0, 0.4);
92 | flex-grow: 0;
93 | margin: -12px;
94 | }
95 |
96 | .cart-item-card .second-row {
97 | display: flex;
98 | flex-direction: row;
99 | justify-content: stretch;
100 | }
101 |
102 | .cart-item-card .second-row .label {
103 | margin-top: 6px;
104 | margin-right: 10px;
105 | }
106 |
107 | .cart-item-card .second-row .input {
108 | margin-right: 20px;
109 | }
110 |
111 | .cart-item-card .second-row .amount {
112 | flex-grow: 1;
113 | text-align: right;
114 | margin-right: 0;
115 | }
116 |
--------------------------------------------------------------------------------
/src/Store/Cart.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { Button, Typography } from '@mui/material';
18 | import React, { useContext } from 'react';
19 | import { useNavigate } from 'react-router-dom';
20 |
21 | import './Cart.css';
22 | import CartItem from './CartItem';
23 | import { CartContext } from './CartContext';
24 | import { StoreData } from './StoreData';
25 |
26 | interface Props {}
27 |
28 | /** Represents a user's shopping cart */
29 | const Cart: React.FC = props => {
30 | const navigate = useNavigate();
31 |
32 | // Get the cart from the context
33 | const { cart } = useContext(CartContext);
34 |
35 | // Get the cart size
36 | const cartSize = StoreData.getCartSize(cart);
37 |
38 | // Return the cart
39 | return (
40 |
65 | );
66 | };
67 |
68 | export default Cart;
69 |
--------------------------------------------------------------------------------
/src/Store/CartContext.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react';
18 |
19 | import { CartItemDetails } from '../interfaces/CartItemDetails';
20 |
21 | // Create an empty cart
22 | let cart: CartItemDetails[] = [];
23 |
24 | // Add the empty cart to the current context
25 | const CartContext = React.createContext({
26 | cart,
27 | setCart(cart: CartItemDetails[]) {
28 | this.cart = cart;
29 | }
30 | });
31 |
32 | export { CartContext };
33 |
--------------------------------------------------------------------------------
/src/Store/CartItem.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React, { useContext } from 'react';
18 | import { Link } from 'react-router-dom';
19 | import { Card, CardContent, IconButton, InputLabel, MenuItem, Select, Typography } from '@mui/material';
20 | import { Close } from '@mui/icons-material';
21 |
22 | import { CartContext } from './CartContext';
23 | import { CartItemDetails } from '../interfaces/CartItemDetails';
24 |
25 | import './List.css';
26 |
27 | /**Properties for the CartItem component */
28 | interface Props {
29 | cartItem: CartItemDetails;
30 | }
31 |
32 | /**CartItem React component
33 | *
34 | * @param {Props} props The details of the item in the cart
35 | */
36 | const CartItem: React.FC = (props: Props) => {
37 | // Get the cart from the current context
38 | const { cart, setCart } = useContext(CartContext);
39 |
40 | /**Handle changes to the quantity of an item in the cart
41 | *
42 | * @param {number} quantity The new quantity of the item
43 | */
44 | function handleQuantityChange(quantity: number) {
45 | // Find the index of the item in the cart
46 | const index = cart.findIndex(
47 | cartItem => cartItem.size === props.cartItem.size && cartItem.item.name === props.cartItem.item.name
48 | );
49 |
50 | // Index exists
51 | if (index !== -1) {
52 | // Copy the cart
53 | const newCart = [...cart];
54 |
55 | // Replace the item at the index with the new item (changing quantity)
56 | newCart.splice(index, 1, {
57 | ...cart[index],
58 | quantity
59 | });
60 |
61 | // Replace the cart with the updated one
62 | setCart(newCart);
63 | }
64 | }
65 |
66 | /**Handle removing an item from the cart */
67 | function handleRemoveClick() {
68 | // Find the index of the item in the cart
69 | const index = cart.findIndex(
70 | cartItem => cartItem.size === props.cartItem.size && cartItem.item.name === props.cartItem.item.name
71 | );
72 |
73 | // Index exists
74 | if (index !== -1) {
75 | // Copy the cart
76 | const newCart = [...cart];
77 |
78 | // Remove the item at the index
79 | newCart.splice(index, 1);
80 |
81 | // Replace the cart with the updated one
82 | setCart(newCart);
83 | }
84 | }
85 |
86 | // Return the CartItem React component
87 | return (
88 |
89 |
90 |
91 |
92 |
93 |
125 |
126 |
127 | );
128 | };
129 |
130 | export default CartItem;
131 |
--------------------------------------------------------------------------------
/src/Store/Category.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | .category-link {
18 | text-decoration: none;
19 | }
20 |
21 | .category-card {
22 | margin: 10px;
23 | }
24 |
25 | .category-image {
26 | height: 200px;
27 | }
28 |
29 | .category-card .category-content,
30 | .category-card .category-content:last-child {
31 | padding: 10px;
32 | }
33 |
--------------------------------------------------------------------------------
/src/Store/Category.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react';
18 | import { Link } from 'react-router-dom';
19 | import { Card, CardContent, CardMedia, Typography } from '@mui/material';
20 |
21 | import { CategoryDetails } from '../interfaces/CategoryDetails';
22 |
23 | import './Category.css';
24 |
25 | /**Category React component
26 | *
27 | * @param {CategoryDetails} props The details of the item categories
28 | */
29 | const Category: React.FC = (props: CategoryDetails) => {
30 | // Return the React component
31 | return (
32 |
33 |
34 |
35 |
36 | {props.title}
37 |
38 |
39 |
40 | );
41 | };
42 |
43 | export default Category;
44 |
--------------------------------------------------------------------------------
/src/Store/Checkout.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | .Checkout {
18 | margin: 20px auto;
19 | text-align: left;
20 | max-width: 1000px;
21 | }
22 |
23 | .Checkout .buttons {
24 | margin: 20px auto;
25 | max-width: 500px;
26 | }
27 |
28 | .Checkout .buttons>* {
29 | width: 100%;
30 | }
31 |
32 | .Checkout .checkout-grid {
33 | padding: 0 20px;
34 | }
35 |
--------------------------------------------------------------------------------
/src/Store/Checkout.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React, { useContext, useEffect, useState } from 'react';
18 | import { useNavigate } from 'react-router-dom';
19 | import { Button, Checkbox, FormControlLabel, Grid, TextField, Typography } from '@mui/material';
20 |
21 | import GooglePayButton from '@google-pay/button-react';
22 |
23 | import { buildPaymentRequest, getUpdatedPaymentData } from './GooglePay';
24 | import { CartContext } from './CartContext';
25 |
26 | import './Checkout.css';
27 |
28 | /**Properties for the Checkout component */
29 | interface Props {}
30 |
31 | /**Checkout React component */
32 | const Checkout: React.FC = () => {
33 | const navigate = useNavigate();
34 |
35 | // Get the cart from the current context
36 | const { cart, setCart } = useContext(CartContext);
37 |
38 | // Current Google Pay payment request details (if in state)
39 | const [paymentRequest, setPaymentRequest] = useState(buildPaymentRequest([]));
40 |
41 | // If the cart changes, update the payment request object
42 | useEffect(() => {
43 | Object.assign(
44 | paymentRequest,
45 | buildPaymentRequest(
46 | cart.map(itemDetail => {
47 | return {
48 | label: itemDetail.item.title,
49 | price: (itemDetail.quantity * itemDetail.item.price).toFixed(2),
50 | type: 'LINE_ITEM'
51 | };
52 | })
53 | )
54 | );
55 | setPaymentRequest(paymentRequest);
56 | }, [cart, paymentRequest]);
57 |
58 | /**Handles Google Pay checkout
59 | *
60 | * @param {google.payments.api.PaymentData} paymentData Google Pay payment data
61 | */
62 | function handleLoadPaymentData(paymentData: google.payments.api.PaymentData) {
63 | // Simply log to the console for this sample app
64 | // Normally this would be sent to a backend server for processing
65 | console.log('Payment data', paymentData);
66 |
67 | // Empty cart
68 | setCart([]);
69 |
70 | // Route the user to the success page
71 | navigate('/confirm');
72 | }
73 |
74 | /**Handles manual checkout (empty the cart and route to confirmation) */
75 | function handleCheckout() {
76 | setCart([]);
77 | navigate('/confirm');
78 | }
79 |
80 | // Return the React component
81 | return (
82 |
83 |
84 |
85 |
86 | Automatic checkout
87 |
88 |
89 |
90 | Skip the forms and check out with Google Pay!
91 |
92 |
93 |
235 | );
236 | };
237 |
238 | export default Checkout;
239 |
--------------------------------------------------------------------------------
/src/Store/Confirmation.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react';
18 | import { useNavigate } from 'react-router-dom';
19 | import { Button, Typography } from '@mui/material';
20 |
21 | import './Status.css';
22 |
23 | /**Properties for the Confirmation component */
24 | interface Props {}
25 |
26 | /**Confirmation React component
27 | *
28 | * @param {Props} props The details of the order confirmation
29 | */
30 | const Confirmation: React.FC = (props: Props) => {
31 | const navigate = useNavigate();
32 |
33 | // Return the React component
34 | return (
35 |
36 |
37 | Success
38 |
39 | Congratulations, on your purchase. The order has been received and is being processed.
40 |
41 |
42 | This is for demo purposes only. You have not been charged, the order is not being processed.
43 |
44 |
45 |
48 |
49 |
50 |
51 | );
52 | };
53 |
54 | export default Confirmation;
55 |
--------------------------------------------------------------------------------
/src/Store/GooglePay.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { paymentRequest } from '../config/GooglePay';
18 | import { shippingOptions } from '../config/ShippingOptions';
19 |
20 | /**Calculate and return the total price
21 | *
22 | * @param {google.payments.api.DisplayItem[]} displayItems The items in the user's cart
23 | * @returns {number} The total price
24 | */
25 | function calculateTotalPrice(displayItems: google.payments.api.DisplayItem[]): number {
26 | return displayItems.reduce((total, item) => total + Number(item.price), 0);
27 | }
28 |
29 | /**Build the Google Pay payment request
30 | *
31 | * @param {google.payments.api.DisplayItem[]} displayItems The items in the user's cart
32 | * @returns {google.payments.api.PaymentDataRequest} The payment data request
33 | */
34 | function buildPaymentRequest(displayItems: google.payments.api.DisplayItem[]): google.payments.api.PaymentDataRequest {
35 | return {
36 | ...paymentRequest,
37 | transactionInfo: {
38 | ...paymentRequest.transactionInfo,
39 | displayItems: [...displayItems],
40 | totalPrice: calculateTotalPrice(displayItems).toFixed(2)
41 | }
42 | };
43 | }
44 |
45 | /**Get the updated payment data from the payment request
46 | *
47 | * @param {google.payments.api.PaymentDataRequest} paymentRequest The original payment request
48 | * @param {google.payments.api.IntermediatePaymentData} paymentData The new intermediate payment data
49 | * @returns {google.payments.api.PaymentDataRequestUpdate} The updated payment request
50 | */
51 | function getUpdatedPaymentData(
52 | paymentRequest: google.payments.api.PaymentDataRequest,
53 | paymentData: google.payments.api.IntermediatePaymentData
54 | ): google.payments.api.PaymentDataRequestUpdate {
55 | // Check if a shipping option was chosen
56 | if (paymentData.shippingOptionData?.id) {
57 | // Get the shipping option from the available choices
58 | const shippingOption = shippingOptions.find(option => option.id === paymentData.shippingOptionData!.id);
59 |
60 | if (shippingOption) {
61 | // Update the shopping cart with the chosen shipping option
62 | const displayItems: google.payments.api.DisplayItem[] = [
63 | ...(paymentRequest.transactionInfo.displayItems || []),
64 | {
65 | label: shippingOption.label,
66 | price: shippingOption.price.toFixed(2),
67 | type: 'SHIPPING_OPTION'
68 | }
69 | ];
70 |
71 | // Return the updated transaction info and display items
72 | return {
73 | newTransactionInfo: {
74 | ...paymentRequest.transactionInfo,
75 | totalPrice: calculateTotalPrice(displayItems).toFixed(2),
76 | displayItems
77 | }
78 | };
79 | }
80 | }
81 |
82 | // The shipping option didn't change...return no changes
83 | // In a real-world scenario, this should also check for shopping cart updates,
84 | // promotion codes being added, and other use-cases
85 | return {};
86 | }
87 |
88 | export { buildPaymentRequest, getUpdatedPaymentData };
89 |
--------------------------------------------------------------------------------
/src/Store/Header.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https: //www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | .App .Header {
18 | background-color: #fff;
19 | color: #000;
20 | }
21 |
--------------------------------------------------------------------------------
/src/Store/Header.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React, { useContext, useEffect, useMemo, useState } from 'react';
18 | import { Link, useNavigate } from 'react-router-dom';
19 | import { AppBar, Badge, IconButton, Menu, MenuItem, Toolbar, Typography } from '@mui/material';
20 | import { Menu as MenuIcon, ShoppingCart } from '@mui/icons-material';
21 |
22 | import { CartContext } from './CartContext';
23 | import { CategoryDetails } from '../interfaces/CategoryDetails';
24 | import { StoreData } from './StoreData';
25 |
26 | import './Header.css';
27 |
28 | /**Header React component */
29 | export default function Header() {
30 | const navigate = useNavigate();
31 |
32 | // Manages store items, categories, etc.
33 | const storeData = useMemo(() => new StoreData(), []);
34 |
35 | // Current shopping cart from context
36 | const { cart } = useContext(CartContext);
37 |
38 | // Get the anchor element from the current state
39 | const [anchorEl, setAnchorEl] = useState(null);
40 |
41 | // Get the categories from the current state
42 | const [categories, setCategories] = useState([] as CategoryDetails[]);
43 |
44 | // If store data changes, update the categories
45 | useEffect(() => {
46 | storeData.getCategories().then(data => setCategories(data));
47 | }, [storeData]);
48 |
49 | // Handle clicks to the Shop menu
50 | const handleMenuClick = (event: React.MouseEvent) => {
51 | setAnchorEl(event.currentTarget);
52 | };
53 |
54 | // Handle clicks to a Shop menu item
55 | const handleMenuItemClick = (category: CategoryDetails) => {
56 | navigate(`/list/${category.name}`);
57 | setAnchorEl(null);
58 | };
59 |
60 | // Handle closing the Shop menu
61 | const handleMenuClose = () => {
62 | setAnchorEl(null);
63 | };
64 |
65 | // Handle clicks to the shopping cart
66 | const handleCartClick = (event: React.MouseEvent) => {
67 | navigate('/cart');
68 | };
69 |
70 | // Return the Header React component
71 | return (
72 |
73 |
74 |
75 |
76 |
77 |
84 |
85 | Shop
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 | );
95 | }
96 |
--------------------------------------------------------------------------------
/src/Store/Home.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https: //www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | .Home {
18 | text-align: center;
19 | margin: 15px auto;
20 | max-width: 800px;
21 | }
22 |
--------------------------------------------------------------------------------
/src/Store/Home.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react';
18 |
19 | import Category from './Category';
20 |
21 | import { CategoryDetails } from '../interfaces/CategoryDetails';
22 |
23 | import './Home.css';
24 |
25 | /**Properties for the Home component */
26 | interface Props {
27 | categories: CategoryDetails[];
28 | }
29 |
30 | /**Home React component
31 | *
32 | * @param {Props} props The details of the item categories
33 | */
34 | const Home: React.FC = (props: Props) => {
35 | // Return the Home React component
36 | return (
37 |
219 | );
220 | }
221 |
--------------------------------------------------------------------------------
/src/Store/List.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https: //www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | .List {
18 | margin: 10px auto;
19 | display: flex;
20 | flex-direction: row;
21 | flex-wrap: wrap;
22 | justify-content: center;
23 | max-width: 1000px;
24 | }
25 |
26 | .list-item-link {
27 | text-decoration: none;
28 | display: flex;
29 | flex-direction: column;
30 | }
31 |
32 | .list-item-card {
33 | margin: 5px;
34 | width: 175px;
35 | flex-grow: 1;
36 | display: flex;
37 | flex-direction: column;
38 | justify-content: center;
39 | }
40 |
41 | .list-item-image {
42 | height: 175px;
43 | margin-top: 10px;
44 | }
45 |
46 | .list-item-card .list-item-content {
47 | padding: 10px;
48 | display: flex;
49 | flex-direction: column;
50 | }
51 |
52 | .list-item-card .list-item-content:last-child {
53 | padding-bottom: 10px;
54 | }
55 |
56 | .list-item-card .list-item-content .title {
57 | font-size: 13px;
58 | }
59 |
--------------------------------------------------------------------------------
/src/Store/List.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React, { useEffect, useMemo, useState } from 'react';
18 | import { useParams } from 'react-router-dom';
19 |
20 | import ListItem from './ListItem';
21 |
22 | import { CategoryDetails } from '../interfaces/CategoryDetails';
23 | import { ItemDetails } from '../interfaces/ItemDetails';
24 | import { StoreData } from './StoreData';
25 |
26 | /**Properties for the List component */
27 | interface Props {
28 | categories: CategoryDetails[];
29 | }
30 |
31 | /**List React component
32 | *
33 | * @param {Props} props The details of the item categories
34 | */
35 | const List: React.FC = (props: Props) => {
36 | // Manages store items, categories, etc.
37 | const storeData = useMemo(() => new StoreData(), []);
38 |
39 | // Current item details (if in state)
40 | const [items, setItems] = useState([] as ItemDetails[]);
41 |
42 | // Current category details (if in state)
43 | const [category, setCategory] = useState();
44 |
45 | // Dynamic URL parameters
46 | const params = useParams<{ listId: string }>();
47 |
48 | // If the list ID or categories change, call setCategory
49 | useEffect(() => {
50 | setCategory(props.categories.find(cat => cat.name === params.listId));
51 | }, [params.listId, props.categories]);
52 |
53 | // If the category or store data changes, call getItemsByCategory
54 | useEffect(() => {
55 | if (!category) return;
56 | storeData.getItemsByCategory(category.name).then(data => setItems(data));
57 | }, [category, storeData]);
58 |
59 | // Return the React component
60 | return (
61 |
62 | {items.map(item => (
63 |
64 | ))}
65 |
66 | );
67 | };
68 |
69 | export default List;
70 |
--------------------------------------------------------------------------------
/src/Store/ListItem.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import './List.css';
18 | import { Card, CardContent, CardMedia, Typography } from '@mui/material';
19 | import { Link, useParams } from 'react-router-dom';
20 | import { ItemDetails } from '../interfaces/ItemDetails';
21 | import React from 'react';
22 |
23 | interface Props {
24 | item: ItemDetails;
25 | }
26 |
27 | const ListItem: React.FC = props => {
28 | const params = useParams<{ listId: string }>();
29 |
30 | return (
31 |
32 |
33 |
34 |
35 |
36 | {props.item.title}
37 |
38 |
39 | ${props.item.price.toFixed(2)}
40 |
41 |
42 |
43 |
44 | );
45 | };
46 |
47 | export default ListItem;
48 |
--------------------------------------------------------------------------------
/src/Store/Status.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | .Confirmation,
18 | .Error {
19 | margin: 20px;
20 | text-align: left;
21 | display: flex;
22 | flex-direction: column;
23 | }
24 |
25 | .Confirmation p,
26 | .Error p {
27 | margin: 10px 0;
28 | }
29 |
30 | .Confirmation .content,
31 | .Error .content {
32 | max-width: 500px;
33 | margin: 10px auto;
34 | }
35 |
36 | .Confirmation .buttons,
37 | .Error .buttons {
38 | margin-top: 20px;
39 | text-align: right;
40 | }
41 |
--------------------------------------------------------------------------------
/src/Store/StorageProvider.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | // Acts as local storage
18 | const map = new Map();
19 |
20 | /**Mock storage provider */
21 | export abstract class StorageProvider {
22 | /**Get a value
23 | *
24 | * @param {string} key The item's key in the map
25 | * @returns {T} The value of the item
26 | */
27 | public abstract get(key: string): T;
28 |
29 | /**Set a value
30 | *
31 | * @param {string} key The item's key in the map
32 | * @param {T} value The item's value
33 | */
34 | public abstract set(key: string, value: T): void;
35 |
36 | /**Create a new storage provider instance */
37 | public static create(): StorageProvider {
38 | // Check if a local storage provider has been created
39 | // If so, return it
40 | // If not, create a new one
41 | if (localStorage) {
42 | return new LocalStorageProvider();
43 | }
44 | return map;
45 | }
46 | }
47 |
48 | /**Mock local storage provider */
49 | export class LocalStorageProvider extends StorageProvider {
50 | /**Get a value
51 | *
52 | * @param {string} key The item's key in the map
53 | * @returns {T} The value of the item
54 | */
55 | public get(key: string): T {
56 | return JSON.parse(localStorage.getItem(key) || 'null');
57 | }
58 |
59 | /**Set a value
60 | *
61 | * @param {string} key The item's key in the map
62 | * @param {T} value The item's value
63 | */
64 | public set(key: string, value: T): void {
65 | localStorage.setItem(key, JSON.stringify(value));
66 | }
67 | }
68 |
--------------------------------------------------------------------------------
/src/Store/StoreData.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { CartItemDetails } from '../interfaces/CartItemDetails';
18 | import { categories } from '../config/CategoryDetails';
19 | import { CategoryDetails } from '../interfaces/CategoryDetails';
20 | import { ItemDetails } from '../interfaces/ItemDetails';
21 | import { StorageProvider } from './StorageProvider';
22 |
23 | /**The store, available items, etc. */
24 | export class StoreData {
25 | // Caches the items in the currently-selected category
26 | private itemCache = new Map>();
27 |
28 | // Handles local storage
29 | private storageProvider = StorageProvider.create();
30 |
31 | /**Get the list of available categories
32 | *
33 | * @returns {Promise} The available categories
34 | */
35 | public getCategories(): Promise {
36 | return Promise.resolve(categories);
37 | }
38 |
39 | /**Get the items for a specific category
40 | *
41 | * @param {string} name The category name
42 | * @returns {Promise} The items in the category
43 | */
44 | public getItemsByCategory(name: string): Promise {
45 | // Check if the items in the category are currently in local storage
46 | let promise = this.itemCache.get(name);
47 |
48 | // Found in cache, return this instead
49 | if (promise) return promise;
50 |
51 | // Fetch the items in the category from the JSON file
52 | promise = fetch(`/data/${name}.json`).then(response => response.json());
53 |
54 | // Cache the output
55 | this.itemCache.set(name, promise);
56 |
57 | // Return the items
58 | return promise;
59 | }
60 |
61 | /**Get a specific item from a category of items
62 | *
63 | * @param {string} category The category to search
64 | * @param {string} name The item name to search for
65 | * @return {Promise} The item, if found
66 | */
67 | public async getItem(category: string, name: string): Promise {
68 | // Get the items for this category
69 | const items = await this.getItemsByCategory(category);
70 |
71 | // Check if the item is in this list
72 | return items.find(item => item.name === name);
73 | }
74 |
75 | /**Add a selected item to the user's cart
76 | *
77 | * @param {ItemDetails} item The item to add
78 | * @param {string} size The size of the item to add
79 | * @param {number} quantity The number of this item to add
80 | */
81 | public addItemToCart(item: ItemDetails, size: string, quantity: number) {
82 | // Get the cart, if it exists in local storage
83 | let cart = this.storageProvider.get('cart') || [];
84 |
85 | // Check if the item already exists in the cart
86 | let existing = cart.find(c => c.item.name === item.name && c.size === size);
87 |
88 | if (!existing) {
89 | // Item doesn't exist
90 | existing = {
91 | item,
92 | size,
93 | quantity
94 | };
95 |
96 | // Add it to the cart
97 | cart = [...cart, existing];
98 | } else {
99 | // Item already exists
100 | // Update the selected quantity
101 | existing.quantity += quantity;
102 | }
103 |
104 | // Overwrite the cart with the updated version
105 | this.setCart(cart);
106 | }
107 |
108 | /**Get the current cart, if it exists
109 | *
110 | * @returns {CartItemDetails[]} The current cart, or an empty array
111 | */
112 | public getCart(): CartItemDetails[] {
113 | return this.storageProvider.get('cart') || [];
114 | }
115 |
116 | /**Update the user's cart with a new one
117 | *
118 | * @param {CartItemDetails[]} cart The new cart to use
119 | */
120 | public setCart(cart: CartItemDetails[]) {
121 | this.storageProvider.set('cart', cart);
122 | }
123 |
124 | /**Get the number of items in the cart
125 | *
126 | * @returns {number} The number of items in the cart
127 | */
128 | public getCartSize(): number {
129 | // Get the cart size from local storage
130 | return StoreData.getCartSize(this.getCart());
131 | }
132 |
133 | /**Get the number of items in the provided cart
134 | *
135 | * @param {CartItemDetails[]} cart The cart to inventory
136 | * @returns {number} The number of items in the cart
137 | * @staticmethod
138 | */
139 | public static getCartSize(cart: CartItemDetails[]): number {
140 | // Need to count the quantity of each item
141 | return cart.reduce((total, current) => total + current.quantity, 0);
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/src/Store/StoreService.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { CartItemDetails } from '../interfaces/CartItemDetails';
18 | import { shippingOptions } from '../config/ShippingOptions';
19 |
20 | /**Mock store services */
21 | export class StoreService {
22 | /**Retrieve the list of shipping options
23 | * @returns {google.payments.api.ShippingOptionParameters} The available shipping options
24 | */
25 | public getShippingOptionParameters(): google.payments.api.ShippingOptionParameters {
26 | // Default to free shipping
27 | return {
28 | defaultSelectedOptionId: 'free',
29 | shippingOptions: shippingOptions.map(o => ({
30 | id: o.id,
31 | label: o.label,
32 | description: o.description
33 | }))
34 | };
35 | }
36 |
37 | /**Calculate transaction info
38 | * @param {CartItemDetails[]} cart The user's shopping cart items
39 | * @param {google.payments.api.Address?} address The user's shipping address
40 | * @param {google.payments.api.SelectionOptionData?} shippingOptionData The shipping option chosen by the user
41 | * @returns {google.payments.api.TransactionInfo} The updated transaction information
42 | */
43 | public getTransactionInfo(
44 | cart: CartItemDetails[],
45 | address?: google.payments.api.Address,
46 | shippingOptionData?: google.payments.api.SelectionOptionData
47 | ): google.payments.api.TransactionInfo {
48 | // The items to display on the shopping cart screen
49 | const displayItems: google.payments.api.DisplayItem[] = cart.map(item => ({
50 | label: `${item.item.title} (${item.size}) x ${item.quantity}`,
51 | price: (item.item.price * item.quantity).toFixed(2),
52 | type: 'LINE_ITEM'
53 | }));
54 |
55 | // The subtotal (before tax, shipping, etc.)
56 | const subtotal = cart.reduce((total, item) => total + item.item.price * item.quantity, 0);
57 |
58 | // Get the shipping option chosen by the user
59 | const shippingOption = shippingOptions.find(option => option.id === shippingOptionData?.id);
60 |
61 | // Get the price of that shipping option
62 | const shipping = shippingOption?.price ?? 0;
63 |
64 | // Calculate tax
65 | const tax = this.getTaxRate(address) * subtotal;
66 |
67 | // Add subtotal, tax, and shipping for total cost
68 | const total = subtotal + shipping + tax;
69 |
70 | // Include the subtotal on the display
71 | displayItems.push({
72 | label: 'Sub total',
73 | price: subtotal.toFixed(2),
74 | type: 'SUBTOTAL'
75 | });
76 |
77 | // Include the chosen shipping option
78 | displayItems.push({
79 | label: shippingOption?.label ?? 'Shipping',
80 | price: shipping.toFixed(2),
81 | type: 'SHIPPING_OPTION'
82 | });
83 |
84 | // Include the tax
85 | if (tax > 0) {
86 | displayItems.push({
87 | label: 'Tax',
88 | price: tax.toFixed(2),
89 | type: 'TAX'
90 | });
91 | }
92 |
93 | // Return the items to display, the total, and currency
94 | return {
95 | displayItems,
96 | totalPrice: total.toFixed(2),
97 | totalPriceStatus: 'FINAL',
98 | totalPriceLabel: 'Total',
99 | currencyCode: 'USD',
100 | countryCode: 'US'
101 | };
102 | }
103 |
104 | /**Get the tax rate (percentage)
105 | * @param {google.payments.api.Address?} address The purchase address
106 | * @returns {number} The tax rate
107 | */
108 | public getTaxRate(address?: google.payments.api.Address): number {
109 | return address?.countryCode === 'US' ? 0.1 : 0.11;
110 | }
111 |
112 | /**Processes the order
113 | *
114 | * @param {CartItemDetails[]} cart The user's shopping cart
115 | * @param {google.payments.api.PaymentData} paymentData The payment data from Google Pay
116 | * @returns {Object} A mock order ID (today's date)
117 | */
118 | public processOrder(cart: CartItemDetails[], paymentData: google.payments.api.PaymentData): Object {
119 | // In a real-world scenario, this would be sent to same backend server to
120 | // process the payment.
121 | console.log(
122 | 'TODO: send order to server',
123 | paymentData.shippingAddress,
124 | paymentData.shippingOptionData?.id,
125 | paymentData.paymentMethodData
126 | );
127 |
128 | // Return a mock order ID (today's date)
129 | return Promise.resolve({
130 | orderId: Date.now().toString()
131 | });
132 | }
133 | }
134 |
--------------------------------------------------------------------------------
/src/config/CategoryDetails.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { CategoryDetails } from '../interfaces/CategoryDetails';
18 |
19 | /**The available merchandise categories */
20 | export const categories: CategoryDetails[] = [
21 | {
22 | name: 'mens_outerwear',
23 | title: 'Mens Outerwear',
24 | image: '/images/categories/mens_outerwear.jpg'
25 | },
26 | {
27 | name: 'ladies_outerwear',
28 | title: 'Ladies Outerwear',
29 | image: '/images/categories/ladies_outerwear.jpg'
30 | },
31 | {
32 | name: 'mens_tshirts',
33 | title: 'Mens T-Shirts',
34 | image: '/images/categories/mens_tshirts.jpg'
35 | },
36 | {
37 | name: 'ladies_tshirts',
38 | title: 'Ladies T-Shirts',
39 | image: '/images/categories/ladies_tshirts.jpg'
40 | }
41 | ];
42 |
--------------------------------------------------------------------------------
/src/config/GooglePay.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { shippingOptionParameters } from './ShippingOptions';
18 |
19 | /**The [Google Pay payment request](https://developers.google.com/pay/api/web/guides/tutorial)
20 | *
21 | * The `stripe:publishableKey` value is a [sample API key provided by Stripe](https://stripe.com/docs/payments/accept-a-payment).
22 | */
23 | export const paymentRequest: google.payments.api.PaymentDataRequest = {
24 | apiVersion: 2,
25 | apiVersionMinor: 0,
26 | allowedPaymentMethods: [
27 | {
28 | type: 'CARD',
29 | parameters: {
30 | allowedAuthMethods: ['PAN_ONLY', 'CRYPTOGRAM_3DS'],
31 | allowedCardNetworks: ['MASTERCARD', 'VISA']
32 | },
33 | tokenizationSpecification: {
34 | type: 'PAYMENT_GATEWAY',
35 | parameters: {
36 | 'gateway': 'stripe',
37 | 'stripe:version': '2018-10-31',
38 | 'stripe:publishableKey': 'pk_test_MNKMwKAvgdo2yKOhIeCOE6MZ00yS3mWShu'
39 | }
40 | }
41 | }
42 | ],
43 | merchantInfo: {
44 | merchantId: '17613812255336763067', // Test merchant ID provided by Google
45 | merchantName: 'Demo Only (you will not be charged)'
46 | },
47 | transactionInfo: {
48 | totalPriceStatus: 'FINAL',
49 | totalPriceLabel: 'Total',
50 | totalPrice: '0', // Force this to be zero for the sample app
51 | currencyCode: 'USD',
52 | countryCode: 'US'
53 | },
54 | shippingAddressRequired: true,
55 | shippingOptionParameters: shippingOptionParameters,
56 | shippingOptionRequired: true,
57 | callbackIntents: ['SHIPPING_ADDRESS', 'SHIPPING_OPTION']
58 | };
59 |
--------------------------------------------------------------------------------
/src/config/ShippingOptions.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /**The available shipping options, their cost, and descriptions */
18 | export const shippingOptions = [
19 | {
20 | id: 'free',
21 | label: 'Free shipping',
22 | description: 'Arrives in 5 to 7 days',
23 | price: 0
24 | },
25 | {
26 | id: 'express',
27 | label: 'Express shipping',
28 | description: '$5.00 - Arrives in 1 to 3 days',
29 | price: 5
30 | }
31 | ];
32 |
33 | /**The default selected shipping option and the available options to choose from */
34 | export const shippingOptionParameters: google.payments.api.ShippingOptionParameters = {
35 | defaultSelectedOptionId: 'free',
36 | shippingOptions: shippingOptions.map(o => ({
37 | id: o.id,
38 | label: o.label,
39 | description: o.description
40 | }))
41 | };
42 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https: //www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | body {
18 | margin: 0;
19 | font-family: 'Roboto', 'Noto', sans-serif;
20 | -webkit-font-smoothing: antialiased;
21 | -moz-osx-font-smoothing: grayscale;
22 | }
23 |
24 | code {
25 | font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
26 | monospace;
27 | }
28 |
--------------------------------------------------------------------------------
/src/index.ejs:
--------------------------------------------------------------------------------
1 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 | <%= htmlWebpackPlugin.options.title %>
24 |
25 |
26 |
27 |
28 |
29 |
32 |
33 |
34 |
35 |
--------------------------------------------------------------------------------
/src/index.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import React from 'react';
18 | import { createRoot } from 'react-dom/client';
19 |
20 | import App from './App';
21 | import './index.css';
22 |
23 | // Get the root container
24 | const container = document.getElementById('root');
25 |
26 | // Create a Root object
27 | const root = createRoot(container!);
28 |
29 | // Render the app in strict mode
30 | root.render(
31 |
32 |
33 |
34 | );
35 |
--------------------------------------------------------------------------------
/src/interfaces/CartItemDetails.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | import { ItemDetails } from './ItemDetails';
18 |
19 | /**The item, size, and quantity for an item in the user's cart */
20 | export interface CartItemDetails {
21 | item: ItemDetails;
22 | size: string;
23 | quantity: number;
24 | }
25 |
--------------------------------------------------------------------------------
/src/interfaces/CategoryDetails.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /**The name, title, and image path for a merchandise category */
18 | export interface CategoryDetails {
19 | name: string;
20 | title: string;
21 | image: string;
22 | }
23 |
--------------------------------------------------------------------------------
/src/interfaces/ItemDetails.tsx:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | /**The name, title, category, price, description, and image paths for an item */
18 | export interface ItemDetails {
19 | name: string;
20 | title: string;
21 | category: string;
22 | price: number;
23 | description: string;
24 | image: string;
25 | largeImage: string;
26 | }
27 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": [
5 | "dom",
6 | "dom.iterable",
7 | "esnext"
8 | ],
9 | "allowJs": true,
10 | "skipLibCheck": true,
11 | "esModuleInterop": true,
12 | "allowSyntheticDefaultImports": true,
13 | "strict": true,
14 | "forceConsistentCasingInFileNames": true,
15 | "module": "esnext",
16 | "moduleResolution": "node",
17 | "resolveJsonModule": true,
18 | "isolatedModules": true,
19 | "jsx": "react-jsx",
20 | "noFallthroughCasesInSwitch": true
21 | },
22 | "include": [
23 | "src"
24 | ]
25 | }
26 |
--------------------------------------------------------------------------------
/webpack.config.cjs:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright 2022 Google LLC
3 | *
4 | * Licensed under the Apache License, Version 2.0 (the "License");
5 | * you may not use this file except in compliance with the License.
6 | * You may obtain a copy of the License at
7 | *
8 | * https://www.apache.org/licenses/LICENSE-2.0
9 | *
10 | * Unless required by applicable law or agreed to in writing, software
11 | * distributed under the License is distributed on an "AS IS" BASIS,
12 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 | * See the License for the specific language governing permissions and
14 | * limitations under the License.
15 | */
16 |
17 | const path = require('path');
18 | const HtmlWebpackPlugin = require('html-webpack-plugin');
19 |
20 | module.exports = {
21 | entry: './src/index.tsx',
22 | mode: 'development',
23 | module: {
24 | rules: [
25 | {
26 | // Build JS/JSX using babel-loader
27 | // https://webpack.js.org/loaders/babel-loader/
28 | test: /\.(js|jsx)$/,
29 | exclude: /(node_modules|bower_components)/,
30 | loader: 'babel-loader',
31 | options: { presets: ['@babel/env'] }
32 | },
33 | {
34 | // Build TS/TSX with ts-loader
35 | // https://webpack.js.org/guides/typescript/
36 | test: /\.(ts|tsx)$/,
37 | exclude: /(node_modules|bower_components)/,
38 | loader: 'ts-loader'
39 | },
40 | {
41 | // Build CSS with style-loader
42 | // https://webpack.js.org/loaders/style-loader/
43 | test: /\.css$/,
44 | use: ['style-loader', 'css-loader']
45 | }
46 | ]
47 | },
48 | resolve: {
49 | extensions: ['*', '.js', '.jsx', '.ts', '.tsx'],
50 | fallback: {
51 | querystring: require.resolve('query-string')
52 | }
53 | },
54 | output: {
55 | // Output to `dist/` directory
56 | path: path.resolve(__dirname, 'dist'),
57 | publicPath: '/',
58 | filename: 'bundle.js'
59 | },
60 | devServer: {
61 | // Configure devServer to refresh when files are modified and
62 | // fix issues with refreshing the page on a non-root url
63 | port: 3000,
64 | hot: 'only',
65 | historyApiFallback: true
66 | },
67 | plugins: [
68 | // Build dist/index.html from src/index.ejs using html-webpack-plugin
69 | // https://webpack.js.org/plugins/html-webpack-plugin/
70 | new HtmlWebpackPlugin({
71 | title: 'React Store',
72 | favicon: path.join(__dirname, 'public/favicon.svg'),
73 | meta: {
74 | charset: 'utf-8',
75 | viewport: 'width=device-width, initial-scale=1, shrink-to-fit=no'
76 | }
77 | })
78 | ]
79 | };
80 |
--------------------------------------------------------------------------------