294 Commits

Author SHA1 Message Date
look-its-ashton
4ba7029aba Merge pull request #114 from CODE-REFINARY/main
Aesthetic Adjustments, Name adjusted to "My Meal Journal"
2023-01-04 13:42:11 -08:00
George Dubinin
ff4ceed4c8 Update README.md 2023-01-04 13:32:22 -08:00
George Dubinin
1670da2527 Update README.md 2023-01-04 13:32:09 -08:00
George Dubinin
aa7e13b205 Update ReviewDetails.html 2023-01-04 13:31:04 -08:00
George Dubinin
9d514f2228 Update CreatePage.html 2023-01-04 13:30:31 -08:00
George Dubinin
4731544a26 Update README.md 2023-01-04 13:29:21 -08:00
George Dubinin
6af3bb2927 Update README.md 2023-01-04 13:27:19 -08:00
George Dubinin
ec46770a02 Update README.md 2023-01-04 13:25:17 -08:00
George Dubinin
d4a96f0cc2 Update README.md 2023-01-04 13:24:57 -08:00
George Dubinin
751cd964ac Update index.html 2023-01-04 13:15:52 -08:00
George Dubinin
416f32a552 Update team.md 2023-01-04 13:08:56 -08:00
George Dubinin
1012cc56d5 Update README.md 2023-01-04 13:06:36 -08:00
George Dubinin
30ffe3087c Update README.md 2023-01-04 13:06:02 -08:00
rheabhutada02
c1118b65bb Update final-videos.md 2022-12-07 21:07:57 -08:00
rheabhutada02
e3c87987be Update final-videos.md 2022-12-07 14:51:57 -08:00
rheabhutada02
7b53862773 Update final-videos.md 2022-12-07 14:51:40 -08:00
rheabhutada02
a0c2760b1e Create final-videos.md 2022-12-07 14:21:18 -08:00
Arthur Lu
65224d88c7 Merge pull request #113 from cse110-fa22-group29/change-demo
Change search bar placeholder to "Search by tags..."
2022-12-06 19:03:20 -08:00
Arthur Lu
3e83720e6a change search bar placeholder to "Search by tags..." 2022-12-07 02:58:45 +00:00
rheabhutada02
5d90e7636f Merge pull request #112 from cse110-fa22-group29/mini-changes
updated logo design
2022-12-06 00:07:52 -08:00
d7hernan
2ab051c672 updated logo design 2022-12-05 20:01:12 -08:00
Arthur Lu
e7bcf3f254 Merge pull request #110 from cse110-fa22-group29/mini-changes
End Sprint Modifications
2022-12-05 19:05:47 -08:00
Arthur Lu
f48cc18b38 fix prettier linting
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-12-05 22:20:17 +00:00
Arthur Lu
2640b10a2d Merge pull request #111 from cse110-fa22-group29/try-nyc
Implement c8 Code Coverage Testing
2022-12-04 22:44:17 -08:00
Arthur Lu
0d27862c89 try no sudo 2022-12-04 19:52:41 -08:00
Arthur Lu
cb5882a04f try loglevel verbose 2022-12-04 19:49:21 -08:00
Arthur Lu
08bd1dc3ba add coverage check, try permision fix 2022-12-04 19:44:30 -08:00
Arthur Lu
35c8619f87 switch to c8 2022-12-04 19:38:52 -08:00
Arthur Lu
6d8dc93543 try nyc 2022-12-04 19:31:27 -08:00
Gavyn Ezell
aad4f70304 min icomment run thru 2022-12-04 18:32:15 -08:00
Kara Hoagland
a1499013dc -Req Star Message
-Load More Position
-Cancel Update Form
2022-12-04 17:53:13 -08:00
Arthur Lu
b15c31722f Merge pull request #109 from cse110-fa22-group29/fix-sprint3-merge
workaround for jsdoc global scope requirement
2022-12-03 13:03:23 -08:00
Arthur Lu
8635ca87a1 workaround for jsdoc global scope requirement 2022-12-03 21:02:56 +00:00
Arthur Lu
c6b7134704 Merge pull request #108 from cse110-fa22-group29/fix-sprint3-merge
fix jsdoc dependency
2022-12-03 12:54:54 -08:00
Arthur Lu
4d9c4f854b fix jsdoc dependency 2022-12-03 20:54:25 +00:00
Arthur Lu
3688e71a33 Merge pull request #107 from cse110-fa22-group29/fix-sprint3-merge
fix js-doc missing command
2022-12-03 12:49:39 -08:00
Arthur Lu
4ce4f2b2e2 fix js-doc missing command 2022-12-03 20:49:16 +00:00
Arthur Lu
6be461cb08 Merge pull request #106 from cse110-fa22-group29/fix-main-sprint1md
Move sprint 1 meeting notes to right folder
2022-12-03 12:45:44 -08:00
Arthur Lu
a2948f7aa8 move file to right folder 2022-12-03 20:44:38 +00:00
Arthur Lu
e9d33edf00 Merge pull request #90 from cse110-fa22-group29/sprint-3
Sprint 3
2022-12-03 12:39:42 -08:00
Kara Hoagland
b364d79ef8 Merge branch 'sprint-3' of https://github.com/cse110-fa22-group29/cse110-fa22-group29 into sprint-3 2022-12-02 18:31:44 -08:00
Kara Hoagland
9e20782c07 lowercase tag fix part2 2022-12-02 18:31:26 -08:00
Arthur Lu
a722d755fd fix prettier action
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-12-03 02:16:27 +00:00
Arthur Lu
793e7891b3 prettier style fixes
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-12-03 02:02:52 +00:00
Arthur Lu
dbbd14399e fix updateReviewToStorage bug with capitalized tag handling,
remove unnecessary overflow-wrap in ReviewCard.js

Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-12-03 00:14:49 +00:00
Arthur Lu
89dfe3293d fix html linting issue (indentation) 2022-12-02 04:05:24 +00:00
dusk-moon
ac9b101b47 Merge pull request #103 from cse110-fa22-group29/49-image-feature
Adding implementation of the photo taking feature to sprint-3
2022-12-01 19:56:02 -08:00
Henry Feng
1c38198fc7 Merge branch '49-image-feature' of https://github.com/cse110-fa22-group29/cse110-fa22-group29 into 49-image-feature 2022-12-01 19:48:01 -08:00
Henry Feng
fa32a61df9 Merge branch 'sprint-3' into 49-image-feature 2022-12-01 19:39:06 -08:00
Arthur Lu
32dbb37034 remove typo sw asset 2022-12-02 03:24:08 +00:00
Arthur Lu
396bbf06d2 fix css linting issue
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-12-02 01:23:40 +00:00
Arthur Lu
1f79340896 remove extra prettier workflow file
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-12-02 01:18:48 +00:00
Arthur Lu
ab7d3b1abd fix missing brancket issue in package.json
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-12-02 01:16:47 +00:00
Arthur Lu
f863f35de7 Merge branch 'main' into sprint-3 2022-12-01 17:06:37 -08:00
Arthur Lu
b07c99f805 fix css linting
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-12-01 17:02:09 -08:00
Arthur Lu
82aba63baf fix styling issue,
fix bug in service worker and search URI

Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-12-01 17:01:05 -08:00
Arthur Lu
8924540757 fix service worker inital cache items
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-12-01 16:48:15 -08:00
rheabhutada02
f0f706e575 Merge pull request #102 from cse110-fa22-group29/filter-sort
Filter and Sort Functionality
2022-12-01 16:39:02 -08:00
Kara Hoagland
469b2bca36 Merge branch 'sprint-3' into 49-image-feature 2022-12-01 16:36:25 -08:00
Kara Hoagland
e9bae6fe2d Merge branch 'sprint-3' into filter-sort 2022-12-01 16:29:09 -08:00
Arthur Lu
cf7b0da5ad fix tests to match modified localStorage layout
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-12-01 16:25:15 -08:00
Kara Hoagland
3145a99e23 most recent if updated 2022-12-01 16:00:51 -08:00
rheabhutada02
b8271dd5b0 Merge pull request #104 from cse110-fa22-group29/add-sw-caching
Add service worker caching towards local first functionality
2022-12-01 14:37:32 -08:00
Arthur Lu
1a1f5d8e1f finalize ADR
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-12-01 22:35:48 +00:00
Arthur Lu
730f904a58 fix style
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-12-01 22:32:50 +00:00
look-its-ashton
b61ea4e54d added checking meeting for week 10 2022-12-01 12:17:08 -08:00
Arthur Lu
7cb90e23c0 add comments and docs to sw.js,
add service worker ADR
2022-12-01 08:37:49 +00:00
Arthur Lu
1ed46b8ade implement fix for strange first load cache behavior 2022-12-01 08:09:22 +00:00
Arthur Lu
d95f0036ac clean up some styling 2022-12-01 07:36:19 +00:00
Sanjit Joseph
df80486f45 Decrease create button size 2022-11-30 22:01:24 -08:00
Sanjit Joseph
e2b9c98176 Removed unusued plate art 2022-11-30 21:32:01 -08:00
Sanjit Joseph
be31dbfbd7 Style search bar 2022-11-30 18:09:09 -08:00
Sanjit Joseph
78f627b39d Change text from 'filtering method' to 'sorting method' 2022-11-30 18:02:07 -08:00
Sanjit Joseph
d964d1e275 Edit style for search bar 2022-11-30 18:01:33 -08:00
Sanjit Joseph
c09e82c6ab Move filter bar inline with search 2022-11-30 17:42:51 -08:00
Sanjit Joseph
f300c740c4 Move filter bar to separate div 2022-11-30 17:31:47 -08:00
Sanjit Joseph
79e7561beb Disallow dragging on invisible create button 2022-11-30 17:24:26 -08:00
Sanjit Joseph
18f79936fe Move create_button styling out of index.html 2022-11-30 17:21:03 -08:00
Sanjit Joseph
42a560ab0e Rename Grouppink (?) to create_button.png 2022-11-30 17:18:49 -08:00
Sanjit Joseph
18a3230ad7 Merge branch 'filter-sort' of https://github.com/cse110-fa22-group29/cse110-fa22-group29 into filter-sort 2022-11-30 17:12:36 -08:00
Sanjit Joseph
1347e3bbc1 Implement new create button 2022-11-30 17:11:57 -08:00
Sanjit Joseph
7b8fea9d67 Upload new create button 2022-11-30 17:11:39 -08:00
Arthur Lu
eb3133c676 fix ReviewCard.js element id issue
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-30 17:02:42 -08:00
look-its-ashton
4d40c72158 Sprint 3 Meeting 2 Notes 2022-11-30 16:56:59 -08:00
Arthur Lu
11b152fec9 Merge branch 'filter-sort' of https://github.com/cse110-fa22-group29/cse110-fa22-group29 into filter-sort 2022-11-30 16:36:23 -08:00
Arthur Lu
64d57ffd90 fix review details html id consistency,
fix appTestHelpers with proper element selection

Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-30 16:36:21 -08:00
Kara Hoagland
23bf3a2c84 fix create page tag duplicate 2022-11-30 16:35:45 -08:00
Arthur Lu
3580941207 Add functional service worker caching towards local first functionality,
fix favicon link issue in ReviewDetails.html
Co-authored-by: rheabhutada02 <rheabhutada02@users.noreply.github.com>

Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-30 16:18:18 -08:00
Kara Hoagland
9bc5b5624b add clear search and no result 2022-11-30 16:11:42 -08:00
Henry Feng
0d17ddee53 Implementation of photo taking feature 2022-11-30 15:59:43 -08:00
Arthur Lu
fa7b8dc7f5 add text break to Form.css
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-30 14:58:34 -08:00
Arthur Lu
5943a5c8ef update tests to match new tag and sorting helper prototypes,
remove getTopReviewsFromStorage and getReviewsByTag from localStorage and main

Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-30 14:49:41 -08:00
Kara Hoagland
5621139dd7 added different filtering methods + load more btn 2022-11-30 02:49:49 -08:00
Kara Hoagland
a65b65d748 add tag search
add top rating sort
add star localstorage
2022-11-29 20:51:45 -08:00
look-its-ashton
7cac0bc0a8 Merge branch 'main' of https://github.com/cse110-fa22-group29/cse110-fa22-group29 2022-11-29 19:30:43 -08:00
look-its-ashton
30d01e33c9 Sprint 3 Tuesday Meeting Notes Added 2022-11-29 19:30:33 -08:00
rheabhutada02
841cb1df14 Merge pull request #101 from cse110-fa22-group29/cicd-phase-2
CI phase 2
2022-11-29 18:50:22 -08:00
Graydogminer
b3a8add8ee add phase 2 video 2022-11-29 17:42:23 -08:00
rheabhutada02
842c703d1a Merge pull request #100 from cse110-fa22-group29/backend-adrs
important backend adrs
2022-11-29 17:39:31 -08:00
Gavyn Ezell
a5fa45b054 important backend adrs 2022-11-29 17:35:38 -08:00
Henry Feng
20cdc4ce76 Merge remote-tracking branch 'origin/sprint-3' into 49-image-feature 2022-11-29 17:21:55 -08:00
rheabhutada02
a68bf60f44 Rename 112922-doccumentation-jsdoc.md to 112922-documentation-jsdoc.md 2022-11-29 16:20:25 -08:00
rheabhutada02
d01c4d2ef5 documentation updates for html files 2022-11-29 16:17:26 -08:00
rheabhutada02
58e4f6fdeb Documentation for ReviewDetails.js 2022-11-29 16:13:58 -08:00
rheabhutada02
ea41495e49 documentation 2022-11-29 15:59:57 -08:00
rheabhutada02
5405cbfd7c Documented CreatePage.js 2022-11-29 15:39:43 -08:00
rheabhutada02
6ca0ee1763 Merge branch 'main' of https://github.com/cse110-fa22-group29/cse110-fa22-group29 2022-11-29 15:10:23 -08:00
rheabhutada02
7757d1d0da Documented CreatePage.html 2022-11-29 15:10:20 -08:00
rheabhutada02
5aa1616f17 Merge pull request #99 from cse110-fa22-group29/add-prettier
Add prettier
2022-11-29 14:53:48 -08:00
Arthur Lu
529f24f306 update phase 2 with future ci features 2022-11-29 22:51:03 +00:00
Arthur Lu
c1fd10c268 update cicd phase 2 status 2022-11-29 22:46:16 +00:00
Arthur Lu
e74b3f5597 add prettier requirements and commands,
add prettier ADR,
add prettier action
2022-11-29 22:38:22 +00:00
rheabhutada02
eb4cb54b05 Merge pull request #92 from cse110-fa22-group29/separate-tag-storage
Individual Tags in Local Storage
2022-11-29 14:28:39 -08:00
Kara Hoagland
6a0708a3f0 moved break for delete 2022-11-29 14:27:48 -08:00
rheabhutada02
fbea45e151 Delete js-docs.yml 2022-11-29 14:27:11 -08:00
rheabhutada02
68020ccae7 Merge pull request #97 from cse110-fa22-group29/add-js-docs
Add JSDoc
2022-11-29 14:25:44 -08:00
Arthur Lu
603fb849f3 add explanation of JSDoc usage to ADR 2022-11-29 22:23:24 +00:00
Arthur Lu
dcee487737 add JSDoc ADR,
add JSDoc to publish action
2022-11-29 22:18:32 +00:00
Kara Hoagland
1cdaa63935 delete tag bug 2022-11-29 14:16:17 -08:00
Arthur Lu
929de8c98b fix js-doc command 2022-11-29 22:11:12 +00:00
Graydogminer
beb3e6cc98 added JS Docs to workflow 2022-11-29 13:59:02 -08:00
Marc
131e14d611 added jsdocs to package.json 2022-11-29 21:53:05 +00:00
Arthur Lu
bc6012af76 fix perttier action naming 2022-11-29 13:49:57 -08:00
rheabhutada02
5ee4c4d231 Merge pull request #96 from cse110-fa22-group29/prettier-init-changes
Add prettier linting
2022-11-29 13:44:56 -08:00
rheabhutada02
fd07a93d50 Merge pull request #95 from cse110-fa22-group29/remove-.vscode
Remove .vscode folder
2022-11-29 13:42:22 -08:00
look-its-ashton
9d7a928032 Rename 112722-retrospective2.md to 112822-retrospective.md 2022-11-29 13:25:27 -08:00
Arthur Lu
29fca61a85 add and update phase 2 docs 2022-11-29 13:18:30 -08:00
Arthur Lu
5c4e4c38f4 add prettier lint action 2022-11-29 08:32:45 -08:00
Arthur Lu
b7d79b6b50 remove .vscode folder,
add .vscode to .gitignore
2022-11-29 08:20:53 -08:00
Arthur Lu
0ca848e26b add prettier to devDependencies,
add lint-prettier and fix-prettier commands
2022-11-29 08:15:59 -08:00
Kara Hoagland
847e8a1aa1 No tag duplicates 2022-11-28 18:48:55 -08:00
look-its-ashton
46bdee7b68 Retrospective 2 Meeting Notes 2022-11-28 16:45:33 -08:00
look-its-ashton
f44d8713a0 Added Gavin's section 2022-11-28 14:02:55 -08:00
look-its-ashton
7bdeafa483 added Daniels progress to sprint review 2 2022-11-27 23:59:00 -08:00
Kara Hoagland
5e06bd0cf7 Merge branch 'sprint-3' into separate-tag-storage 2022-11-27 20:34:12 -08:00
Kara Hoagland
dd0bcbe57d moved from details to localStorage 2022-11-27 17:31:13 -08:00
look-its-ashton
f91520ed85 Merge pull request #93 from cse110-fa22-group29/sprint-2
Sprint 2
2022-11-27 17:23:07 -08:00
look-its-ashton
e77fe1406c Sprint 2 typo 2022-11-27 17:14:33 -08:00
look-its-ashton
57be3a11ed Merge branch 'sprint-2' of https://github.com/cse110-fa22-group29/cse110-fa22-group29 into sprint-2 2022-11-27 17:07:34 -08:00
look-its-ashton
c381bd1f60 retrospectiev 2 started and sprint 2 review 2.md 2022-11-27 17:07:10 -08:00
Kara Hoagland
1484a882b2 tag storage 2022-11-27 15:48:00 -08:00
Arthur Lu
f99cfd0eff fix tag vertical fitting issue
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-26 18:39:33 -08:00
Arthur Lu
a63552f32b fix ReviewCard css,
fixes article tag overflow issue,
should resolve #85

Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-26 18:00:09 -08:00
Arthur Lu
ae2e14172d change #d-mealImg to #d-meal-img and #d-mealName to #d-meal-name
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-26 17:38:19 -08:00
Arthur Lu
af4378ee40 fix some linting issues,
fix bug in localStroage unit tests

Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-26 16:06:24 -08:00
Arthur Lu
39aa535864 cleanup e2e test code
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-26 16:03:47 -08:00
Arthur Lu
9ff58a1c2c add sorting and filtering localStorage helper functions,
add new unit tests for new helper functions

Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-26 15:37:48 -08:00
Sanjit Joseph
4c649e7770 Update favicon with current logo 2022-11-24 02:41:02 -08:00
Sanjit Joseph
5db9320dae Give the raccoon a chef's hat 2022-11-24 02:36:02 -08:00
Sanjit Joseph
b2dd734ade Add hover text to new entry button 2022-11-24 02:27:27 -08:00
Sanjit Joseph
622d324c9a Add rounded corners to food image element 2022-11-24 02:24:37 -08:00
Sanjit Joseph
5901888475 Add hover text to home/edit/delete buttons 2022-11-24 02:13:41 -08:00
Sanjit Joseph
de1ec502b1 Fix default image cropping issues + add caption 2022-11-23 18:04:09 -08:00
Sanjit Joseph
4832726b14 Update E2E tests to check for new default image 2022-11-23 17:22:23 -08:00
Sanjit Joseph
0b7e101bb2 Select default_plate image when no food image uploaded 2022-11-23 17:20:55 -08:00
rheabhutada02
e6ac5ea33d Update 111622-checkin6.md 2022-11-23 15:59:30 -08:00
rheabhutada02
31633ff825 Update 112322-checkin7.md 2022-11-23 15:59:06 -08:00
rheabhutada02
5443b61825 Update 112322-checkin7.md 2022-11-23 15:58:54 -08:00
rheabhutada02
aeab069dec Create 112322-checkin7.md 2022-11-23 15:58:15 -08:00
Sanjit Joseph
f5d9b6e906 Upload status video 1 2022-11-22 21:45:45 -08:00
Sanjit Joseph
3ebefac2db Delete statusvideo1.mp4
Fixing commit message shenanigans
2022-11-22 21:44:03 -08:00
Sanjit Joseph
a9bf42a849 Merge pull request #88 from sm-joseph/main
Upload status video 1
2022-11-22 21:38:41 -08:00
Sanjit Joseph
53f51bce5f Upload status video 1 2022-11-22 21:37:12 -08:00
Sanjit Joseph
1017bd48a2 Merge pull request #87 from sm-joseph/main
Fix commit message linking to unwanted pr
2022-11-22 21:26:55 -08:00
Sanjit Joseph
3131391d92 Merge branch 'cse110-fa22-group29:main' into main 2022-11-22 21:24:25 -08:00
Sanjit Joseph
88ac0aea66 Upload status video 1 2022-11-22 21:23:05 -08:00
Sanjit Joseph
c7d2a5434d Merge pull request #86 from sm-joseph/main
Upload status video #1
2022-11-22 21:11:53 -08:00
Sanjit Joseph
ade244707a Upload status video #1 2022-11-22 21:10:50 -08:00
Arthur Lu
33e619c2d5 Merge pull request #79 from cse110-fa22-group29/sprint-2
Sprint 2
2022-11-22 16:40:27 -08:00
Arthur Lu
83a0358869 fix form tag wrap issue
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-22 14:46:01 -08:00
Arthur Lu
5ba0dab1a1 fix flex-flow css linting issue
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-21 18:00:58 -08:00
Arthur Lu
1dfd8c91a2 fix css linting issues
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-21 17:55:44 -08:00
Arthur Lu
ecff5313a1 increase timeout for e2e tests
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-21 17:38:34 -08:00
Arthur Lu
a12de4e058 fix some more css issues
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-21 17:31:12 -08:00
Arthur Lu
9194dd5166 fix html linting and some css linting issues
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-21 17:27:18 -08:00
Arthur Lu
63a7d5ce1f Merge pull request #84 from cse110-fa22-group29/sprint-2-css-review-details
Sprint 2 css review details
2022-11-21 17:20:36 -08:00
Arthur Lu
9f9ac19b71 fix ReviewDetails CreatePage large tag display issue
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-21 17:20:12 -08:00
rheabhutada02
0912ea7956 fixed logo and tags
Co-authored-by: Kara Hoagland <KH-Cl@users.noreply.github.com>
Co-authored-by: Arthur Lu <learthurgo@gmail.com>
Co-authored-by: d7hernan <d7hernan@users.noreply.github.com>
2022-11-21 17:03:10 -08:00
rheabhutada02
b5e5a88163 fixed the pathing issue for images in main.e2e.test.js 2022-11-21 16:14:09 -08:00
rheabhutada02
5f1a246e6a moved all the icons to images and fixed path issues associated with this move 2022-11-21 16:12:17 -08:00
rheabhutada02
4073d2cc4b fixed and styled review details page
Co-authored-by: Kara Hoagland <KH-Cl@users.noreply.github.com>
Co-authored-by: Arthur Lu <learthurgo@gmail.com>
Co-authored-by: d7hernan <d7hernan@users.noreply.github.com>
2022-11-21 16:07:20 -08:00
rheabhutada02
23657853e5 Merge branch 'sprint-2-css-review-details' of https://github.com/cse110-fa22-group29/cse110-fa22-group29 into sprint-2-css-review-details 2022-11-21 15:28:23 -08:00
rheabhutada02
ec9d0246ca fixed the update form, and update functionality, and formatted
Co-authored-by: Kara Hoagland <KH-Cl@users.noreply.github.com>
Co-authored-by: Arthur Lu <learthurgo@gmail.com>
2022-11-21 15:27:45 -08:00
Arthur Lu
1cbefee26f fix favicon linking
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-21 14:37:37 -08:00
Arthur Lu
dd56207892 fix update form listener
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-21 14:26:54 -08:00
rheabhutada02
123057f0f1 fixed the css linking 2022-11-21 13:56:00 -08:00
rheabhutada02
50283be4f5 renamed the file 2022-11-21 13:52:48 -08:00
rheabhutada02
46b1ec4b07 fixed form formatting, moved it to its own file 2022-11-21 13:52:44 -08:00
rheabhutada02
661feafa40 Merge branch 'sprint-2-css-review-details' of https://github.com/cse110-fa22-group29/cse110-fa22-group29 into sprint-2-css-review-details
Co-authored-by: Arthur Lu <learthurgo@gmail.com>
Co-authored-by: Kara Hoagland <KH-Cl@users.noreply.github.com>
2022-11-21 12:35:52 -08:00
rheabhutada02
68b0c8edf5 cleaned css and html
Co-authored-by: Arthur Lu <learthurgo@gmail.com>
2022-11-21 12:32:54 -08:00
Kara Hoagland
5d2c446551 Merge pull request #83 from cse110-fa22-group29/remove-alt-img
remove alt from js/html/tests
2022-11-21 12:32:50 -08:00
Kara Hoagland
52bc6a27a4 default img if img fails to load 2022-11-21 12:29:06 -08:00
Kara Hoagland
1db54e9f7a remove alt from js/html/tests 2022-11-21 11:58:26 -08:00
look-its-ashton
d70881c912 sprint2 meeting 3 notes 2022-11-21 11:16:05 -08:00
d7hernan
1798835807 modified css for CreatePage and color palette for homepage
Co-authored-by: rheabhutada02
Co-authored-by: Kara Hoagland
2022-11-21 00:56:54 -08:00
rheabhutada02
1055f7ef26 updating font 2022-11-20 23:50:54 -08:00
Kara Hoagland
5a05741e08 Merge pull request #80 from cse110-fa22-group29/req-stars-fix
Req stars fix
2022-11-20 23:37:45 -08:00
d7hernan
4c5132c2b2 Merge branch 'sprint-2' into sprint-2-css-review-details 2022-11-20 22:49:51 -08:00
d7hernan
49f85d5468 color palette changes 2022-11-20 22:35:02 -08:00
d7hernan
9ef3c59fee added restaurant, tag, and comments to reviewDetails
Co-authored-by: rheabhutada02
2022-11-20 22:22:31 -08:00
d7hernan
069aff88af centered search journal form 2022-11-20 21:58:44 -08:00
d7hernan
6d126f6085 Merge branch 'sprint-2-css-review-details' of https://github.com/cse110-fa22-group29/cse110-fa22-group29 into sprint-2-css-review-details 2022-11-20 21:21:25 -08:00
d7hernan
948f638cd7 fixed indentation 2022-11-20 21:21:18 -08:00
Arthur Lu
b24b1110f6 configure htmlHint and stylelint to use tab indentation,
fix html and css linting issues
2022-11-21 03:50:54 +00:00
Arthur Lu
eed39f580f cleanup css in homepage.css and index.html 2022-11-21 03:17:32 +00:00
Arthur Lu
259018ca97 fix linting issue 2022-11-21 03:06:47 +00:00
Arthur Lu
142e6d93b6 set e2e test connection to 2 seconds 2022-11-21 02:53:50 +00:00
Arthur Lu
a5ac2dc940 fix review card spacing and centering in homepage
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-20 17:03:55 -08:00
Arthur Lu
331f8e731c add some padding to icons
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-20 16:54:15 -08:00
Arthur Lu
19bbabe9b4 Merge pull request #82 from cse110-fa22-group29/sprint-2-css-review-details
Implement css and js for ReviewDetails
2022-11-20 16:41:41 -08:00
Arthur Lu
4336157371 Merge branch 'sprint-2' into sprint-2-css-review-details 2022-11-20 16:41:35 -08:00
Arthur Lu
9e82dae202 add comment for homepage mobile logic
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-20 16:39:51 -08:00
Arthur Lu
ccbf060c8c Merge branch 'sprint-2' of https://github.com/cse110-fa22-group29/cse110-fa22-group29 into sprint-2 2022-11-20 16:31:34 -08:00
Arthur Lu
1f832aadd2 fix homepage structal issues,
TODO: clean css

Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-20 16:31:32 -08:00
d7hernan
6ce15a094e css and js for ReviewDetails
Co-authored-by: Kara Hoagland <KH-Cl@users.noreply.github.com>
Co-authored-by: Arthur Lu <learthurgo@gmail.com>
2022-11-20 16:27:27 -08:00
Graydogminer
8a1c210515 fix htmlhint to allow tabs for indent 2022-11-20 16:20:23 -08:00
look-its-ashton
c412282e04 Merge branch 'sprint-2' of https://github.com/cse110-fa22-group29/cse110-fa22-group29 into sprint-2 2022-11-20 15:46:37 -08:00
look-its-ashton
8c2ad629d2 updated main page 2022-11-20 15:46:13 -08:00
Arthur Lu
7b7abad2e6 fix error in test syntax
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-20 15:33:31 -08:00
Arthur Lu
70c863c378 Merge branch 'add-multiple-testing' into sprint-2 2022-11-20 15:29:16 -08:00
Arthur Lu
12e818e079 fix js linting
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-20 15:23:22 -08:00
Kara Hoagland
250617776b more details 2022-11-20 14:47:26 -08:00
Arthur Lu
9c531771f2 Merge pull request #75 from cse110-fa22-group29/allow-for-user-uploaded-images
implementation of basic image local storage
2022-11-20 14:43:50 -08:00
Henry Feng
131553ddeb Merge remote-tracking branch 'origin/sprint-2' into allow-for-user-uploaded-images 2022-11-20 14:40:17 -08:00
Arthur Lu
c5cc7bf309 update github actions with new npm script naming
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-20 14:36:13 -08:00
Kara Hoagland
302af4bbd5 tempIfElseAlert 2022-11-20 14:36:03 -08:00
Henry Feng
3c7b5f7f4e addresses case where image is not updated 2022-11-20 14:27:24 -08:00
Marc
3a7ed2fb16 fix stylelint to allow tabs as indent 2022-11-20 14:26:48 -08:00
Arthur Lu
dd3e0cfefb Merge branch 'sprint-2' of https://github.com/cse110-fa22-group29/cse110-fa22-group29 into sprint-2 2022-11-20 14:17:12 -08:00
Arthur Lu
d284f0ddf2 change some npm scripts
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-20 14:17:10 -08:00
rheabhutada02
3db5f62a5c Merge branch 'sprint-2' of https://github.com/cse110-fa22-group29/cse110-fa22-group29 into sprint-2 2022-11-20 14:12:37 -08:00
rheabhutada02
4f2d88db9f Co-authored-by: Gavyn Ezell <ezellgavyn@gmail.com>
Co-authored-by: Kara Hoagland <KH-Cl@users.noreply.github.com>
2022-11-20 14:12:34 -08:00
Arthur Lu
c3944d476b fix lintHTML and lintCSS commands
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-20 14:12:26 -08:00
Arthur Lu
8a9a32414e Merge branch 'sprint-2' of https://github.com/cse110-fa22-group29/cse110-fa22-group29 into sprint-2 2022-11-20 14:07:02 -08:00
Arthur Lu
e73a544ab2 fix js linting
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-20 14:07:01 -08:00
rheabhutada02
ce6b8fcfa6 Merge pull request #78 from cse110-fa22-group29/sprint-2-homepage-integration
Sprint 2 homepage integration
2022-11-20 14:06:32 -08:00
rheabhutada02
db3e8dba8d Merge branch 'sprint-2' into sprint-2-homepage-integration 2022-11-20 14:06:14 -08:00
Marc
f2edc4dc6a added for loops for multiple tests 2022-11-20 14:01:48 -08:00
Marc
5d331c3800 added for loops to tests 2022-11-20 13:56:27 -08:00
Henry Feng
f340f3ed82 Added local img storage to updating 2022-11-20 13:51:28 -08:00
rheabhutada02
2a6dbc0503 Merge pull request #76 from cse110-fa22-group29/sprint-2-homepage-integration
Sprint 2 homepage integration
2022-11-20 13:48:29 -08:00
Arthur Lu
72e2f0fa03 comment appTestHelpers.js
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-20 13:43:42 -08:00
Arthur Lu
3b1b0cfd57 quick async fix
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-20 13:39:52 -08:00
Arthur Lu
e7d8eaea59 fix issue with tag checking,
modularize frequent app opperations in appTestHelpers.js,
fix isue with tage count checking

Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-20 13:39:21 -08:00
look-its-ashton
85d583e1b8 updating sprint2meeting3 2022-11-20 13:37:25 -08:00
look-its-ashton
bec66f1385 Sprint 2 Meeting 3 Meeting Notes 2022-11-20 13:18:00 -08:00
Arthur Lu
1c1ac64c58 change e2e tests to use default images
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-19 12:34:29 -08:00
Gavyn Ezell
5668e68594 first style integration
Co-authored-by: d7hernan <d7hernan@users.noreply.github.com>
Co-authored-by: look-its-ashton <look-its-ashton@users.noreply.github.com>
2022-11-19 12:29:50 -08:00
Arthur Lu
8338156cb8 fix delete test issue with alert handling
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-19 12:16:03 -08:00
Henry Feng
3e909ed381 Merge remote-tracking branch 'origin/sprint-2' into allow-for-user-uploaded-images 2022-11-19 12:10:55 -08:00
Arthur Lu
20e9842aea fix expected values for ratings and src tests
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-19 12:00:59 -08:00
Arthur Lu
7035fa46ee fixes to tag-add-btn,
fixes to tests with rating selection

Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-19 11:42:30 -08:00
Gavyn Ezell
23ae101f56 testing images
Co-authored-by: d7hernan <d7hernan@users.noreply.github.com>
2022-11-19 11:19:57 -08:00
rheabhutada02
1379c22f6f Merge pull request #73 from cse110-fa22-group29/add-crud-e2e-testing
Add crud e2e testing
2022-11-19 10:58:14 -08:00
rheabhutada02
78c07f27d3 Merge pull request #66 from cse110-fa22-group29/storage-revamp
Storage revamp
2022-11-19 10:51:59 -08:00
rheabhutada02
c5229c7bc1 Updated ReviewDetails.js 2022-11-19 10:45:28 -08:00
Arthur Lu
20afab9b1f remove create test review card reference
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-19 10:21:43 -08:00
Arthur Lu
2e95147336 Merge branch 'add-crud-e2e-testing' of https://github.com/cse110-fa22-group29/cse110-fa22-group29 into add-crud-e2e-testing 2022-11-18 23:26:54 -08:00
Arthur Lu
ef5dccfd1a temp fix issue with root user 2022-11-18 23:26:51 -08:00
Marc
d5be6a2e4d Check details & homepage for create & read 2022-11-18 23:08:54 -08:00
Arthur Lu
274a05fdc2 convert page.click() to button.click() 2022-11-18 20:43:55 -08:00
Arthur Lu
65815998e9 fix create new review star selection 2022-11-18 20:37:33 -08:00
Arthur Lu
cac2b0bf07 populate part of add review,
various bug fixes,
TODO: resolve issue with star selectors
2022-11-18 20:36:10 -08:00
Arthur Lu
82be561bfe add wait for page navigation to applicable tests 2022-11-18 19:21:53 -08:00
Arthur Lu
b75e4172b4 Merge pull request #72 from cse110-fa22-group29/storage-revamp
Pull CRUD implementation changes from revamp-storage to add-crud-e2e-testing
2022-11-18 19:12:22 -08:00
Arthur Lu
32323eaf83 Merge pull request #71 from cse110-fa22-group29/sprint-2
Reflect changes to sprint-2 to storage-revamp
2022-11-18 15:28:38 -08:00
Arthur Lu
f332b27168 Merge pull request #70 from cse110-fa22-group29/remove-unused-files
Reflect main changes to sprint-2
2022-11-18 15:17:43 -08:00
Arthur Lu
0a39039e9c Merge pull request #69 from cse110-fa22-group29/remove-unused-files
Remove unused files
2022-11-18 15:16:40 -08:00
Arthur Lu
baa722b55e remove unused files
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-18 15:15:20 -08:00
Arthur Lu
9cf7baf3e5 remove commented form from index
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-18 14:43:59 -08:00
Arthur Lu
f6a9fb7fc5 remove implied init from localStorage unit tests
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-18 14:08:19 -08:00
Arthur Lu
a91c9bc7ef Merge pull request #68 from cse110-fa22-group29/add-app-to-readme
Add link to app in README.md
2022-11-18 13:51:28 -08:00
Arthur Lu
5f84e700d1 update e2e test layout 2022-11-18 12:34:59 -08:00
Arthur Lu
46cee253f3 Merge branch 'main' into add-app-to-readme 2022-11-18 01:33:51 -08:00
Arthur Lu
ca89953d41 add link to app in README.md 2022-11-18 09:31:53 +00:00
Arthur Lu
425bc45453 fix unit test action stall issue 2022-11-18 09:23:54 +00:00
Arthur Lu
3422f584f9 fix linting in js 2022-11-18 07:56:07 +00:00
Arthur Lu
89b7319dd8 cleanup unused html and js code 2022-11-18 07:52:43 +00:00
Arthur Lu
5e83338668 update unit tests to match new localStorage implementations 2022-11-18 07:51:08 +00:00
Arthur Lu
6493fbd171 modularize localStorage calls into localStorage.js in preparation for unit testing 2022-11-18 07:13:53 +00:00
Henry Feng
416d26658d implementation of basic image local storage 2022-11-17 16:17:51 -08:00
Arthur Lu
6c00246e2d fix linting issues
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-17 15:33:12 -08:00
Arthur Lu
c45aec116b fix e2e test for create,
split create test into two parts,
split other test templates into two parts

Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-17 15:32:37 -08:00
Arthur Lu
1518fda766 add e2e tests for update and delete,
fix package.json commadns for lint and fix-style

Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-17 13:54:58 -08:00
look-its-ashton
e4755dd074 sprint 2 meeting one rough draft 2022-11-17 13:24:59 -08:00
Arthur Lu
c66f43f6e9 add empty crud e2e tests
Signed-off-by: Arthur Lu <learthurgo@gmail.com>
2022-11-17 12:32:38 -08:00
look-its-ashton
02f493e33b sprint 2 meeting one rough draft 2022-11-17 11:53:51 -08:00
rheabhutada02
ad723543e8 Merge pull request #58 from cse110-fa22-group29/updated-documentation
Added ADR for HTMLhint and Stylelint
2022-11-16 17:14:30 -08:00
rheabhutada02
56dceb5edb Rename checkin6.md to 111622-checkin6.md 2022-11-16 15:55:18 -08:00
rheabhutada02
41905a219b updated checkin6.md 2022-11-16 15:54:50 -08:00
rheabhutada02
467828d388 Rename 11822-sprint1day2.md to 110822-sprint1day2.md 2022-11-16 15:48:10 -08:00
Graydogminer
81ada40ca3 Create 111422-csslinting-stylelint.md 2022-11-14 01:05:58 -08:00
Graydogminer
cc6df228ed Create 111422-htmllinting-htmlhint.md 2022-11-14 00:48:27 -08:00
Graydogminer
1d453bdd49 Update phase1.md 2022-11-13 14:45:42 -08:00
108 changed files with 4371 additions and 2229 deletions

View File

@@ -1,33 +1,20 @@
{
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": "eslint:recommended",
"overrides": [
],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"rules": {
"indent": [
"error",
"tab"
],
"linebreak-style": [
"error",
"unix"
],
"quotes": [
"error",
"double"
],
"semi": [
"error",
"always"
],
"no-global-assign": 0
}
"env": {
"browser": true,
"es2021": true,
"node": true
},
"extends": "eslint:recommended",
"overrides": [],
"parserOptions": {
"ecmaVersion": "latest",
"sourceType": "module"
},
"rules": {
"indent": ["error", "tab"],
"linebreak-style": ["error", "unix"],
"quotes": ["error", "double"],
"semi": ["error", "always"],
"no-global-assign": 0
}
}

View File

@@ -1,23 +1,23 @@
name: CSS Linting
on:
pull_request:
branches:
- main
pull_request:
branches:
- main
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
# Single deploy job since we're just deploying
test:
runs-on: ubuntu-latest
steps:
- name: Install apt updates
run: sudo apt -y update; sudo apt -y upgrade;
- name: Checkout
uses: actions/checkout@v3
- name: Install dependencies
run: sudo npm install
- name: Run tests
run: sudo npm run lintCSS
# Single deploy job since we're just deploying
test:
runs-on: ubuntu-latest
steps:
- name: Install apt updates
run: sudo apt -y update; sudo apt -y upgrade;
- name: Checkout
uses: actions/checkout@v3
- name: Install dependencies
run: sudo npm install
- name: Run tests
run: sudo npm run lint-css

View File

@@ -2,42 +2,52 @@
name: Deploy GitHub Pages
on:
# Runs on pushes targeting the default branch
push:
branches:
- main
# Runs on pushes targeting the default branch
push:
branches:
- main
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
contents: read
pages: write
id-token: write
contents: read
pages: write
id-token: write
# Allow one concurrent deployment
concurrency:
group: "pages"
cancel-in-progress: true
group: "pages"
cancel-in-progress: true
jobs:
# Single deploy job since we're just deploying
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
- name: Setup Pages
uses: actions/configure-pages@v2
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
with:
# Upload only the src repository
path: './source/'
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1
# Single deploy job since we're just deploying
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- name: Install apt updates
run: sudo apt -y update; sudo apt -y upgrade;
- name: Install prerequisites
uses: actions/setup-node@v3
with:
node-version: 18
- name: Checkout
uses: actions/checkout@v3
- name: Install dependencies
run: sudo npm install -g jsdoc
- name: Run js-doc
run: sudo npm run js-doc
- name: Setup Pages
uses: actions/configure-pages@v2
- name: Upload artifact
uses: actions/upload-pages-artifact@v1
with:
# Upload only the src repository
path: "./source/"
- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v1

View File

@@ -1,23 +1,23 @@
name: HTML Linting
on:
pull_request:
branches:
- main
pull_request:
branches:
- main
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
# Single deploy job since we're just deploying
test:
runs-on: ubuntu-latest
steps:
- name: Install apt updates
run: sudo apt -y update; sudo apt -y upgrade;
- name: Checkout
uses: actions/checkout@v3
- name: Install dependencies
run: sudo npm install
- name: Run tests
run: sudo npm run lintHTML
# Single deploy job since we're just deploying
test:
runs-on: ubuntu-latest
steps:
- name: Install apt updates
run: sudo apt -y update; sudo apt -y upgrade;
- name: Checkout
uses: actions/checkout@v3
- name: Install dependencies
run: sudo npm install
- name: Run tests
run: sudo npm run lint-html

View File

@@ -1,25 +1,25 @@
name: JS Linting
on:
pull_request:
branches:
- main
pull_request:
branches:
- main
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
# Single deploy job since we're just deploying
test:
runs-on: ubuntu-latest
steps:
- name: Install apt updates
run: sudo apt -y update; sudo apt -y upgrade;
- name: Install prerequisites
run: sudo apt install -y nodejs npm;
- name: Checkout
uses: actions/checkout@v3
- name: Install dependencies
run: sudo npm install
- name: Run tests
run: sudo npm run lint
# Single deploy job since we're just deploying
test:
runs-on: ubuntu-latest
steps:
- name: Install apt updates
run: sudo apt -y update; sudo apt -y upgrade;
- name: Install prerequisites
run: sudo apt install -y nodejs npm;
- name: Checkout
uses: actions/checkout@v3
- name: Install dependencies
run: sudo npm install
- name: Run tests
run: sudo npm run lint-js

View File

@@ -1,29 +1,29 @@
name: JS Unit Test
on:
pull_request:
branches:
- main
pull_request:
branches:
- main
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
# Single deploy job since we're just deploying
test:
runs-on: ubuntu-latest
steps:
- name: Install apt updates
run: sudo apt -y update; sudo apt -y upgrade;
- name: Install prerequisites
uses: actions/setup-node@v3
with:
node-version: 18
- name: Checkout
uses: actions/checkout@v3
- name: Install dependencies
run: sudo npm install
- name: Start local http server
run: sudo npm run http-server
- name: Run tests
run: sudo npm test
# Single deploy job since we're just deploying
test:
runs-on: ubuntu-latest
steps:
- name: Install apt updates
run: sudo apt -y update; sudo apt -y upgrade;
- name: Install prerequisites
uses: actions/setup-node@v3
with:
node-version: 18
- name: Checkout
uses: actions/checkout@v3
- name: Install dependencies
run: npm install
- name: Start local http server
run: npm run http-server &
- name: Run tests with coverage
run: npm run coverage

27
.github/workflows/prettier-linting.yml vendored Normal file
View File

@@ -0,0 +1,27 @@
name: Prettier
on:
pull_request:
branches:
- main
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
jobs:
# Single deploy job since we're just deploying
test:
runs-on: ubuntu-latest
steps:
- name: Install apt updates
run: sudo apt -y update; sudo apt -y upgrade;
- name: Install prerequisites
uses: actions/setup-node@v3
with:
node-version: 18
- name: Checkout
uses: actions/checkout@v3
- name: Install dependencies
run: sudo npm install
- name: Run tests
run: sudo npm run lint-prettier

3
.gitignore vendored
View File

@@ -1,3 +1,6 @@
**/.devcontainer/*
**/node_modules/*
**/package-lock.json
**/.vscode/*
**/.nyc_output/*
**/coverage/*

View File

@@ -1,3 +1,4 @@
{
"attr-value-not-empty": false
"attr-value-not-empty": false,
"space-tab-mixed-disabled": "tab"
}

5
.prettierrc.json Normal file
View File

@@ -0,0 +1,5 @@
{
"printWidth": 160,
"tabWidth": 4,
"useTabs": true
}

View File

@@ -1,3 +1,7 @@
{
"extends": "stylelint-config-standard"
"extends": "stylelint-config-standard",
"ignore": ["inside-parens", "param", "value"],
"rules": {
"indentation": "tab"
}
}

View File

@@ -1,2 +1,14 @@
# cse110-fa22-group29
# My Meal Journal
My Meal Journal is a local-first journaling application on the web designed for recording your standout meal experiences. The app utilizes local storage in the browser to store invidual journal entries with support for tagging, filtering, image posting, and more!<br>
The site is completely static with no front-end or back-end libraries employed. As such cross browser support is relatively strong and site performance is very reliable.
Access the Site Here:<br>
[My Meal Journal](https://cse110-fa22-group29.github.io/cse110-fa22-group29/)
Meet the Team:<br>
[Team Page Link](https://github.com/cse110-fa22-group29/cse110-fa22-group29/blob/main/admin/team.md)
If you enjoyed the site or have suggestion for how we can improve it don't hesitate to reach out to the developers!<br>
Crafted with ❤️ and care by students of the University of California San Diego.

View File

@@ -8,11 +8,11 @@ Rather than create one large pipeline with many steps which increases complexity
We've identified 5 major features which we definitely want to implement in the CI/CD pipeline.
- Deployment
- Unit Testing
- Linting
- End To End Validation
- Manual Validation
- Deployment
- Unit Testing
- Linting
- End To End Validation
- Manual Validation
We created this diagram to demonstrate our strategy of multiple simple pipelines.
@@ -22,15 +22,18 @@ We created this diagram to demonstrate our strategy of multiple simple pipelines
So far the features listed below have been completed to some degree:
- Deployment
- Implemented: action triggered on any push to main, uses the github pages action to publish the app
- ToDo: Add minifications ste between trigger and github pages action
- Unit Testing
- Implemented: action triggers on any PR, uses mocha to perform unit testing on core components
- ToDo: trigger workflow only on certain PRs which relate to JS code
- Linting (JS)
- Implemented: ction triggers on any PR, uses eslint to perform style enforcement on all JS components
- ToDo: trigger workflow only on certain PRs which relate to JS code
- Deployment
- Implemented: action triggered on any push to main, uses the github pages action to publish the app
- ToDo: Add minifications ste between trigger and github pages action
- Unit Testing
- Implemented: action triggers on any PR, uses mocha to perform unit testing on core components
- ToDo: trigger workflow only on certain PRs which relate to JS code
- Linting (JS)
- Implemented: ction triggers on any PR, uses eslint to perform style enforcement on all JS components
- ToDo: trigger workflow only on certain PRs which relate to JS code
- Linting (HTML)
- Implemented: action triggers on any PR, uses HTMLhint to perform style enforcement on all HTML components
- Linting (CSS)
- Implemented: action triggers on any PR, uses Stylelint to perform style enforcement on all CSS components
## Planned Features and Timeline

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 KiB

View File

@@ -0,0 +1,48 @@
# CI/CD Phase 2
## Overall Pipeline Architecture
Rather than create one large pipeline with many steps which increases complexity, we decided to create many small independent pipelines which work in parallel to conduct code quality checking. Using this strategy, if any one pipeline has issues, we can still continue development without delay, and the quality of code is likely to remain high.
## Overview of Pipeline Features
We've identified 5 major features which we definitely want to implement in the CI/CD pipeline.
- Deployment
- Unit Testing
- Linting
- End To End Validation
- Manual Validation
We also identified some features which are nice to have:
- Automatic documentation publishing
- Minification
- HTML Validation and accessibility scoring
We created this diagram to demonstrate our strategy of multiple simple pipelines.
![Pipeline Diagram](phase2.drawio.png)
## Finished Features and Implementation
So far the features listed below have been completed to some degree:
- Deployment
- Implemented: action triggered on any push to main, uses the github pages action to publish the app
- Implemented: uses JSDoc to generate documentation on the same site at [docs](https://cse110-fa22-group29.github.io/cse110-fa22-group29/docs/)
- ToDo: Add minification step between trigger and github pages action
- Unit Testing
- Implemented: action triggers on PR to main, uses mocha to perform unit testing on core components
- End to end testing
- Implemented: action triggers on PR to main, uses mocha and puppeteer to perform end to end testing
- Linting (JS)
- Implemented: action triggers on PR to main, uses eslint to perform style enforcement on all JS components
- Linting (HTML)
- Implemented: action triggers on PR to main, uses HTMLhint to perform style enforcement on all HTML components
- Linting (CSS)
- Implemented: action triggers on PR to main, uses Stylelint to perform style enforcement on all CSS components
- Linting (general)
- Implemented: action triggers on PR to main, uses Prettier to perform style checking on all file types
## Planned Features and Timeline

BIN
admin/cipipeline/phase2.mp4 Normal file

Binary file not shown.

View File

@@ -1,8 +1,13 @@
# Meeting Minutes (10/12/2022)
## Team 29: Hackers1995
## Meeting Topic: Kickoff Meeting
This meeting is being held to kickoff the start of many meetings to come during the quarter.
## Attendance
1. Rhea Bhutada
2. George Dubinin
3. Gavyn Ezell
@@ -14,34 +19,36 @@ This meeting is being held to kickoff the start of many meetings to come during
9. Daniel Hernandez
## Absentees
1. Arthur Lu
## Meeting Details
- When: 10/12/2022 at 3:30PM
- Where: Zoom
- When: 10/12/2022 at 3:30PM
- Where: Zoom
## Agenda:
- ### Old/Unresolved Business
- N/A
- ### New Business
- go over github organization
- review assignments
- go through rules
- start branding/team name
- ### Next Meeting's Business
- figure out roles
- decide weekly meeting times
- figure out team bonding events
- brainstorm CRUD applications
- complete any remaining assignments
- ### Old/Unresolved Business
- N/A
- ### New Business
- go over github organization
- review assignments
- go through rules
- start branding/team name
- ### Next Meeting's Business
- figure out roles
- decide weekly meeting times
- figure out team bonding events
- brainstorm CRUD applications
- complete any remaining assignments
## Decisions Made
- went over github organizations and reviewed the assignments
- went through the rules and agreed on the contract
- figured out the brand name
- went over github organizations and reviewed the assignments
- went through the rules and agreed on the contract
- figured out the brand name
## End Time
- 10/12/2022 at 4:30PM
- 10/12/2022 at 4:30PM

View File

@@ -1,8 +1,13 @@
# Meeting Minutes (10/12/2022)
## Team 29: Hackers1995
## Meeting Topic: Weekly Check-In Meeting
This meeting is the first weekly meeting with TA
## Attendance
1. Gagan Gopalaiah
2. Rhea Bhutada
3. Kara Hoagland
@@ -10,23 +15,27 @@ This meeting is the first weekly meeting with TA
5. Arthur
## Meeting Details
- When: 10/12/2022 at 8:00PM
- Where: Zoom
- When: 10/12/2022 at 8:00PM
- Where: Zoom
## Agenda:
- ### Reviewed Project Details
- building CRUD app
- utilizing HTML, CSS, JavaScript
- general domain is better than specific domain
- ### Get Started early
- brainstorm CRUD apps
- review assignments
- figure out unit test code
- familiarize yourself with GitHub Actions
- ### Reviewed Project Details
- building CRUD app
- utilizing HTML, CSS, JavaScript
- general domain is better than specific domain
- ### Get Started early
- brainstorm CRUD apps
- review assignments
- figure out unit test code
- familiarize yourself with GitHub Actions
## Important Information
- Gagan OH (6:30PM-7:30PM on Wednesday) in CSE Basement
- Reserved the room if any of us want to meet there. TA not going to present unless required.
- Gagan OH (6:30PM-7:30PM on Wednesday) in CSE Basement
- Reserved the room if any of us want to meet there. TA not going to present unless required.
## End Time
- 10/12/2022 at 8:30PM
- 10/12/2022 at 8:30PM

View File

@@ -1,9 +1,13 @@
# Meeting Minutes (10/19/2022)
## Team 29: Hackers1995
## Meeting Topic: Weekly Check-In Meeting
This meeting is the second weekly meeting with TA.
## Attendance
1. Gagan Gopalaiah
2. Rhea Bhutada
3. George Dubinin
@@ -14,37 +18,45 @@ This meeting is the second weekly meeting with TA.
8. Isaac Otero
## Meeting Details
- When: 10/19/2022 at 8:00PM
- Where: Zoom
- When: 10/19/2022 at 8:00PM
- Where: Zoom
## Agenda:
- ### Recap of last week
- went over assignments
- discussed feelings on the midterm
- ### New Potential Meeting Time
- without TA unless necessary
- before lecture on Monday in CSE Basement
- ### Recap of last week
- ### Upcoming Assignments
- two coming up
- brainstorm activity (due 10/23)
- continue brainstorming throughout the week
- due sunday
- pitch (11/1)
- initial draft by 10/25 - 10/26
- went over assignments
- discussed feelings on the midterm
- ### Tips on Designing
- user center design
- define the problem first, then the tools/techniques
- finalize on the product and its features, then decide on how to build it
- ### New Potential Meeting Time
- ### Standup
- not expected everyday
- once every two days is ideal
- doesn't have to be too descriptive
- without TA unless necessary
- before lecture on Monday in CSE Basement
- ### Review of Recent Brainstorming Session
- ### Upcoming Assignments
- two coming up
- brainstorm activity (due 10/23)
- continue brainstorming throughout the week
- due sunday
- pitch (11/1)
- initial draft by 10/25 - 10/26
- ### Tips on Designing
- user center design
- define the problem first, then the tools/techniques
- finalize on the product and its features, then decide on how to build it
- ### Standup
- not expected everyday
- once every two days is ideal
- doesn't have to be too descriptive
- ### Review of Recent Brainstorming Session
## End Time
- 10/19/2022 at 3:50PM
- 10/19/2022 at 3:50PM

View File

@@ -1,8 +1,13 @@
# Meeting Minutes (10/21/2022)
## Team 29: Hackers1995
## Meeting Topic: Application Brainstorming
This meeting is held to help the group decide on what application. We will also discuss preliminary designs.
## Attendance
1. George Dubinin
2. Gavyn Ezell
3. Henry Feng
@@ -15,30 +20,35 @@ This meeting is held to help the group decide on what application. We will also
10. Daniel Hernandez
## Absentees
N/A
## Meeting Details
- When:
- 10/21/2022 at 10:00AM
- 10/21/2022 at 1:30PM
- Where: Zoom
- When:
- 10/21/2022 at 10:00AM
- 10/21/2022 at 1:30PM
- Where: Zoom
## Agenda:
- ### Old/Unresolved Business
- N/A
- ### New Business
- List ideas that have been shared so far
- List new ideas/ideas that haven't been recorded on the doc yet
- Discuss, vote, and decide on one idea
- ### Next Meeting's Business
- Discuss design features for the chosen app
- ### Old/Unresolved Business
- N/A
- ### New Business
- List ideas that have been shared so far
- List new ideas/ideas that haven't been recorded on the doc yet
- Discuss, vote, and decide on one idea
- ### Next Meeting's Business
- Discuss design features for the chosen app
## Decisions Made
- Added UCSD Food Reviewer App idea to the brainstorming doc
- The 10AM group cast 3 votes for the Social Media Auxilary and 1 vote for the UCSD Food Reviewer App (one participant voted twice)
- The 1:30PM group cast 7 votes for the UCSD Food Reviewer App and 5 votes for the Copy/Paste App
- We will move forward with the UCSD Food Reviewer App
- Added UCSD Food Reviewer App idea to the brainstorming doc
- The 10AM group cast 3 votes for the Social Media Auxilary and 1 vote for the UCSD Food Reviewer App (one participant voted twice)
- The 1:30PM group cast 7 votes for the UCSD Food Reviewer App and 5 votes for the Copy/Paste App
- We will move forward with the UCSD Food Reviewer App
## End Time
- 10/21/2022 at 11:00AM
- 10/21/2022 at 2:30PM
- 10/21/2022 at 11:00AM
- 10/21/2022 at 2:30PM

View File

@@ -1,8 +1,13 @@
# Meeting Minutes (10/23/2022)
## Team 29: Hackers1995
## Meeting Topic: Application Final Decision
This meeting is held to help the group decide on which kind of app to build.
## Attendance
1. George Dubinin
2. Henry Feng
3. Arthur Lu
@@ -12,29 +17,34 @@ This meeting is held to help the group decide on which kind of app to build.
7. Isaac Otero
## Absentees
1. Sanjit Joseph
2. Gavyn Ezell
3. Daniel Hernandez
## Meeting Details
- When:
- 10/23/2022 at 1:00PM
- Where: Zoom (Rhea's Meeting Room)
- When:
- 10/23/2022 at 1:00PM
- Where: Zoom (Rhea's Meeting Room)
## Agenda:
- ### Old/Unresolved Business
- N/A
- ### New Business
- Decide on a final app idea
- ### Next Meeting's Business
- Discuss design features for the chosen app
- ### Old/Unresolved Business
- N/A
- ### New Business
- Decide on a final app idea
- ### Next Meeting's Business
- Discuss design features for the chosen app
## Decisions Made
- Maybe for the food reviewer app. Presenting possible writeup to Gagan
- Maybe for the resume builder. Presenting possible writeup to Gagan https://docs.google.com/document/d/1zdvVxd47Ivdz-D0rZGNJqc3D9GiQj0n_xMJKapOV39A/edit?usp=sharing
- Maybe for Social Media Local Archive. Presenting possible writeup to Gagan https://docs.google.com/document/d/1upNr6lneB2uzCoQ12_aa1CMg1W8p2NBFb6xmP7i4-z4/edit?usp=sharing
- No to the copy/paste app (not local first)
- Maybe for the food reviewer app. Presenting possible writeup to Gagan
- Maybe for the resume builder. Presenting possible writeup to Gagan https://docs.google.com/document/d/1zdvVxd47Ivdz-D0rZGNJqc3D9GiQj0n_xMJKapOV39A/edit?usp=sharing
- Maybe for Social Media Local Archive. Presenting possible writeup to Gagan https://docs.google.com/document/d/1upNr6lneB2uzCoQ12_aa1CMg1W8p2NBFb6xmP7i4-z4/edit?usp=sharing
- No to the copy/paste app (not local first)
## End Time
- When:
- 10/23/2022 at 2:00PM
- When:
- 10/23/2022 at 2:00PM

View File

@@ -1,10 +1,15 @@
# Meeting Minutes (10/26/2022)
## Team 29: Hackers1995
## Meeting Topic: Weekly Check-In Meeting
This is our third weekly meeting with Gagan.
## Attendance
TA. Gagan Gopalaiah
1. Rhea Bhutada
2. George Dubinin
3. Sanjit Joseph
@@ -12,33 +17,38 @@ TA. Gagan Gopalaiah
5. Gavyn Ezell
## Meeting Details
- When: 10/26/2022 at 3:00 PM
- Where: Zoom (Gagan's Zoom room: https://ucsd.zoom.us/j/5177090642)
- When: 10/26/2022 at 3:00 PM
- Where: Zoom (Gagan's Zoom room: https://ucsd.zoom.us/j/5177090642)
## Agenda:
- ### Present our ideas to Gagan
- All ideas seem to be doable
- Consider a few tweaks to "CRUDify" apps
- Gagan is partial to food review app idea, but any of them can work
- ### Present our ideas to Gagan
- ### Tips for projects
- SOCIAL MEDIA ORGANIZER: avoid API integration if possible/only make it a small part, not a main feature
- RESUME BUILDER: try to "CRUDify" it more if we're going for this
- All ideas seem to be doable
- Consider a few tweaks to "CRUDify" apps
- Gagan is partial to food review app idea, but any of them can work
- ### Standups
- Once per 2 days, 3 in worst case
- Perhaps make a separate slack channel for these to avoid clutter
- ### Tips for projects
- SOCIAL MEDIA ORGANIZER: avoid API integration if possible/only make it a small part, not a main feature
- RESUME BUILDER: try to "CRUDify" it more if we're going for this
- ### Standups
- Once per 2 days, 3 in worst case
- Perhaps make a separate slack channel for these to avoid clutter
## Moving forward:
- ### BY FRIDAY:
- Try and meet tomorrow (10/27) to make a final decision
- Let Gagan know what we've decided on
- Complete project pitch assignment - need to present to Gagan tomorrow 10/27, due on canvas 11/1
- ### OVER WEEKEND:
- (If possible) Start on CI/CD pipeline (basic js app/unit tests, use Github actions to set up)
- ### BY FRIDAY:
- Try and meet tomorrow (10/27) to make a final decision
- Let Gagan know what we've decided on
- Complete project pitch assignment - need to present to Gagan tomorrow 10/27, due on canvas 11/1
- ### OVER WEEKEND:
- (If possible) Start on CI/CD pipeline (basic js app/unit tests, use Github actions to set up)
## End Time
- 10/26/2022 at 4:00 PM
- 10/26/2022 at 4:00 PM

View File

@@ -1,9 +1,13 @@
# Meeting Minutes (10/27/2022)
## Team 29: Hackers1995
## Meeting Topic: Final Project Decision
We're figuring out what project we're going to do, and figure out what we need for the starting pitch.
## Attendance
1. Rhea Bhutada
2. Sanjit Joseph
3. Arthur Lu
@@ -15,46 +19,51 @@ We're figuring out what project we're going to do, and figure out what we need f
9. Isaac Otero
## Meeting Details
- When: 10/27/2022 at 5:00 PM
- Where: Zoom (Rhea's Zoom room: https://ucsd.zoom.us/j/8054288343)
- When: 10/27/2022 at 5:00 PM
- Where: Zoom (Rhea's Zoom room: https://ucsd.zoom.us/j/8054288343)
## Agenda:
- ### Decide which project we're doing
- Gagan seemed to like the food review app idea best in their current states
- We all seem to agree that the food review app is acceptable
- Made a couple clarifications, no major changes or objections to the app
- ### Start project pitch
- Created google slides: **https://docs.google.com/presentation/d/1_XWihJGVChFtYS38RnYJtQUuFKsgvewOCOkdeMHFRg4/edit?usp=sharing**
- Prof recommends skimming the book: **https://basecamp.com/shapeup** (esp. ch.5 on risks and rabbit holes)
- Finishing Risks + Rabbit holes here in the meeting
- Kara posted a design prototype in Slack: https://cse110fall2022.slack.com/archives/C04598WA7P1/p1666918573779859
- ### Decide which project we're doing
- ### App Description
- Renaming it to a "Food Diary" app, not limited to UCSD
- Allows users to store info about recent foods, restaurant name, location, price, your rating etc.
- Probably provides food suggestions based on where you've eaten (and liked) before
- We're not going to try anything with external data atm.
- Gagan seemed to like the food review app idea best in their current states
- We all seem to agree that the food review app is acceptable
- Made a couple clarifications, no major changes or objections to the app
- ### Start project pitch
- Created google slides: **https://docs.google.com/presentation/d/1_XWihJGVChFtYS38RnYJtQUuFKsgvewOCOkdeMHFRg4/edit?usp=sharing**
- Prof recommends skimming the book: **https://basecamp.com/shapeup** (esp. ch.5 on risks and rabbit holes)
- Finishing Risks + Rabbit holes here in the meeting
- Kara posted a design prototype in Slack: https://cse110fall2022.slack.com/archives/C04598WA7P1/p1666918573779859
- ### App Description
- Renaming it to a "Food Diary" app, not limited to UCSD
- Allows users to store info about recent foods, restaurant name, location, price, your rating etc.
- Probably provides food suggestions based on where you've eaten (and liked) before
- We're not going to try anything with external data atm.
## Moving forward:
- ### BY TOMORROW:
- FINISH PITCH SLIDES
- MUST CHANGE DIAGRAM TO ALL RESTAURANTS (Isaac will change this)
- Daniel will update the pitch slides by adding images/graphics.
- Daniel + Sanjit are doing visual representation.
- Gayvn is doing potential competitors
- Henry, Sanjit, Kara are doing user personas
- Rhea is doing statement + purpose
- Arthur + Marc are doing "why it's a CRUD app"
- See if we can have a short meeting tomorrow before meeting Gagan just to review our pitch.
- Put all components in specs folder before pitch
- Meet at 2:30? Meeting with Gagan is probably at 3:30
- ### BY TOMORROW:
- ### LATER:
- Have some people split off and work on the basic UI design. Technically Sanjit had the 'art role' according to the TA but not sure what that entails. More ppl would def be helpful. TBD who else is helping
- FINISH PITCH SLIDES
- MUST CHANGE DIAGRAM TO ALL RESTAURANTS (Isaac will change this)
- Daniel will update the pitch slides by adding images/graphics.
- Daniel + Sanjit are doing visual representation.
- Gayvn is doing potential competitors
- Henry, Sanjit, Kara are doing user personas
- Rhea is doing statement + purpose
- Arthur + Marc are doing "why it's a CRUD app"
- See if we can have a short meeting tomorrow before meeting Gagan just to review our pitch.
- Put all components in specs folder before pitch
- Meet at 2:30? Meeting with Gagan is probably at 3:30
- ### LATER:
- Have some people split off and work on the basic UI design. Technically Sanjit had the 'art role' according to the TA but not sure what that entails. More ppl would def be helpful. TBD who else is helping
## End Time
- 10/27/2022 at 6:15 PM
- 10/27/2022 at 6:15 PM

View File

@@ -1,24 +1,31 @@
# Meeting Minutes (10/28/2022)
## Team 29: Hackers1995
## Meeting Topic: Project Pitch
We finished up the project pitch docs and presenting them to Gagan.
Google slides: **https://docs.google.com/presentation/d/1_XWihJGVChFtYS38RnYJtQUuFKsgvewOCOkdeMHFRg4/edit?usp=sharing**
## Meeting Details
- When: 10/28/2022 at 2:30 PM
- Where: Zoom (Rhea's Zoom room: https://ucsd.zoom.us/j/8054288343)
- When: 10/28/2022 at 2:30 PM
- Where: Zoom (Rhea's Zoom room: https://ucsd.zoom.us/j/8054288343)
## Agenda:
- ### Finish Project Pitch documents
- Finished user stories/diagrams and uploaded to github
- Went over presentation before showing TA
- Presented project to Gagan
- **Overall reaction - he liked our app! More feedback to come, but we can feel free to start some basic work.**
- ### Finish Project Pitch documents
- Finished user stories/diagrams and uploaded to github
- Went over presentation before showing TA
- Presented project to Gagan
- **Overall reaction - he liked our app! More feedback to come, but we can feel free to start some basic work.**
## Moving forward:
- I think we need to upload our project pitch to canvas by 11/1
- Start on the really basic stuff as discussed in lecture (hello world for CI/CD setup, etc)
- I think we need to upload our project pitch to canvas by 11/1
- Start on the really basic stuff as discussed in lecture (hello world for CI/CD setup, etc)
## End Time
- 10/28/2022 at 4:00 PM
- 10/28/2022 at 4:00 PM

View File

@@ -1,41 +1,50 @@
# Meeting Minutes (11/01/2022)
## Team 29: Hackers1995
## Meeting Topic: Work going forward
We're trying to figure out what our goals are for the project and how to get started.
## Meeting Details
- When: 11/01/2022 at 7:00 PM
- Where: Zoom (Rhea's Zoom room: https://ucsd.zoom.us/j/8054288343)
- When: 11/01/2022 at 7:00 PM
- Where: Zoom (Rhea's Zoom room: https://ucsd.zoom.us/j/8054288343)
## Attendance
1. Rhea
2. Gavyn
3. Isaac
4. Kara
5. Marc
6. Henry
7. Daniel
8. Sanjit
1. Rhea
2. Gavyn
3. Isaac
4. Kara
5. Marc
6. Henry
7. Daniel
8. Sanjit
## Notes:
- Gagan suggests we have a feature backlog and pull stuff from that
- Using Github Issues for our feature backlog
- Perhaps integrate TTS from Lab5 into something (pick a random restaurant while driving, etc)
- Gagan suggests we have a feature backlog and pull stuff from that
- Using Github Issues for our feature backlog
- Created figma sketch for app design, uploaded to github and google slides
- Perhaps integrate TTS from Lab5 into something (pick a random restaurant while driving, etc)
- Created figma sketch for app design, uploaded to github and google slides
## Moving forward:
- ### BY TONIGHT:
- We'll submit our pitch files
- ### LATER:
- Sanjit will upload a basic hello world program in order to test deployment/github actions
- Arthur will start figuring out how to configure github actions
- ### PREFERENCES:
- BACKEND: Henry, Gavyn, Kara
- FRONTEND: Isaac
- NO PREFERENCE: Daniel, Marc, Rhea, Sanjit
- ### BY TONIGHT:
- We'll submit our pitch files
- ### LATER:
- Sanjit will upload a basic hello world program in order to test deployment/github actions
- Arthur will start figuring out how to configure github actions
- ### PREFERENCES:
- BACKEND: Henry, Gavyn, Kara
- FRONTEND: Isaac
- NO PREFERENCE: Daniel, Marc, Rhea, Sanjit
## End Time
- 11/01/2022 at 9:00 PM
- 11/01/2022 at 9:00 PM

View File

@@ -1,34 +1,39 @@
# Meeting Minutes (11/02/2022)
## Team 29: Hackers1995
## Meeting Topic: Weekly TA Catchup with Gagan
We are meeting with Gagan to discuss early phase design concepts and decisions we need to think about as we start the early coding phase.
## Attendance
1. Rhea Bhutada
2. George Dubinin
3. Gagan Gopalaiah
## Meeting Details
- When: 11/02/2022 at 3:30PM
- Where: Zoom
- When: 11/02/2022 at 3:30PM
- Where: Zoom
## Agenda:
## Discussion Points by Gagan
- Now that we finished designs stage there are 2 approaches
- The first is to just start coding without thinking about design (cowboy coding). It works but can get bumpy down the road
- The second is to look at the project from a birds eye view and break it down into milestones and tasks. First break it down into weeks and then decide on what to do each day of the week. This will make it easier to keep things organized.
- Jira and GitHub issues will be super helpful. Jira is a more expensive option so instead prof recommends creating issues.
- Start thinking about storage options. Think local first and decide on options like:
- locally stored json files
- browser local storage
- "real" database like IndexDB
- Think about different models to keep track of changes and versions. Consider the branching model (one central repository and everyone has a branch or one breanch per feature) and the forking model (the central repository is copied and developers work in these copies and push changes to their own copies before syncing to the central repo). Useful info here: https://www.flagship.io/git-branching-strategies/
- Think about how pull requests will be approved and create a system for PR review and suggests.
- Break down the project and decide on which tasks to be completed. Then decide on how long sprints will last and how tasks will be assigned.
- We need to create the ADR and place it in the brainstorming section of the repo. This will contain details about specific project decisions that we made like database decisions (for example).
- Now that we finished designs stage there are 2 approaches
- The first is to just start coding without thinking about design (cowboy coding). It works but can get bumpy down the road
- The second is to look at the project from a birds eye view and break it down into milestones and tasks. First break it down into weeks and then decide on what to do each day of the week. This will make it easier to keep things organized.
- Jira and GitHub issues will be super helpful. Jira is a more expensive option so instead prof recommends creating issues.
- Start thinking about storage options. Think local first and decide on options like:
- locally stored json files
- browser local storage
- "real" database like IndexDB
- Think about different models to keep track of changes and versions. Consider the branching model (one central repository and everyone has a branch or one breanch per feature) and the forking model (the central repository is copied and developers work in these copies and push changes to their own copies before syncing to the central repo). Useful info here: https://www.flagship.io/git-branching-strategies/
- Think about how pull requests will be approved and create a system for PR review and suggests.
- Break down the project and decide on which tasks to be completed. Then decide on how long sprints will last and how tasks will be assigned.
- We need to create the ADR and place it in the brainstorming section of the repo. This will contain details about specific project decisions that we made like database decisions (for example).
## End Time
- 11/02/2022 at 4:00PM
- 11/02/2022 at 4:00PM

View File

@@ -1,9 +1,13 @@
# Meeting Minutes (11/03/2022)
## Team 29: Hackers1995
## Meeting Topic: Technologies Discussion
We're deciding on what web technologies we will incorporate into our food blog application.
## Attendance
1. Rhea Bhutada
2. Sanjit Joseph
3. Arthur Lu
@@ -15,30 +19,30 @@ We're deciding on what web technologies we will incorporate into our food blog a
9. Isaac Otero
## Meeting Details
- When: 11/03/2022 at 3:00PM
- Where: In-person (CSE Basement B250) and George's Zoom room
- When: 11/03/2022 at 3:00PM
- Where: In-person (CSE Basement B250) and George's Zoom room
## Agenda:
- ### Answer the questions that Gagan's asked the team leads yesterday
- What high level approach will we have to coding?
- Slow approach with diagrams and short sprints of around 3 days. Biweekly meetings where we catch up with what happened end of each sprint.
- What issue tracker will we use?
- Use GitHub issues for tracking. Assign and breakdown tasks at the begining of each sprint.
- What database will we use?
- Rely on localStorage short-term and implement a non-relational database like MongoDB later.
- What branching/forking strategy will we use
- We will be creating branches for different features and be submitting PRs direclty to the master branch. Forks will only be created for large overhaul type changes
- How will PRs be approved
- The team will be split up into groups for different aspects of the app (front end, ui, database for example) and PRs will be reviewed and approved by 1 other member of the respective group
- Introduce the ADR and discuss how we will create it
-
- ### Answer the questions that Gagan's asked the team leads yesterday
- What high level approach will we have to coding?
- Slow approach with diagrams and short sprints of around 3 days. Biweekly meetings where we catch up with what happened end of each sprint.
- What issue tracker will we use?
- Use GitHub issues for tracking. Assign and breakdown tasks at the begining of each sprint.
- What database will we use?
- Rely on localStorage short-term and implement a non-relational database like MongoDB later.
- What branching/forking strategy will we use
- We will be creating branches for different features and be submitting PRs direclty to the master branch. Forks will only be created for large overhaul type changes
- How will PRs be approved
- The team will be split up into groups for different aspects of the app (front end, ui, database for example) and PRs will be reviewed and approved by 1 other member of the respective group
- ## Introduce the ADR and discuss how we will create it
## Assignments:
- ### By X point in time:
- ### By X point in time:
-
## End Time
- 11/03/2022 at 4:00 PM
- 11/03/2022 at 4:00 PM

View File

@@ -1,32 +1,41 @@
# Meeting Minutes (11/04/2022)
## Team 29: Hackers1995
## Meeting Topic: Technologies Discussion
We're planning out our first sprint and breaking up the project into tasks. Tasks will be assigned to groups and GitHub issues will be created
for each task and assigned to a group.
## Attendance
1. Rhea Bhutada
2. Sanjit Joseph
3. Arthur Lu
4. Marc Reta
6. Kara Hoagland
7. Daniel Hernandez
8. Gavyn Ezell
9. Isaac Otero
10. Henry Feng
5. Kara Hoagland
6. Daniel Hernandez
7. Gavyn Ezell
8. Isaac Otero
9. Henry Feng
## Meeting Details
- When: 11/04/2022 at 10:00AM
- Where: George's Zoom room
- When: 11/04/2022 at 10:00AM
- Where: George's Zoom room
## Agenda:
## Sprint 1 Categories and Assignments
Frontend: Isaac, Sanjit, and Daniel
Backend: Rhea, George, Gavyn, Kara,
- Save to database
- Load from database
- Clear database
Unit Testing: Arthur, Marc
- Save to database
- Load from database
- Clear database
Unit Testing: Arthur, Marc
## End Time
- 11/03/2022 at 10:30 AM
- 11/03/2022 at 10:30 AM

View File

@@ -1,9 +1,13 @@
# Meeting Minutes (11/07/2022)
## Team 29: Hackers1995
## Meeting Topic: First Sprint
Meeting notes for the first sprint
## Attendance
1. Rhea Bhutada
2. George Dubinin
3. Gavyn Ezell
@@ -15,27 +19,29 @@ Meeting notes for the first sprint
9. Arthur Lu
## Absentees
1. Isaac Otero
## Meeting Details
- When: 11/07/2022 at 6:00PM
- Where: CSE Building Second Floor
- When: 11/07/2022 at 6:00PM
- Where: CSE Building Second Floor
## Agenda:
- ### Old/Unresolved Business
- N/A
- ### New Business
- The first sprint:
- Create more Gitflows and automation. Verify current workflows and actions
- Determine interface details for the app (user experience)
- Start on the backend
- ### Next Meeting's Business
- ### Old/Unresolved Business
- N/A
- ### New Business
- The first sprint:
- Create more Gitflows and automation. Verify current workflows and actions
- Determine interface details for the app (user experience)
- Start on the backend
- ### Next Meeting's Business
## Decisions Made
- Linting details decided (TABS NOT SPACES)
- Linting details decided (TABS NOT SPACES)
## End Time
- 11/07/2022 at 8:00PM
- 11/07/2022 at 8:00PM

View File

@@ -0,0 +1,45 @@
# Meeting Minutes (11/08/2022)
## Team 29: Hackers1995
## Meeting Topic: In-Person First Sprint Day 2
Meeting notes for the first sprint
## Attendance
1. Rhea Bhutada
2. George Dubinin
3. Gavyn Ezell
4. Kara Hoagland
5. Sanjit Joseph
6. Daniel Hernandez
## Meeting Details
- When: 11/08/2022 at 2:00PM
- Where: Mike's Red Tacos
## Agenda:
- ### Old/Unresolved Business
- N/A
- ### New Business
- Isaac now knows what Wolftown is
- Pair programming setup with VSCode
- ### Next Meeting's Business
## App Progress
- The landing page is closer
- Review card css file entered
- Review Card javascript logic implemented (thanks Gavin)
-
## Decisions Made
- Linting details decided (TABS NOT SPACES)
## End Time
- 11/07/2022 at 8:00PM

View File

@@ -1,36 +1,43 @@
# Meeting Minutes (11/09/2022)
## Team 29: Hackers1995
## Meeting Topic: Weekly TA Catchup with Gagan
We are meeting with Gagan to discuss progress made on Sprint 1 and testing strategies that we need to keep in mind as we continue developing.
## Attendance
1. Rhea Bhutada
2. George Dubinin
3. Gagan Gopalaiah
4. Sanjit Joseph
## Meeting Details
- When: 11/09/2022 at 3:30PM
- Where: Zoom
- When: 11/09/2022 at 3:30PM
- Where: Zoom
## Agenda:
## Discussion Points by Gagan
- Provided updates on first sprint
- Testing Tips
- functionality testing
- test one feature
- test individual functions
- static testing
- checking if its meeting the conventions and standards for specific programming language
- linting
- specific to programming language
- overall
- if tested properly, we reduce problems end-to-end testing
- Documentation
- What the code does?
- What the file is for?
- JS Docs
- Provided updates on first sprint
- Testing Tips
- functionality testing
- test one feature
- test individual functions
- static testing
- checking if its meeting the conventions and standards for specific programming language
- linting
- specific to programming language
- overall
- if tested properly, we reduce problems end-to-end testing
- Documentation
- What the code does?
- What the file is for?
- JS Docs
## End Time
- 11/09/2022 at 4:00PM
- 11/09/2022 at 4:00PM

View File

@@ -1,8 +1,11 @@
# Sprint 1 Retrospective (11/14/2022)
## Team 29: Hackers1995
## Meeting Topic: Sprint 1 Retrospective
## Attendance
1. Rhea Bhutada
2. George Dubinin
3. Sanjit Joseph
@@ -15,54 +18,64 @@
10. Isaac Otero
## Meeting Details
- When: 11/14/2022 at 4:30PM
- Where: On Campus
- When: 11/14/2022 at 4:30PM
- Where: On Campus
## Agenda:
Discuss the review, share more detailed thoughts on sprint 1, and create some resolutions for sprint 2
## Sprint 1 Review Below (for convenience)
## Sprint 1 REVIEW
In collecting feedback during our final sprint the leads decided to ask members individually about their experience during sprint 1 to then summarize these responses. Each member was asked 4 questions with their summarized responses below:
### What do you think worked well in the first sprint?
We resolved to hold each of our sprint 1 meetings in person with a remote option available to members that couldn't attend. We really liked hanging out at the restaurants before working on the sprint and these experiences encouraged psychological safety in the group. We made some noticeable progress which was very encouraging for the group. Specifically, we figured out quite a bit of the CI/CD pipeline details which will help us going forward and we got a solid grasp of what the visual aspects and feel of the website will be.
### What can we improve on for the next sprint?
We ran into trouble early on due to some lack of planning for specific tasks. The members agreed that we should have spent more time defining tasks for specific members and defining goals for our different teams (frontend, backend, and unit testing). There was some concern over members not being able to attend all meetings and we think this could have been fixed with regularly scheduled meetings. Some technical concerns were the Javascript unit testing pipeline development lagging behind code development and pipeline requirements being unclear. Perhaps we should write out a style document to guide the automated linting process.
### What was your contribution to the sprint?
* Rhea Bhutada: Worked on the backend features including how to get create new review card page to open in a new window
* Gavyn Etzel: Helped with javascript side of things for website
* Henry Feng: Local image store and meeting support
* Sanjit: Default photo design and frontend star rating css
* Daniel: Helped modify html, added upload file feature
* Arthur Lu: Added JS Linting, Unit testing pipeline actions and rote a few simple unit tests; added deployment pipeline action
* Marc Rheta: Added HTML Linting and CSS Linting
* Isaac Otero: Low and mid fidelity wireframes of how our page will look like, Started working on homepage.html
* George Dubinin: Meeting notes, Repo organization, cookies
* Kara Hoagland: CRUD backend functionality
- Rhea Bhutada: Worked on the backend features including how to get create new review card page to open in a new window
- Gavyn Etzel: Helped with javascript side of things for website
- Henry Feng: Local image store and meeting support
- Sanjit: Default photo design and frontend star rating css
- Daniel: Helped modify html, added upload file feature
- Arthur Lu: Added JS Linting, Unit testing pipeline actions and rote a few simple unit tests; added deployment pipeline action
- Marc Rheta: Added HTML Linting and CSS Linting
- Isaac Otero: Low and mid fidelity wireframes of how our page will look like, Started working on homepage.html
- George Dubinin: Meeting notes, Repo organization, cookies
- Kara Hoagland: CRUD backend functionality
### Was there anything blocking your progress in the sprint?
Communication was challenging especially for members that would attend over Zoom and it was a challenge keeping track of each member's progress. We ran into some issues with the branching strategy with branches rapidly multiplying at points and the GitHub tags not working. The biggest technical issue we experienced involved Node and ES6 compatibility issues.
Communication was challenging especially for members that would attend over Zoom and it was a challenge keeping track of each member's progress. We ran into some issues with the branching strategy with branches rapidly multiplying at points and the GitHub tags not working. The biggest technical issue we experienced involved Node and ES6 compatibility issues.
Overall we feel that sprint 1 was a success with many lessons learned. Our enthusiasm for the project is only building and we are excited to get back into it with sprint 2 after a much needed short break.
## Resolutions
* Divide up tasks and assign tasks to members
* Define objectives for team groups (frontend, backend, and unit testing)
* Scheduled meetings with more notice and keep meetings at a more central location so that more members can attend
* Get the unit testing modules up to date
* To-do: create a style guide
* Heed the styles and documentation (to avoid linter issues)
- Divide up tasks and assign tasks to members
- Define objectives for team groups (frontend, backend, and unit testing)
- Scheduled meetings with more notice and keep meetings at a more central location so that more members can attend
- Get the unit testing modules up to date
- To-do: create a style guide
- Heed the styles and documentation (to avoid linter issues)
## Early Issues
* restructure local storage to store individual (key, review) pairs rather than storing data under one key (current schema)
* implement a file upload system (think canvas file upload)
* add a cuisine attribute for tagging and filtering
* Create UI buttons and low fidelity css
* Unit test all the above
- restructure local storage to store individual (key, review) pairs rather than storing data under one key (current schema)
- implement a file upload system (think canvas file upload)
- add a cuisine attribute for tagging and filtering
- Create UI buttons and low fidelity css
- Unit test all the above
## End Time
- 11/14/2022 at 5:00PM
- 11/14/2022 at 5:00PM

View File

@@ -1,9 +1,13 @@
# Sprint 1 Review Meeting Minutes (11/13/2022)
## Team 29: Hackers1995
## Meeting Topic: Sprint 1 Review
We are meeting with Gagan to discuss progress made on Sprint 1 and testing strategies that we need to keep in mind as we continue developing.
## Attendance
1. Rhea Bhutada
2. George Dubinin
3. Sanjit Joseph
@@ -16,37 +20,45 @@ We are meeting with Gagan to discuss progress made on Sprint 1 and testing strat
10. Isaac Otero
## Meeting Details
- When: 11/13/2022 at 1:00PM
- Where: Capital One Cafe and Zoom
- When: 11/13/2022 at 1:00PM
- Where: Capital One Cafe and Zoom
## Agenda:
Review the week 7 sprint and get the writeup for the Agile review assignemnt
## Sprint 1 REVIEW
In collecting feedback during our final sprint the leads decided to ask members individually about their experience during sprint 1 to then summarize these responses. Each member was asked 4 questions with their summarized responses below:
### What do you think worked well in the first sprint?
We resolved to hold each of our sprint 1 meetings in person with a remote option available to members that couldn't attend. We really liked hanging out at the restaurants before working on the sprint and these experiences encouraged psychological safety in the group. We made some noticeable progress which was very encouraging for the group. Specifically, we figured out quite a bit of the CI/CD pipeline details which will help us going forward and we got a solid grasp of what the visual aspects and feel of the website will be.
### What can we improve on for the next sprint?
We ran into trouble early on due to some lack of planning for specific tasks. The members agreed that we should have spent more time defining tasks for specific members and defining goals for our different teams (frontend, backend, and unit testing). There was some concern over members not being able to attend all meetings and we think this could have been fixed with regularly scheduled meetings. Some technical concerns were the Javascript unit testing pipeline development lagging behind code development and pipeline requirements being unclear. Perhaps we should write out a style document to guide the automated linting process.
### What was your contribution to the sprint?
* Rhea Bhutada: Worked on the backend features including how to get create new review card page to open in a new window
* Gavyn Etzel: Helped with javascript side of things for website
* Henry Feng: Local image store and meeting support
* Sanjit: Default photo design and frontend star rating css
* Daniel: Helped modify html, added upload file feature
* Arthur Lu: Added JS Linting, Unit testing pipeline actions and rote a few simple unit tests; added deployment pipeline action
* Marc Rheta: Added HTML Linting and CSS Linting
* Isaac Otero: Low and mid fidelity wireframes of how our page will look like, Started working on homepage.html
* George Dubinin: Meeting notes, Repo organization, cookies
* Kara Hoagland: CRUD backend functionality
- Rhea Bhutada: Worked on the backend features including how to get create new review card page to open in a new window
- Gavyn Etzel: Helped with javascript side of things for website
- Henry Feng: Local image store and meeting support
- Sanjit: Default photo design and frontend star rating css
- Daniel: Helped modify html, added upload file feature
- Arthur Lu: Added JS Linting, Unit testing pipeline actions and rote a few simple unit tests; added deployment pipeline action
- Marc Rheta: Added HTML Linting and CSS Linting
- Isaac Otero: Low and mid fidelity wireframes of how our page will look like, Started working on homepage.html
- George Dubinin: Meeting notes, Repo organization, cookies
- Kara Hoagland: CRUD backend functionality
### Was there anything blocking your progress in the sprint?
Communication was challenging especially for members that would attend over Zoom and it was a challenge keeping track of each member's progress. We ran into some issues with the branching strategy with branches rapidly multiplying at points and the GitHub tags not working. The biggest technical issue we experienced involved Node and ES6 compatibility issues.
Communication was challenging especially for members that would attend over Zoom and it was a challenge keeping track of each member's progress. We ran into some issues with the branching strategy with branches rapidly multiplying at points and the GitHub tags not working. The biggest technical issue we experienced involved Node and ES6 compatibility issues.
Overall we feel that sprint 1 was a success with many lessons learned. Our enthusiasm for the project is only building and we are excited to get back into it with sprint 2 after a much needed short break.
## End Time
- 11/13/2022 at 3:00PM
- 11/13/2022 at 3:00PM

View File

@@ -0,0 +1,40 @@
# Meeting Minutes (11/16/2022)
## Team 29: Hackers1995
## Meeting Topic: Weekly TA Catchup with Gagan
We are meeting with Gagan to discuss Checkpoint 1 and Sprint 2 resolutions.
## Attendance
1. Rhea Bhutada
2. George Dubinin
3. Gagan Gopalaiah
4. Kara Hoagland
## Meeting Details
- When: 11/16/2022 at 3:30PM
- Where: Zoom
## Agenda:
## Discussion Points by Gagan
- Updated Gagan on Sprint 1
- looked at Girhub actions
- looked at the published page so far
- discussed retrospective
- Upcoming Assignments
- we have to come up with a video on the status of our app
- ramp up the styling part, so u can brag about the design of the app
- this video is supposed to encourage healthy competition
- Other Concerns
- JSDocs - not primary concern right now
- GitHub Pages vs. Netlify
- Gagan sees Netlify as more professional and not to difficult to implement
## End Time
- 11/16/2022 at 3:45PM

View File

@@ -0,0 +1,59 @@
# Meeting Minutes (11/07/2022)
## Team 29: Hackers1995
## Meeting Topic: First Sprint
Meeting notes for the first sprint
## Attendance
1. Rhea Bhutada
2. George Dubinin
3. Gavyn Ezell
4. Henry Feng
5. Kara Hoagland
6. Marc Reta
7. Sanjit Joseph
8. Daniel Hernandez
9. Arthur Lu
10. Isaac Otero
## Meeting Details
- When: 11/17/2022 at 11:30PM
- Where: Design & Innovation Building
## Agenda:
- ### Old/Unresolved Business
- N/A
- ### New Business
- Second sprint commences!
- Focus on design progress for the project showoff
- Cuisine vs Tag identifiers for reviews (both?)
- localStorage will hold:
- list of active IDs which is updated for very create operation. An ID uniquely identifies a review
- value, "nextId" denoting the index of the next available slot for an Id
- entries for every single review (javascript object)
- a list for every tag that denotes which Ids belong to reviews containing this tag
End2end tests will rely on specific html element names which include the following:
- "create-btn" (located on homepage and used to create a new review)
- "submit-btn" (located on form and used to post review)
- "update-btn" (located on a specific review page)
- "delete-btn" (located on a specific review page)
- "tag-add-btn" (located on the review create form)
- ### Next Meeting's Business
## Decisions Made
-
## End Time
- 11/17/2022 at 1:00PM

View File

@@ -0,0 +1,48 @@
# Meeting Minutes (11/20/2022)
## Team 29: Hackers1995
## Meeting Topic: Second Sprint Meeting 3
## Attendance
1. Rhea Bhutada
2. George Dubinin
3. Gavyn Ezell
4. Henry Feng
5. Kara Hoagland
6. Marc Reta
7. Sanjit Joseph
8. Daniel Hernandez
9. Arthur Lu
10. Isaac Otero
## Meeting Details
- When: 11/20/2022 at 1:00PM
- Where: CSE Building Second Floor
## Agenda:
- ### Old/Unresolved Business
- N/A
- ### New Business
- Planning for the Agile Steam Status Video
- _Present the status of your software_
- Show off the preliminary design of index.html
- Walk through the process of creating a journal entry
- _Description of current challenges to development_
- _Preview of the next sprint and what to look forward to_
- Front end redo for home page including semantic restructuring and enhanced CSS
- Documentation session for JS, CSS, and HTML files
- Pipeline details have largely been ironed out
- ### Next Meeting's Business
- Creation of team status video
## End Time
- 11/20/2022 at 3:00PM

View File

@@ -0,0 +1,40 @@
# Meeting Minutes (11/23/2022)
## Team 29: Hackers1995
## Meeting Topic: Weekly TA Catchup with Gagan
We are meeting with Gagan to discuss status video and general updates on project.
## Attendance
1. Rhea Bhutada
2. George Dubinin
3. Gagan Gopalaiah
## Meeting Details
- When: 11/23/2022 at 3:30PM
- Where: Zoom
## Discussion Points by Gagan
- progress looks good!!
- deadline for project
- december 3rd/4th code freeze
- no new features
- only debugging
- after december 3rd/4th we need to focus on making a good final video
- final video
- played on finals day, voted on in class
- need to spend a good amount of time on it
- essential to make this good
- last week there are going to be one-to-one sessions held
- Gagan will be asking questions to the team
- everyone needs to be aware of all aspects of the project
- start end-to-end testing on project
- quickly discussed team roles
## End Time
- 11/23/2022 at 3:52PM

View File

@@ -0,0 +1,77 @@
# Sprint 2 Review Meeting Minutes (11/27/2022)
## Team 29: Hackers1995
## Meeting Topic: Sprint 2 Review
We are reviewing the second sprint 2 progress made and highlights
## Attendance
1. Rhea Bhutada
2. George Dubinin
3. Sanjit Joseph
4. Kara Hoagland
5. Arthur Lu
6. Mark Rheta
7. Henry Feng
8. Gavyn Etzel
9. Sanjit Joseph
10. Isaac Otero
## Meeting Details
- When: 11/27/2022 at 4:30PM
- Where: Zoom
## Agenda:
Review the second sprint and discuss assiget the writeup for the Agile review assignemnt
## Sprint 2 REVIEW
In collecting feedback for the sprint the leads decided to ask members individually about their experience during sprint 2 to then summarize these responses. Each member was asked 4 questions with their summarized responses below:
### ➼ What do you think worked well in the first sprint?
Communication within the group was improved and our joint study sessions where more productive. The design team got the support they needed to accomplish the majority of their work on the project. The push to emphasize the sub-teams responsible for different tasks turned out to be a great idea and everyone put in a good effort.
### ➼ What can we improve on for the next sprint?
With the vast majority of feature implementation underway the rapid progress created a lot of bugs which otherwise could have been avoid with more careful planning. Some members felt that even though they made a great effort they weren't able to contribute as much as they wanted to. Some of the code documentation fell behind and some design discussions were circumvented because some members where busy. One consequence was that relatively few ADRs were created even though we made many important design decisions during sprint 2.
### ➼ What was your contribution to the sprint?
- Rhea Bhutada: I mainly helped implement the backend for the CRUD features of the app and documentation related to this. This mainly entailed changing the way that we were storing user data in local storage. Additionally, I helped design the form and homepage.
- Gavyn Etzel: Helped with JavaScript functionality (CRUD Features), and also did a lot of the documentation for the script files
Helped work through the storage revamp for our review cards
Also helped integrate our first design/style setup with functionality
- Henry Feng: Worked on implementing local image uploading and storing features for updating and creating profiles.
- Sanjit: I reimplemented the star ratings since they had some issues and werent merged with sprint 1. I fixed a bunch of linting issues that popped up from that as well. I did a fair bit of color palette brainstorming with the team. I also went over our app design for the sprint video and edited that together. Most importantly I put a chef hat on the raccoon
- Daniel: Helped in initial CreatePage and HomePage design which improved through feedback from the rest of the group.
Helped in styling suggestions.
- Arthur Lu: Worked on fixing some CI/CD pipeline issues
Implemented e2e testing for basic update and delete functionality
Helped with fixing the homepage and review page layout
Helped with fixing the article tag overflow issue
- Marc Rheta: Implemented the e2e testing for reading and create
Allowed tabs for CSS/HTML linters
- Isaac Otero: I was able to help out with the sprint video for the last sprint and thought of how our page will look like, Started working on homepage.html
- George Dubinin: Meeting notes, Repo organization, Front-end (a little), Project Status Review video.
- Kara Hoagland: I helped set up the new local storage design, reimplemented the CRUD features using the new local storage design, contributed to the styling, added a default img, backend on the details page
### ➼ Was there anything blocking your progress in the sprint?
A few members got sick over the break and with midterms picking up for other classes some members had trouble dedicting time for the project but everyone still put in a great effort overall.
## Next Sprint Goals
- Resolve the 4 issues open on GitHub right now
- Make the project "local first" by creating a cache
- Bug fixes and final product adjustments possibly pushed to sprint 4
- We aim to keep sprint 3 short (a few days max)
- JS docs (we can potentially leave this out with an explanation of where our documentation is)
## End Time
- 11/27/2022 at 5:00PM

View File

@@ -0,0 +1,84 @@
# Sprint 1 Retrospective (11/28/2022)
## Team 29: Hackers1995
## Meeting Topic: Sprint 1 Retrospective
## Attendance
1. Rhea Bhutada
2. George Dubinin
3. Sanjit Joseph
4. Kara Hoagland
5. Arthur Lu
6. Mark Rheta
7. Henry Feng
8. Gavyn Etzel
9. Sanjit Joseph
10. Isaac Otero
## Meeting Details
- When: 11/28/2022 at 4:00PM
- Where: Zoom
## Agenda:
Discuss the review, share more detailed thoughts on sprint 2, and create some resolutions for sprint 3
## Sprint 3 Review Below (for convenience)
In collecting feedback for the sprint the leads decided to ask members individually about their experience during sprint 2 to then summarize these responses. Each member was asked 4 questions with their summarized responses below:
### ➼ What do you think worked well in the first sprint?
Communication within the group was improved and our joint study sessions where more productive. The design team got the support they needed to accomplish the majority of their work on the project. The push to emphasize the sub-teams responsible for different tasks turned out to be a great idea and everyone put in a good effort.
### ➼ What can we improve on for the next sprint?
With the vast majority of feature implementation underway the rapid progress created a lot of bugs which otherwise could have been avoid with more careful planning. Some members felt that even though they made a great effort they weren't able to contribute as much as they wanted to. Some of the code documentation fell behind and some design discussions were circumvented because some members where busy. One consequence was that relatively few ADRs were created even though we made many important design decisions during sprint 2.
### ➼ What was your contribution to the sprint?
- Rhea Bhutada: I mainly helped implement the backend for the CRUD features of the app and documentation related to this. This mainly entailed changing the way that we were storing user data in local storage. Additionally, I helped design the form and homepage.
- Gavyn Etzel: Helped with JavaScript functionality (CRUD Features), and also did a lot of the documentation for the script files
Helped work through the storage revamp for our review cards
Also helped integrate our first design/style setup with functionality
- Henry Feng: Worked on implementing local image uploading and storing features for updating and creating profiles.
- Sanjit: I reimplemented the star ratings since they had some issues and werent merged with sprint 1. I fixed a bunch of linting issues that popped up from that as well. I did a fair bit of color palette brainstorming with the team. I also went over our app design for the sprint video and edited that together. Most importantly I put a chef hat on the raccoon
- Daniel: Helped in initial CreatePage and HomePage design which improved through feedback from the rest of the group.
Helped in styling suggestions.
- Arthur Lu: Worked on fixing some CI/CD pipeline issues
Implemented e2e testing for basic update and delete functionality
Helped with fixing the homepage and review page layout
Helped with fixing the article tag overflow issue
- Marc Rheta: Implemented the e2e testing for reading and create
Allowed tabs for CSS/HTML linters
- Isaac Otero: I was able to help out with the sprint video for the last sprint and thought of how our page will look like, Started working on homepage.html
- George Dubinin: Meeting notes, Repo organization, Front-end (a little), Project Status Review video.
- Kara Hoagland: I helped set up the new local storage design, reimplemented the CRUD features using the new local storage design, contributed to the styling, added a default img, backend on the details page
### ➼ Was there anything blocking your progress in the sprint?
A few members got sick over the break and with midterms picking up for other classes some members had trouble dedicting time for the project but everyone still put in a great effort overall.
## Next Sprint Goals
- Resolve the 4 issues open on GitHub right now
- Make the project "local first" by creating a cache
- Bug fixes and final product adjustments possibly pushed to sprint 4
- We aim to keep sprint 3 short (a few days max)
- JS docs (we can potentially leave this out with an explanation of where our documentation is)
## Resolutions
- Sprint 3 first meeting happening 11-29 at 5:00PM
- Make sure that there's enough communication between front-end and back-end
- Focus on meeting with your subgroup and then touch base with the main group
- Keep documentation up to date with the rest of the project
- We need to finalize the home page design (this has been open for a while).
- Fix image sizing issues by focusing on supporting 300x300 pixel images with sizes of around 2-5 megabytes
## End Time
- 11/14/2022 at 5:00PM

View File

@@ -0,0 +1,41 @@
# Meeting Minutes (11/29/2022)
## Team 29: Hackers1995
## Meeting Topic: Sprint 3 Debut Meeting
## Attendance
1. Rhea Bhutada
2. George Dubinin
3. Gavyn Ezell
4. Henry Feng
5. Kara Hoagland
6. Marc Reta (remote)
7. Sanjit Joseph
8. Daniel Hernandez
9. Arthur Lu (remote)
## Meeting Details
- When: 11/29/2022 at 5:00PM
- Where: Design and Innovation Building
## Agenda:
- ### Old/Unresolved Business
- Resolve pretty print linting PR
- Resolve documentation not being merged to main PR
- ### New Business
- Create ADR for image storage
- Review sorting defaults (recent or top rated)
- Adding lists of reviewIDs corresponding to reviews which share specific star ratings
- Create function for retrieving top 20 reviews organized by decreasing star ratings
- Implement search for for flitering tags
- Frontend checked out new branch for alternate home page designs
- ### Next Meeting's Business
- Creation of team status video
## End Time
- 11/20/2022 at 3:00PM

View File

@@ -0,0 +1,36 @@
# Meeting Minutes (11/30/2022)
## Team 29: Hackers1995
## Meeting Topic: Sprint 3 Continued
## Attendance
1. Rhea Bhutada
2. George Dubinin
3. Henry Feng
4. Kara Hoagland
5. Sanjit Joseph
6. Arthur Lu
## Meeting Details
- When: 11/30/2022 at 2:00PM
- Where: Design and Innovation Building
## Agenda:
- ### Old/Unresolved Business
- Fix empty page for no-tag search
- Catch testing up with what we implemented yesterday
- ### New Business
- Cache the site for local first (high priority)
- Implement editing form "in place" (optional for this sprint)
- Change icon for "add review" entry
- Overcoming UI test challenges
- ### Next Meeting's Business
- Creation of team status video
## End Time
- 11/30/2022 at 2:00PM

View File

@@ -1,39 +0,0 @@
# Meeting Minutes (11/08/2022)
## Team 29: Hackers1995
## Meeting Topic: In-Person First Sprint Day 2
Meeting notes for the first sprint
## Attendance
1. Rhea Bhutada
2. George Dubinin
3. Gavyn Ezell
4. Kara Hoagland
5. Sanjit Joseph
6. Daniel Hernandez
## Meeting Details
- When: 11/08/2022 at 2:00PM
- Where: Mike's Red Tacos
## Agenda:
- ### Old/Unresolved Business
- N/A
- ### New Business
- Isaac now knows what Wolftown is
- Pair programming setup with VSCode
- ### Next Meeting's Business
## App Progress
- The landing page is closer
- Review card css file entered
- Review Card javascript logic implemented (thanks Gavin)
-
## Decisions Made
- Linting details decided (TABS NOT SPACES)
## End Time
- 11/07/2022 at 8:00PM

View File

@@ -0,0 +1,29 @@
# Meeting Minutes (12/1/2022)
## Team 29: Hackers1995
## Meeting Topic: Weekly TA Catchup with Gagan
We are meeting with Gagan to discuss status video and general updates on project.
## Attendance
1. Rhea Bhutada
2. George Dubinin
3. Gagan Gopalaiah
## Meeting Details
- When: 12/1/2022 at 12:00PM
- Where: Zoom
## Discussion Points by Gagan
- Don't code up anything after Sunday. Reserve the time for bug fixes
- Final Interview is a 4-5 minute interview about general course specific topics
- Live demo of the app for Gagan
- Gagan asks us to evaluate instructional assistants
## End Time
- 12/1/2022 at 12:20PM

View File

@@ -1,13 +1,18 @@
# Team Working Agreement
## Term: Fall 2022
## Creation: 10/12/2022; Revised: N/A
## Group Identification
- Team 29
- TA: Gagan Gopalaiah
- Instructor: Professor Thomas Powell
- Team Name: Hackers1995
## Team member info (name/email)
1. Rhea Bhutada, rbhutada@ucsd.edu
2. George Dubinin, gdubinin@ucsd.edu
3. Gavyn Ezell, gezell@ucsd.edu
@@ -20,38 +25,42 @@
10. Daniel Hernandez, d7hernan@ucsd.edu
## RULES:
#### 1) Primary Means of Communication and Expectations
- All members will communicate via Slack.
- All members will be expected to read messages from group chats and direct messages, and respond in no more than 4 hours and no later than 10PM.
- All pull requests require 3 people to review the code being pushed to main.
#### 1) Primary Means of Communication and Expectations
- All members will communicate via Slack.
- All members will be expected to read messages from group chats and direct messages, and respond in no more than 4 hours and no later than 10PM.
- All pull requests require 3 people to review the code being pushed to main.
#### 2) Scheduling Meetings (Schedule at least one meeting as part of constructing your team agreement.)
- Members are expected to meet at least once a week with the group either in-person or on Zoom. Future meeting details will be determined within a 24 hours window.
- Team members hosting the meeting will send out a reminder of the meeting with an agenda 2 hours before the meeting.
- Members are expected to meet at least once a week with the group either in-person or on Zoom. Future meeting details will be determined within a 24 hours window.
- Team members hosting the meeting will send out a reminder of the meeting with an agenda 2 hours before the meeting.
#### 3) General Responsibilities for All Team Members
- Respect the contributions of others.
- Work on assignments early to allow others to review and debug any issues.
- Communicate any issues or problems as early as possible.
- Be open to criticism.
- Respect the contributions of others.
- Work on assignments early to allow others to review and debug any issues.
- Communicate any issues or problems as early as possible.
- Be open to criticism.
#### 4) Specific Team Member Responsibilities/Deadlines (Optional)
- A daily standup is required every day from every team member. A daily standup includes what you've completed, what you want to work on, and what issues you encountered for the day. If you haven't done anything for that day, write down what you will be contributing.
- A daily standup is required every day from every team member. A daily standup includes what you've completed, what you want to work on, and what issues you encountered for the day. If you haven't done anything for that day, write down what you will be contributing.
#### 5) Conflict Resolution
- Conflicts between individuals will first try to be resolved amongst the people involved.
- Group conflicts will be voted on.
- Ongoing conflicts will be reported to the TA.
- Unprofessionalism of any kind will not be tolerated. Conflicts involving this will immediately be brought up with the TA
- Conflicts between individuals will first try to be resolved amongst the people involved.
- Group conflicts will be voted on.
- Ongoing conflicts will be reported to the TA.
- Unprofessionalism of any kind will not be tolerated. Conflicts involving this will immediately be brought up with the TA
#### 6) Expectations of Faculty and GTAs
- If a team member fails to live up to this agreement, the situation may be reported to the staff, but the team will still be responsible for submitting a completed assignment. Staff will be available to meet with teams to resolve issues.
- If a team member fails to live up to this agreement, the situation may be reported to the staff, but the team will still be responsible for submitting a completed assignment. Staff will be available to meet with teams to resolve issues.
## Team Signatures
#### Print Name:
#### Signature:

View File

@@ -1,73 +1,76 @@
# **Hackers1995**
## **Brand**
![poster](./branding/teamposter.jpg)
## **Values**
- Openness
- Honesty
- Respect
- Integrity
- Diversity/Inclusion
- Openness
- Honesty
- Respect
- Integrity
- Diversity/Inclusion
## **Roster**
### **TA: Gagan Gopalaiah**
### **Team Lead: Rhea Bhutada**
- #### About Me:
- My name is Rhea Bhutada and I am currently a CS major and CogSci minor at ERC. The intersection between neuroscience and computer science really fascinates me and I generally try to apply myself to projects that deal with the overlap of both of these fields. This year I'm working as an undergraduate researcher at the Swartz Center for Computational Neuroscience, which has been an extremely cool experience. Other than that I love to stay active. I used to play basketball in high school and was in an NCAA commercial with Shaq. But lately, Ive been really into running. Overall, I'm excited to contribute to this project! Although I haven't had too much industry experience, I am interested to see how I can apply my previous course work to backend or frontend design.
- #### Link to Github: https://github.com/rheabhutada02
- #### About Me:
- My name is Rhea Bhutada and I am currently a CS major and CogSci minor at ERC. The intersection between neuroscience and computer science really fascinates me and I generally try to apply myself to projects that deal with the overlap of both of these fields. This year I'm working as an undergraduate researcher at the Swartz Center for Computational Neuroscience, which has been an extremely cool experience. Other than that I love to stay active. I used to play basketball in high school and was in an NCAA commercial with Shaq. But lately, Ive been really into running. Overall, I'm excited to contribute to this project! Although I haven't had too much industry experience, I am interested to see how I can apply my previous course work to backend or frontend design.
- #### Link to Github: https://github.com/rheabhutada02
### **Team Lead: George Dubinin**
- #### About Me:
- Hello World! I'm a fifth year (3rd year transfer) computer science major from the North Bay Area. Web development has been a big focus of mine since taking Prof Powell's 134B last winter and I'm stoked to be back in the "full stack" developer seat for 110. I am the second the team lead and in addition to my love for leading and working on team projects I am also fascinated by web development technologies including containerization, infrastructure as code (IaC), software as a service (SAAS), and web-based encryption (security). I am also an avid DJ and the traininer manmager for the DJ club on campus. This quarter is shaping up to be a memorable one!
- #### Link to Github: https://github.com/look-its-ashton
- #### About Me:
- Hello World! I'm a fifth year (3rd year transfer) computer science major from the North Bay Area. Web development has been a big focus of mine since taking Prof Powell's 134B last winter and I'm stoked to be back in the "full stack" developer seat for 110. I am the second the team lead and in addition to my love for leading and working on team projects I am also fascinated by web development technologies including containerization, infrastructure as code (IaC), software as a service (SAAS), and web-based encryption (security). I am also an avid DJ and the traininer manmager for the DJ club on campus. This quarter is shaping up to be a memorable one!
- #### Link to Github: https://github.com/CODE-REFINARY
### **Gavyn Ezell**
- #### About Me:
- My name is Gavyn Ezell and Im from Hawaii. Currently a 3rd year CS Major at Muir. I love video games, playing piano, and going to the gym. For SWE, backend interests me most (I am not good with design and visuals), and Im hoping to learn a lot more backend from this project!
- #### Link to Github: https://github.com/gavyn-ezell
- #### About Me:
- My name is Gavyn Ezell and Im from Hawaii. Currently a 3rd year CS Major at Muir. I love video games, playing piano, and going to the gym. For SWE, backend interests me most (I am not good with design and visuals), and Im hoping to learn a lot more backend from this project!
- #### Link to Github: https://github.com/gavyn-ezell
### **Daniel Hernandez**
- #### About Me:
- My name is Daniel Hernandez and I am a 3rd year Computer Science major and music minor. Some of my interests in the CS field are ML, AI, and Cybersecurity. Outside of school, I play drums for a local band. For SE, the backend aspect appeals to me the most since I am able to utilize more of what I learned from my past classes. However, I would want to try frontend since I do enjoy design to some extent.
- #### Link to Github: https://github.com/d7hernan
- #### About Me:
- My name is Daniel Hernandez and I am a 3rd year Computer Science major and music minor. Some of my interests in the CS field are ML, AI, and Cybersecurity. Outside of school, I play drums for a local band. For SE, the backend aspect appeals to me the most since I am able to utilize more of what I learned from my past classes. However, I would want to try frontend since I do enjoy design to some extent.
- #### Link to Github: https://github.com/d7hernan
### **Henry Feng**
- #### About Me:
- My name is Henry, and I am a 3rd year CS major. I was born in China and grew up in New Zealand. I wrote my first line of code, in Python during my second year of high school. My favourite foods are ramen, steak and pasta. Some of my hobbies include playing guitar, hiking, cooking, video games, and music (from the Persona series). I am excited to start this project and hope to contribute to both frontend and backend.
- #### Link to Github: https://github.com/dusk-moon
- #### About Me:
- My name is Henry, and I am a 3rd year CS major. I was born in China and grew up in New Zealand. I wrote my first line of code, in Python during my second year of high school. My favourite foods are ramen, steak and pasta. Some of my hobbies include playing guitar, hiking, cooking, video games, and music (from the Persona series). I am excited to start this project and hope to contribute to both frontend and backend.
- #### Link to Github: https://github.com/dusk-moon
### **Kara Hoagland**
- #### About Me:
- My name is Kara Hoagland and I am a 3rd year Computer Engineering major. CS-wise, I'm interested in topics such as computer vision and RFID, but it's hard to limit oneself because there's so many interesting topics out there. Outside of CS, I enjoy D&D, biking, and reading. I got some industry experience over summer and love getting to see how that experience and my previous classes all apply to this project. I'm interested in full stack but more so the backend of things.
- #### Link to Github: https://github.com/KH-Cl
- #### About Me:
- My name is Kara Hoagland and I am a 3rd year Computer Engineering major. CS-wise, I'm interested in topics such as computer vision and RFID, but it's hard to limit oneself because there's so many interesting topics out there. Outside of CS, I enjoy D&D, biking, and reading. I got some industry experience over summer and love getting to see how that experience and my previous classes all apply to this project. I'm interested in full stack but more so the backend of things.
- #### Link to Github: https://github.com/KH-Cl
### **Marc Reta**
- #### About Me: My name is Marc Reta and I am a 3rd year Computer Engineering major in Warren College. I love exploring San Diego and going on adventures. I have a huge interest in Public Transportation. I'm looking foward to working with everyone in my group and learn how to create an application.
- #### Link to Github: https://github.com/Graydogminer
- #### About Me: My name is Marc Reta and I am a 3rd year Computer Engineering major in Warren College. I love exploring San Diego and going on adventures. I have a huge interest in Public Transportation. I'm looking foward to working with everyone in my group and learn how to create an application.
- #### Link to Github: https://github.com/Graydogminer
### **Sanjit Joseph**
- #### About Me:
- Hi! My name is Sanjit Joseph and I'm a 3rd year CE major at Sixth. I'm from the Bay Area, so I've been surrounded by technology most of my life. I'm into building computers and I waste a lot of time (and money) messing with my PC and playing video games on it. I enjoy things outside of tech, though--as an Eagle Scout, I've done tons of backpacking throughout California and the US. I also hold a black belt in Shotokan Karate. As for this class, I'm pretty excited about all the different aspects of software engineering; frontend and backend both appeal to me, but I'm really just excited to work on a long class project in a team setting.
- #### Link to Github: https://github.com/sm-joseph
- #### About Me:
- Hi! My name is Sanjit Joseph and I'm a 3rd year CE major at Sixth. I'm from the Bay Area, so I've been surrounded by technology most of my life. I'm into building computers and I waste a lot of time (and money) messing with my PC and playing video games on it. I enjoy things outside of tech, though--as an Eagle Scout, I've done tons of backpacking throughout California and the US. I also hold a black belt in Shotokan Karate. As for this class, I'm pretty excited about all the different aspects of software engineering; frontend and backend both appeal to me, but I'm really just excited to work on a long class project in a team setting.
- #### Link to Github: https://github.com/sm-joseph
### **Isaac Otero**
- #### About Me:
- My name is Isaac Otero, I am a 5th year Cog Sci major. I am interested in front end development. I want to implement what Ive learned from my design classes into my projects for front end development.
- #### Link to Github: https://github.com/Isaac-Otero
- #### About Me:
- My name is Isaac Otero, I am a 5th year Cog Sci major. I am interested in front end development. I want to implement what Ive learned from my design classes into my projects for front end development.
- #### Link to Github: https://github.com/Isaac-Otero
### **Arthur Lu**
- #### About Me:
- My name is Arthur Lu and I am a 3rd year CE major. I am primarily interested in low level systems design, hardware development and optimization, and HPC architecture. I work as an undergraduate research assistant for Prof. Turakhia developing hardware accelerators for long length genome alignment. When Im not busy, I like to relax with some retro video games.
- #### Link to Github: https://github.com/ltcptgeneral
- #### About Me:
- My name is Arthur Lu and I am a 3rd year CE major. I am primarily interested in low level systems design, hardware development and optimization, and HPC architecture. I work as an undergraduate research assistant for Prof. Turakhia developing hardware accelerators for long length genome alignment. When Im not busy, I like to relax with some retro video games.
- #### Link to Github: https://github.com/ltcptgeneral

View File

@@ -0,0 +1,6 @@
# Final Video Links
## Link to Public Video:
https://www.youtube.com/watch?v=6o8SH_964Fo
## Link to Private Video:
https://www.youtube.com/watch?v=-iu8kXFZnCw

Binary file not shown.

View File

@@ -1,23 +1,30 @@
{
"name": "food-journal",
"version": "1.0.0",
"type": "module",
"scripts": {
"test": "mocha --recursive --require mock-local-storage './{,!(node_modules)/**}/*.test.js'",
"lint": "eslint '**/*.js'",
"fix-style": "eslint --fix **/*.js",
"lintHTML": "htmlhint '**/*.html'",
"lintCSS": "stylelint '**/*.css'",
"http-server": "http-server source"
},
"devDependencies": {
"eslint": "^8.27.0",
"htmlhint": "1.1.4",
"mocha": "10",
"mock-local-storage": "^1.1.23",
"stylelint": "14.14.1",
"stylelint-config-standard": "^29.0.0",
"puppeteer": "18",
"http-server": ""
}
"name": "food-journal",
"version": "1.0.0",
"type": "module",
"scripts": {
"test": "mocha --recursive --require mock-local-storage './{,!(node_modules)/**}/*.test.js'",
"coverage": "c8 --check-coverage --lines 90 --functions 90 --branches 90 npm run test",
"lint-js": "eslint **/*.js",
"fix-js": "eslint --fix **/*.js",
"lint-html": "htmlhint **/*.html",
"lint-css": "stylelint **/*.css",
"fix-css": "stylelint --fix **/*.css",
"http-server": "http-server source",
"lint-prettier": "prettier --check .",
"fix-prettier": "prettier --write .",
"js-doc": "jsdoc -d source/docs/ -r source/"
},
"devDependencies": {
"c8": "^7.12.0",
"eslint": "^8.27.0",
"htmlhint": "1.1.4",
"http-server": "",
"mocha": "10",
"mock-local-storage": "^1.1.23",
"prettier": "2.8.0",
"puppeteer": "^18.2.1",
"stylelint": "14.14.1",
"stylelint-config-standard": "^29.0.0"
}
}

View File

@@ -1,77 +1,93 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Food Journal</title>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Food Journal</title>
<!--Add Favicon-->
<link rel="icon" type="image/x-icon" href="./assets/images/favicon.ico" />
<!-- Recipe Card Custom Element -->
<script src="assets/scripts/ReviewCard.js" type="module"></script>
<!-- Review Card Custom Element -->
<script src="assets/scripts/ReviewCard.js" type="module"></script>
<!-- Create Page Stylesheets & Scripts -->
<link rel="stylesheet" href="./static/CreatePage.css" />
<link rel="stylesheet" href="./static/Form.css" />
<script src="./assets/scripts/CreatePage.js" type="module"></script>
</head>
<!-- Main Stylesheets & Scripts -->
<!-- Temporarily commented out reset.css due to furthur discussion needed on the values of the default config-->
<!-- <link rel="stylesheet" href="/static/reset.css" /> -->
<link rel="stylesheet" href="./static/ReviewCard.css" />
<script src="./assets/scripts/CreatePage.js" type="module"></script>
<header>
<!-- Setting up logo and site name at the top of the website -->
<div class="top-bar">
<img src="./assets/images/Logo.png" alt="logo" />
<h1>My Meal Journal</h1>
<img src="./assets/images/Logo.png" alt="logo" />
</div>
</header>
</head>
<body>
<div class="journal-form">
<h1>New Entry</h1>
<body>
<input type="button" value="Home" id="home-btn" onclick="window.location.assign('./index.html')">
<form id="new-food-entry">
<fieldset>
<legend>Pic:</legend>
<label for="mealImage">
Source:
<input type="text" id="mealImg" name="mealImg">
</label>
<label for="image-alt">
Alt Text:
<input type="text" id="imgAlt" name="imgAlt">
</label>
</fieldset>
<fieldset>
<form id="new-food-entry">
<fieldset>
<legend>PICTURE:</legend>
<select id="select" name="select">
<option value="file">File Upload</option>
<option value="photo">Take a Photo</option>
</select>
<input type="file" accept="image/*" id="mealImg" name="mealImg" />
</fieldset>
<legend> Meal: </legend>
<label for="Meal: ">Meal:
<input type="text" id="mealName" name="mealName" required>
</label>
<label for="comments">Comments:
<br>
<textarea name="comments" id="comments"></textarea>
</label>
</fieldset>
<fieldset>
<video id="player" width="320" height="240" autoplay hidden></video>
<canvas id="photoCanvas" width="320" height="240" hidden></canvas>
<button type="button" id="photoButton" hidden>Take Photo</button>
</fieldset>
<fieldset class="rating">
<legend> Rating: </legend>
<input type="radio" id="s5" name="rating" value="5"/> <label for="s5"> 5 stars </label>
<input type="radio" id="s4" name="rating" value="4"/> <label for="s4"> 4 stars </label>
<input type="radio" id="s3" name="rating" value="3"/> <label for="s3"> 3 stars </label>
<input type="radio" id="s2" name="rating" value="2"/> <label for="s2"> 2 stars </label>
<input type="radio" id="s1" name="rating" value="1"/> <label for="s1"> 1 star </label>
</fieldset>
<fieldset>
<legend>MEAL NAME:</legend>
<label for="Name: "> <input type="text" id="mealName" name="mealName" required /> </label>
</fieldset>
<fieldset>
<legend>Other Info:</legend>
<label for="restaurant">
Restaurant:
<input type="text" id="restaurant" name="restaurant" required>
</label>
<label for="tag-form">
Tags:
<input type="text" id="tag-form" name="tag-form">
<div class='tag-container' id="tag-container-form">
<fieldset>
<legend>RESTAURANT NAME:</legend>
<label for="Name:"> <input type="text" id="restaurant" name="restaurant" required /> </label>
</fieldset>
</div>
<button type="button" id="tagAdd">Add Tag</button>
</label>
<fieldset>
<legend>RATING:</legend>
<div style="display: flex; justify-content: flex-start; align-items: center">
<div class="rating">
<input type="radio" id="s5" name="rating" value="5" /> <label for="s5" id="s5-select"> 5 stars </label>
<input type="radio" id="s4" name="rating" value="4" /> <label for="s4" id="s4-select"> 4 stars </label>
<input type="radio" id="s3" name="rating" value="3" /> <label for="s3" id="s3-select"> 3 stars </label>
<input type="radio" id="s2" name="rating" value="2" /> <label for="s2" id="s2-select"> 2 stars </label>
<input type="radio" id="s1" name="rating" value="1" /> <label for="s1" id="s1-select"> 1 star </label>
</div>
</div>
</fieldset>
</fieldset>
<button type="submit" id="save-btn" value="Submit">Save Review</button>
</form>
</body>
<fieldset>
<legend>COMMENTS:</legend>
<textarea name="comments" id="comments" rows="5" style="resize: none; width: 100%"></textarea>
</fieldset>
<fieldset>
<legend>TAGS: (ex. cuisine, distance, cost, etc)</legend>
<input type="text" id="tag-form" name="tag-form" />
<div class="tag-container" id="tag-container-form"></div>
<button type="button" id="tag-add-btn">+</button>
</fieldset>
<button type="submit" id="save-btn" value="Submit">Save</button>
<!-- Button that allows user to go back to the homepage -->
<input type="button" value="Cancel" id="home-btn" onclick="window.location.assign('./index.html')" />
</form>
</div>
</body>
</html>

View File

@@ -1,78 +1,144 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Food Journal</title>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Food Journal</title>
<!-- Recipe Card Custom Element -->
<script src="assets/scripts/ReviewCard.js" type="module"></script>
<!--Add Favicon-->
<link rel="icon" type="image/x-icon" href="./assets/images/favicon.ico" />
<!-- Review Card Custom Element -->
<script src="assets/scripts/ReviewCard.js" type="module"></script>
<!-- Main Stylesheets & Scripts -->
<!-- Temporarily commented out reset.css due to furthur discussion needed on the values of the default config-->
<!-- <link rel="stylesheet" href="/static/reset.css" /> -->
<link rel="stylesheet" href="./static/ReviewCard.css" />
<script src="assets/scripts/ReviewDetails.js" type="module"></script>
<!-- Main Stylesheets & Scripts -->
<link rel="stylesheet" href="./static/ReviewDetails.css" />
<link rel="stylesheet" href="./static/Form.css" />
<script src="assets/scripts/ReviewDetails.js" type="module"></script>
</head>
<body>
<header>
<div class="top-bar">
<img src="./assets/images/Logo.png" alt="logo" />
<h1>My Meal Journal</h1>
<img src="./assets/images/Logo.png" alt="logo" />
</div>
</header>
</head>
<body>
<main>
<input type="button" value="Home" id="home-btn" onclick="window.location.assign('./index.html')">
<button type="button" id="update-btn">Update</button>
<button type="button" id="delete-btn" class="danger">Delete</button>
</main>
<!----> <form id="update-food-entry" class="hidden">
<fieldset>
<legend>Pic:</legend>
<label for="mealImage">
Source:
<input type="text" id="mealImg" name="mealImg">
</label>
<label for="image-alt">
Alt Text:
<input type="text" id="imgAlt" name="imgAlt">
</label>
</fieldset>
<fieldset>
<main>
<div class="journal-form" id="review-details">
<form>
<fieldset class="meal-name">
<h1 id="d-meal-name" style="font-family: Century Gothic"></h1>
<h1 id="d-restaurant" style="font-family: Century Gothic; font-size: 30px"></h1>
</fieldset>
<legend> Meal: </legend>
<label for="Meal: ">Meal:
<input type="text" id="mealName" name="mealName" required>
</label>
<label for="comments">Comments:
<br>
<textarea name="comments" id="comments"></textarea>
</label>
</fieldset>
<fieldset class="meal-pics">
<!-- image source -->
<img width="40%" height="40%" id="d-meal-img" style="margin-left: auto; margin-right: auto; display: block" />
</fieldset>
<fieldset class="rating">
<legend> Rating: </legend>
<input type="radio" id="s5" name="rating" value="5"/> <label for="s5"> 5 stars </label>
<input type="radio" id="s4" name="rating" value="4"/> <label for="s4"> 4 stars </label>
<input type="radio" id="s3" name="rating" value="3"/> <label for="s3"> 3 stars </label>
<input type="radio" id="s2" name="rating" value="2"/> <label for="s2"> 2 stars </label>
<input type="radio" id="s1" name="rating" value="1"/> <label for="s1"> 1 star </label>
</fieldset>
<fieldset class="stars-and-comments" style="text-align: center">
<img width="30%" height="30%" id="d-rating" style="margin-left: auto; margin-right: auto; display: block" />
<p id="d-comments"></p>
</fieldset>
<fieldset>
<legend>Other Info:</legend>
<label for="restaurant">
Restaurant:
<input type="text" id="restaurant" name="restaurant" required>
</label>
<label for="tag-form">
Tags:
<input type="text" id="tag-form" name="tag-form">
<div class='tag-container' id="tag-container-form">
<fieldset class="meal-tags">
<div class="tag-container" id="d-tags" style="justify-content: center"></div>
</fieldset>
</form>
</div>
</div>
<button type="button" id="tag-add-btn">Add Tag</button>
</label>
<!---Navigation Buttons-->
<div style="display: flex; justify-content: center">
<img
src="./assets/images/home_button_for_interface.png"
style="margin: 20px 10px 20px 10px"
id="home-btn"
title="Home Page"
onclick="window.location.assign('./index.html')"
height="50"
width="50"
/>
<img
src="./assets/images/edit_button_for_interface.png"
style="margin: 20px 10px 20px 10px"
id="update-btn"
title="Edit Review"
height="50"
width="50"
/>
<img
src="./assets/images/delete_icon_for_interface.png"
style="margin: 20px 10px 20px 10px"
id="delete-btn"
title="Delete Review"
class="danger"
height="50"
width="50"
/>
</div>
</main>
</fieldset>
<button type="submit" value="Submit">Add Review</button>
</form>
</body>
<div class="journal-form hidden" id="update-form">
<h1>Update Entry</h1>
<form id="new-food-entry">
<fieldset>
<legend>PICTURE:</legend>
<select id="select" name="select">
<option value="file">File Upload</option>
<option value="photo">Take a Photo</option>
</select>
<input type="file" accept="image/*" id="mealImg" name="mealImg" />
</fieldset>
<fieldset>
<video id="player" width="320" height="240" autoplay hidden></video>
<canvas id="photoCanvas" width="320" height="240" hidden></canvas>
<button type="button" id="photoButton" hidden>Take Photo</button>
</fieldset>
<fieldset>
<legend>MEAL NAME:</legend>
<label for="Name: "> <input type="text" id="mealName" name="mealName" required /> </label>
</fieldset>
<fieldset>
<legend>RESTAURANT NAME:</legend>
<label for="Name:"> <input type="text" id="restaurant" name="restaurant" required /> </label>
</fieldset>
<fieldset>
<legend>RATING:</legend>
<div style="display: flex; justify-content: flex-start; align-items: center">
<div class="rating">
<input type="radio" id="s5" name="rating" value="5" /> <label for="s5" id="s5-select"> 5 stars </label>
<input type="radio" id="s4" name="rating" value="4" /> <label for="s4" id="s4-select"> 4 stars </label>
<input type="radio" id="s3" name="rating" value="3" /> <label for="s3" id="s3-select"> 3 stars </label>
<input type="radio" id="s2" name="rating" value="2" /> <label for="s2" id="s2-select"> 2 stars </label>
<input type="radio" id="s1" name="rating" value="1" /> <label for="s1" id="s1-select"> 1 star </label>
</div>
</div>
</fieldset>
<fieldset>
<legend>COMMENTS:</legend>
<textarea name="comments" id="comments" rows="5" style="resize: none; width: 100%"></textarea>
</fieldset>
<fieldset>
<legend>TAGS: (ex. cuisine, distance, cost, etc)</legend>
<input type="text" id="tag-form" name="tag-form" />
<div class="tag-container" id="tag-container-form"></div>
<button type="button" id="tag-add-btn">+</button>
</fieldset>
<button type="submit" id="save-btn" value="Submit">Save</button>
<input type="button" value="Cancel" id="cancel-btn" />
</form>
</div>
</body>
</html>

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.6 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 350 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 311 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 129 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 253 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 KiB

View File

@@ -1,78 +1,173 @@
import { newReviewToStorage } from "./localStorage.js";
window.addEventListener("DOMContentLoaded", init);
/**
* Delegates the functionality for creating review cards.
*/
function init() {
// get next id
// creates the key
initFormHandler();
initFormHandler();
}
/**
* Creates a form and associates a new ID with the new review card.
*/
function initFormHandler() {
//accessing form components
// Accesses form components
let tagContainer = document.getElementById("tag-container-form");
let form = document.querySelector("form");
form.addEventListener("submit", function(e){
/*
* User submits the form for their review.
* We create reviewCard and put in storage
*/
// Declaring variable storing image data url
let imgDataURL = "";
// Accessing components related to taking photo
let videoMode = true;
let player = document.getElementById("player");
let canvas = document.getElementById("photoCanvas");
let photoButton = document.getElementById("photoButton");
let context = canvas.getContext("2d");
// Event listener for the photo taking/reset button
photoButton.addEventListener("click", () => {
// capturing the current video frame
if (videoMode) {
videoMode = false;
// setting up the appropriate components for displaying the photo preview
photoButton.innerText = "Retake";
player.setAttribute("hidden", "");
canvas.removeAttribute("hidden", "");
// displaying the captured snapshot on a canvas and saving it as a data url
context.drawImage(player, 0, 0, canvas.width, canvas.height);
imgDataURL = canvas.toDataURL();
}
// returning to displaying the video stream
else {
videoMode = true;
// setting up the appropriate components for the video stream
photoButton.innerText = "Take Photo";
canvas.setAttribute("hidden", "");
player.removeAttribute("hidden", "");
}
});
// Event listener for reading image form different data
let select = document.getElementById("select");
const input = document.getElementById("mealImg");
select.addEventListener("change", function () {
// Select a photo with HTML file selector
if (select.value == "file") {
// enabling file upload components and hiding photo taking components
input.removeAttribute("hidden", "");
player.setAttribute("hidden", "");
canvas.setAttribute("hidden", "");
photoButton.setAttribute("hidden", "");
// stopping the video stream
player.srcObject.getVideoTracks()[0].stop();
}
// Take a photo
else {
// enabling photo taking components and hiding file upload components
videoMode = true;
photoButton.innerText = "Take Photo";
input.setAttribute("hidden", "");
player.removeAttribute("hidden", "");
photoButton.removeAttribute("hidden", "");
// getting video stream from user's camera then displaying it on a video element
navigator.mediaDevices.getUserMedia({ video: true }).then((stream) => {
player.srcObject = stream;
});
}
});
// Addresses sourcing image from local file
document.getElementById("mealImg").addEventListener("change", function () {
const reader = new FileReader();
// Store image data URL after successful image load
reader.addEventListener(
"load",
() => {
imgDataURL = reader.result;
},
false
);
// Convert image file into data URL for local storage
reader.readAsDataURL(document.getElementById("mealImg").files[0]);
});
form.addEventListener("submit", function (e) {
// Create reviewObject and put in storage
e.preventDefault();
let formData = new FormData(form);
let reviewObject = {};
// Adds data to the reviewObject from form data
for (let [key, value] of formData) {
console.log(`${key}`);
console.log(`${value}`);
if (`${key}` !== "tag-form") {
reviewObject[`${key}`] = `${value}`;
}
}
reviewObject["tags"] = [];
let tags = document.querySelectorAll(".tag");
for(let i = 0; i < tags.length; i ++) {
reviewObject["tags"].push(tags[i].innerHTML);
tagContainer.removeChild(tags[i]);
if (`${key}` === "mealImg" && imgDataURL !== "") {
reviewObject["mealImg"] = imgDataURL;
}
}
//grabbing the nextID, and putting our review object in storage associated with the ID
let nextReviewId = JSON.parse(localStorage.getItem("nextID"));
reviewObject["reviewID"] = nextReviewId;
// Makes sure that ratings is filled
if (reviewObject["rating"] != null) {
//Adds rags separately as an array
reviewObject["tags"] = [];
localStorage.setItem("review"+nextReviewId, JSON.stringify(reviewObject));
sessionStorage.setItem("currID", JSON.stringify(nextReviewId));
// Grabs tags
let tags = document.querySelectorAll(".tag");
for (let i = 0; i < tags.length; i++) {
reviewObject["tags"].push(tags[i].innerHTML);
tagContainer.removeChild(tags[i]);
}
//updating our activeIDS list
let tempIdArr = JSON.parse(localStorage.getItem("activeIDS"));
tempIdArr.push(nextReviewId);
localStorage.setItem("activeIDS", JSON.stringify(tempIdArr));
//increment nextID for next review creation
nextReviewId++;
localStorage.setItem("nextID", JSON.stringify(nextReviewId));
window.location.assign('./ReviewDetails.html');
// Assigns the new review with a new ID
let nextReviewId = newReviewToStorage(reviewObject);
sessionStorage.setItem("currID", JSON.stringify(nextReviewId));
// Redirects to a page that shows the newly created review
window.location.assign("./ReviewDetails.html");
}
// Does not let user proceed if rating is not complete
else {
window.alert("Please fill in rating by selecting the stars :)");
}
});
let tagAddBtn = document.getElementById("tagAdd");
tagAddBtn.addEventListener("click", ()=> {
// Event listener for tag functionality
let tagAddBtn = document.getElementById("tag-add-btn");
//Set used to track tags and ensure no duplicates
let tagSet = new Set();
tagAddBtn.addEventListener("click", () => {
let tagField = document.getElementById("tag-form");
// If there is a tag, it'll display the tag
if (tagField.value.length > 0) {
let tagLabel = document.createElement("label");
tagLabel.innerHTML = tagField.value;
tagLabel.setAttribute("class","tag");
tagLabel.addEventListener("click",()=> {
tagContainer.removeChild(tagLabel);
});
let tagSetVal = tagField.value.toLocaleLowerCase();
if (!tagSet.has(tagSetVal)) {
let tagLabel = document.createElement("label");
tagLabel.innerHTML = tagField.value;
tagLabel.setAttribute("class", "tag");
tagSet.add(tagSetVal);
tagLabel.addEventListener("click", () => {
tagContainer.removeChild(tagLabel);
tagSet.delete(tagSetVal);
});
tagContainer.append(tagLabel);
tagContainer.append(tagLabel);
} else {
window.alert("No duplicate tags allowed");
}
tagField.value = "";
}
});
}

View File

@@ -6,124 +6,135 @@ class ReviewCard extends HTMLElement {
constructor() {
super();
let shadowEl = this.attachShadow({mode:"open"});
let shadowEl = this.attachShadow({ mode: "open" });
let articleEl = document.createElement("article");
let styleEl = document.createElement("style");
styleEl.textContent = `
* {
font-family: sans-serif;
margin: 0;
padding: 0;
}
* {
font-family: Century Gothic;
margin: 0;
padding: 0;
cursor: pointer;
}
a {
text-decoration: none;
}
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:hover {
text-decoration: underline;
}
article {
align-items: center;
border: 1px solid rgb(223, 225, 229);
border-radius: 8px;
display: grid;
grid-template-rows: 118px 56px 14px 18px 15px 36px;
height: auto;
row-gap: 5px;
padding: 0 16px 16px 16px;
width: 178px;
}
article {
align-items: center;
border: 2px solid rgb(31, 41, 32);
border-radius: 8px;
height: auto;
row-gap: 5px;
padding: 0 16px 16px 16px;
width: 200px;
margin: 8px 8px 8px 8px;
}
div.rating {
align-items: center;
column-gap: 5px;
display: flex;
}
div.rating {
align-items: center;
display: flex;
}
div.rating>img {
height: auto;
display: inline-block;
object-fit: scale-down;
width: 78px;
}
div.rating>img {
height: auto;
display: inline-block;
object-fit: scale-down;
}
article>img {
border-top-left-radius: 8px;
border-top-right-radius: 8px;
height: 118px;
object-fit: cover;
margin-left: -16px;
width: calc(100% + 32px);
}
article>img {
border-top-left-radius: 6px;
border-top-right-radius: 6px;
height: 120px;
object-fit: cover;
margin-left: -16px;
margin-right: -16px;
width: calc(100% + 32px);
}
label.restaurant-name {
color: black !important;
}
.meal-name-div {
height: 54px;
overflow: hidden;
}
label.meal-name {
display: -webkit-box;
font-size: 16px;
height: 36px;
line-height: 18px;
overflow: hidden;
-webkit-line-clamp: 2;
-webkit-box-orient: vertical;
}
label.restaurant-name {
color: black !important;
}
label:not(.meal-name),
span,
time {
color: #70757A;
font-size: 12px;
}
`;
label.meal-name {
font-size: 24px;
height: 36px;
}
label:not(.meal-name),
span,
time {
color: #70757A;
font-size: 12px;
}
.tag-container-div {
margin-top: 20px;
height: 100px;
overflow: hidden;
}
.tag-container {
display: flex;
flex-flow: row wrap;
height: fit-content;
}
.a-tag {
background-color:#94da97;
border-radius: 6px;
color: #94da97;
padding: 0px 6px 2px 6px;
margin: 2px 2px 2px 2px;
font-weight: bold;
overflow: hidden;
height: 14px;
}
`;
articleEl.append(styleEl);
shadowEl.append(articleEl);
this.shadowEl = shadowEl;
//attach event listener to each recipe-card
// Attach event listener to each review-card
this.addEventListener("click", (event) => {
console.log(event.target);
console.log(event.target.reviewId);
//Option 1: sending current data to second html page using localStorage (could also just store index)
// Saves the ID for corresponding review on new page (for data retrieval)
sessionStorage.setItem("currID", JSON.stringify(event.target.data.reviewID));
// Goes to the new page for the review
window.location.assign("./ReviewDetails.html");
/*
//Option 2: sending current data to second html page using string query w/ url (currently not storing value)
let reviewFields = window.location.search.slice(1).split("&");
for(let i = 0; i < reviewFields.length; i++) {
let kv = reviewFields[i].split("=");
let key = kv[0];
let value = kv[1];
console.log(key);
console.log(value);
// What you want to do with name and value...
}*/
});
}
/**
* Called when the .data property is set on this element.
*
* For Example:
* let reviewCard = document.createElement('review-card');
* reviewCard.data = { foo: 'bar' }
*
* @param {Object} data - The data to pass into the <review-card>, must be of the
* following format:
* {
* "mealImg": "string",
* "imgAlt": "string",
* "mealName": "string",
* "comments": "string",
* "rating": number,
* "restaurant": "string",
* "tags": string array
* }
*/
* Called when the .data property is set on this element.
*
* For Example:
* let reviewCard = document.createElement('review-card');
* reviewCard.data = { foo: 'bar' }
*
* @param {Object} data - The data to pass into the <review-card>, must be of the
* following format:
* {
* "mealImg": string,
* "mealName": string,
* "comments": string,
* "rating": number,
* "restaurant": string,
* "reviewID": number,
* "tags": string array
* }
*/
set data(data) {
// If nothing was passed in, return
if (!data) return;
@@ -131,123 +142,124 @@ class ReviewCard extends HTMLElement {
// Select the <article> we added to the Shadow DOM in the constructor
let articleEl = this.shadowEl.querySelector("article");
// setting the article elements for the review card
this.reviewID = data["reviewID"];
// Setting the article elements for the review card
this.reviewID = data["reviewID"];
//image setup
// Image setup
let mealImg = document.createElement("img");
mealImg.setAttribute("id", "a-mealImg");
mealImg.setAttribute("alt",data["imgAlt"]);
if(data["mealImg"] != ""){
mealImg.setAttribute("src",data["mealImg"]);
}
else{
mealImg.setAttribute("src", "./assets/images/icons/plate_with_cutlery.png");
}
mealImg.setAttribute("id", "a-meal-img");
mealImg.setAttribute("alt", "Meal Photo Corrupted");
mealImg.setAttribute("src", data["mealImg"]);
mealImg.addEventListener("error", function (e) {
mealImg.setAttribute("src", "./assets/images/default_plate.png");
e.onerror = null;
});
//meal name setup
// Meal name setup
let meallabelDiv = document.createElement("div");
meallabelDiv.setAttribute("class", "meal-name-div");
let mealLabel = document.createElement("label");
mealLabel.setAttribute("id", "a-mealName");
mealLabel.setAttribute("class","meal-name");
mealLabel.setAttribute("id", "a-meal-name");
mealLabel.setAttribute("class", "meal-name");
mealLabel.innerHTML = data["mealName"];
meallabelDiv.append(mealLabel);
//restaurant name setup
// Restaurant name setup
let restaurantLabel = document.createElement("label");
restaurantLabel.setAttribute("id", "a-restaurant");
restaurantLabel.setAttribute("class","restaurant-name");
restaurantLabel.setAttribute("class", "restaurant-name");
restaurantLabel.innerHTML = data["restaurant"];
//comment section setup (display set to none)
// Comment section setup (display set to none)
let comments = document.createElement("p");
comments.setAttribute("id", "a-comments");
comments.style.display = "none";
comments.innerText = data["comments"];
//other info: rating
// Rating setup
let ratingDiv = document.createElement("div");
ratingDiv.setAttribute("class", "rating");
let starsImg = document.createElement("img");
starsImg.setAttribute("id", "a-rating");
starsImg.setAttribute("src", "./assets/images/icons/"+data["rating"]+"-star.svg");
starsImg.setAttribute("alt", data["rating"] +" stars");
starsImg.setAttribute("src", "./assets/images/" + data["rating"] + "-star.svg");
starsImg.setAttribute("alt", data["rating"] + " stars");
starsImg.setAttribute("num", data["rating"]);
ratingDiv.append(starsImg);
//added tags
// Tags setup
let tagContainerDiv = document.createElement("div");
tagContainerDiv.setAttribute("class", "tag-container-div");
let tagContainer = document.createElement("div");
tagContainer.setAttribute("class", "tag-container");
tagContainer.setAttribute("id", "a-tags");
tagContainer.setAttribute("list", data["tags"]);
if(data["tags"]){
// Checks if user gave tags, if so added to review card
if (data["tags"]) {
for (let i = 0; i < data["tags"].length; i++) {
let newTag = document.createElement("label");
newTag.setAttribute("class","tag");
newTag.setAttribute("class", "a-tag");
newTag.innerHTML = data["tags"][i];
tagContainer.append(newTag);
}
}
tagContainerDiv.append(tagContainer);
//adding final ID to data!
// Setting all the data to the review card
articleEl.append(mealImg);
articleEl.append(mealLabel);
articleEl.append(meallabelDiv);
articleEl.append(restaurantLabel);
articleEl.append(ratingDiv);
articleEl.append(tagContainer);
articleEl.append(tagContainerDiv);
articleEl.append(comments);
}
/**
* Called when getting the .data property of this element.
*
* For Example:
* let reviewCard = document.createElement('review-card');
* reviewCard.data = { foo: 'bar' }
*
* @return {Object} data - The data from the <review-card>, of the
* following format:
* {
* "mealImg": "string",
* "imgAlt": "string",
* "mealName": "string",
* "comments": "string",
* "rating": number,
* "restaurant": "string",
* "tags": string array
* }
*/
* Called when getting the .data property of this element.
*
* For Example:
* let reviewCard = document.createElement('review-card');
* reviewCard.data = { foo: 'bar' }
*
* @return {Object} data - The data from the <review-card>, of the
* following format:
* {
* "mealImg": string,
* "mealName": string,
* "comments": string,
* "rating": number,
* "restaurant": string,
* "reviewID": number,
* "tags": string array
* }
*/
get data() {
let dataContainer = {};
// getting the article elements for the review card
dataContainer["reviewID"] = this.reviewID;
// Getting the article elements for the review card
dataContainer["reviewID"] = this.reviewID;
//get image
let mealImg = this.shadowEl.getElementById("a-mealImg");
let mealImg = this.shadowEl.getElementById("a-meal-img");
dataContainer["mealImg"] = mealImg.getAttribute("src");
dataContainer["imgAlt"] = mealImg.getAttribute("alt");
//get meal name
let mealLabel = this.shadowEl.getElementById("a-mealName");
let mealLabel = this.shadowEl.getElementById("a-meal-name");
dataContainer["mealName"] = mealLabel.innerHTML;
//get comment section
// Get comment section
let comments = this.shadowEl.getElementById("a-comments");
console.log(comments);
dataContainer["comments"] = comments.innerText;
//get other info: rating
// Get rating
let starsImg = this.shadowEl.getElementById("a-rating");
dataContainer["rating"] = starsImg.getAttribute("num");
//get restaurant name
//Get restaurant name
let restaurantLabel = this.shadowEl.getElementById("a-restaurant");
dataContainer["restaurant"] = restaurantLabel.innerHTML;
//get tags
// Get tags
let tagContainer = this.shadowEl.getElementById("a-tags");
dataContainer["tags"] = tagContainer.getAttribute("list").split(",");

View File

@@ -1,114 +1,274 @@
//reviewDetails.js
import {getReviewsFromStorage, saveReviewsToStorage} from "./localStorage.js";
import { deleteReviewFromStorage, getReviewFromStorage, updateReviewToStorage } from "./localStorage.js";
// Run the init() function when the page has loaded
window.addEventListener("DOMContentLoaded", init);
function init(){
/**
* Populates the relevant data to the details from local storage review.
*/
function init() {
setupInfo();
setupDelete();
setupUpdate();
}
function setupDelete(){
/**
* Populates the relevant data to the details from local storage review
*/
function setupInfo() {
let currID = JSON.parse(sessionStorage.getItem("currID"));
let currReview = getReviewFromStorage(currID);
//meal image
let mealImg = document.getElementById("d-meal-img");
mealImg.setAttribute("src", currReview["mealImg"]);
mealImg.addEventListener("error", function (e) {
mealImg.setAttribute("src", "./assets/images/default_plate.png");
e.onerror = null;
});
//meal name
let mealLabel = document.getElementById("d-meal-name");
mealLabel.innerHTML = currReview["mealName"];
//restaurant name
let restaurantLabel = document.getElementById("d-restaurant");
restaurantLabel.innerHTML = currReview["restaurant"];
//comments
let comments = document.getElementById("d-comments");
comments.innerText = currReview["comments"];
//rating
let starsImg = document.getElementById("d-rating");
starsImg.setAttribute("src", "./assets/images/" + currReview["rating"] + "-star.svg");
starsImg.setAttribute("alt", currReview["rating"] + " stars");
//tags
let tagContainer = document.getElementById("d-tags");
if (currReview["tags"]) {
for (let i = 0; i < currReview["tags"].length; i++) {
let newTag = document.createElement("label");
newTag.setAttribute("class", "d-tag");
newTag.innerHTML = currReview["tags"][i];
tagContainer.append(newTag);
}
}
}
/**
* Sets up delete button to delete reveiw from storage and switch to homepage.
*/
function setupDelete() {
let deleteBtn = document.getElementById("delete-btn");
let currID = JSON.parse(sessionStorage.getItem("currID"));
let activeIDS = JSON.parse(localStorage.getItem("activeIDS"));
deleteBtn.addEventListener("click", function(){
if(window.confirm("Are you sure you want to delete this entry?")){
for (let i in activeIDS) {
if (activeIDS[i] == currID) {
activeIDS.splice(i,1);
localStorage.setItem('activeIDS', JSON.stringify(activeIDS));
sessionStorage.removeItem('currID');
localStorage.removeItem(`review${currID}`);
window.location.assign("./index.html");
break;
}
}
deleteBtn.addEventListener("click", function () {
if (window.confirm("Are you sure you want to delete this entry?")) {
deleteReviewFromStorage(currID);
sessionStorage.removeItem("currID");
window.location.assign("./index.html");
}
});
}
function setupUpdate(){
/**
* Sets up update button to reveal form and update info in storage and the current page.
*/
function setupUpdate() {
let updateBtn = document.getElementById("update-btn");
let currID = JSON.parse(sessionStorage.getItem("currID"));
let currReview = JSON.parse(localStorage.getItem(`review${currID}`));
let form = document.getElementById("update-food-entry");
updateBtn.addEventListener("click", function(){
let currReview = getReviewFromStorage(currID);
let form = document.getElementById("new-food-entry");
let updateDiv = document.getElementById("update-form");
updateBtn.addEventListener("click", function () {
//update function
if(currReview){
form.style.display = "block";
let tagContainer = document.getElementById("tag-container-form");
//Set value of each input element to current's values
document.getElementById("mealImg").defaultValue = currReview["mealImg"];
document.getElementById("imgAlt").defaultValue = currReview["imgAlt"];
document.getElementById("mealName").defaultValue = currReview["mealName"];
document.getElementById("comments").textContent = currReview["comments"];
document.getElementById("s" + `${currReview["rating"]}`).checked = true;
document.getElementById("restaurant").defaultValue = currReview["restaurant"];
updateDiv.classList.remove("hidden");
if(currReview["tags"]){
while (tagContainer.firstChild) {
tagContainer.removeChild(tagContainer.firstChild);
let tagContainer = document.getElementById("tag-container-form");
//Set value of each input element to current's values
document.getElementById("mealImg").defaultValue = currReview["mealImg"];
document.getElementById("mealName").defaultValue = currReview["mealName"];
document.getElementById("comments").textContent = currReview["comments"];
document.getElementById("s" + `${currReview["rating"]}`).checked = true;
document.getElementById("restaurant").defaultValue = currReview["restaurant"];
//Set used to track tags and ensure no duplicates
let tagSet = new Set();
if (currReview["tags"]) {
while (tagContainer.firstChild) {
tagContainer.removeChild(tagContainer.firstChild);
}
let tagSetVal;
for (let i = 0; i < currReview["tags"].length; i++) {
tagSetVal = currReview["tags"][i].toLocaleLowerCase();
tagSet.add(tagSetVal);
let newTag = document.createElement("label");
newTag.setAttribute("class", "tag");
newTag.innerHTML = currReview["tags"][i];
newTag.addEventListener("click", () => {
tagContainer.removeChild(newTag);
tagSet.delete(tagSetVal);
});
tagContainer.append(newTag);
}
}
// Declaring variable storing image data url
let imgDataURL = "";
// Accessing components related to taking photo
let videoMode = true;
let player = document.getElementById("player");
let canvas = document.getElementById("photoCanvas");
let photoButton = document.getElementById("photoButton");
let context = canvas.getContext("2d");
// Event listener for the photo taking/reset button
photoButton.addEventListener("click", () => {
// capturing the current video frame
if (videoMode) {
videoMode = false;
// setting up the appropriate components for displaying the photo preview
photoButton.innerText = "Retake";
player.setAttribute("hidden", "");
canvas.removeAttribute("hidden", "");
// displaying the captured snapshot on a canvas and saving it as a data url
context.drawImage(player, 0, 0, canvas.width, canvas.height);
imgDataURL = canvas.toDataURL();
}
// returning to displaying the video stream
else {
videoMode = true;
// setting up the appropriate components for the video stream
photoButton.innerText = "Take Photo";
canvas.setAttribute("hidden", "");
player.removeAttribute("hidden", "");
}
});
/*
* change the input source of the image between local file and taking photo
* depending on user's selection
*/
let select = document.getElementById("select");
const input = document.getElementById("mealImg");
select.addEventListener("change", function () {
// Select a photo with HTML file selector
if (select.value == "file") {
// enabling file upload components and hiding photo taking components
input.removeAttribute("hidden", "");
player.setAttribute("hidden", "");
canvas.setAttribute("hidden", "");
photoButton.setAttribute("hidden", "");
// stopping the video stream
player.srcObject.getVideoTracks()[0].stop();
}
// Take a photo
else {
// enabling photo taking components and hiding file upload components
videoMode = true;
photoButton.innerText = "Take Photo";
input.setAttribute("hidden", "");
player.removeAttribute("hidden", "");
photoButton.removeAttribute("hidden", "");
// getting video stream from user's camera then displaying it on a video element
navigator.mediaDevices.getUserMedia({ video: true }).then((stream) => {
player.srcObject = stream;
});
}
});
//addressing sourcing image from local file
document.getElementById("mealImg").addEventListener("change", function () {
const reader = new FileReader();
//store image data URL after successful image load
reader.addEventListener(
"load",
() => {
imgDataURL = reader.result;
},
false
);
//convert image file into data URL for local storage
reader.readAsDataURL(document.getElementById("mealImg").files[0]);
});
//cancel button on update form hids form not making any changes
let cancelBtn = document.getElementById("cancel-btn");
cancelBtn.addEventListener("click", function () {
updateDiv.classList.add("hidden");
});
//Take form data values as newData when submit
form.addEventListener("submit", function () {
/*
* User submits the form for their review.
* We create reviewCard data, replace in storage, and update tags
*/
let formData = new FormData(form);
let newData = {};
//iterate through formData and add to newData
for (let [key, value] of formData) {
if (`${key}` !== "tag-form") {
newData[`${key}`] = `${value}`;
}
for (let i = 0; i < currReview["tags"].length; i++) {
let newTag = document.createElement("label");
newTag.setAttribute("class","tag");
newTag.innerHTML = currReview["tags"][i];
newTag.addEventListener("click",()=> {
tagContainer.removeChild(newTag);
});
tagContainer.append(newTag);
// Account for the case where image is not updated
if (`${key}` === "mealImg" && imgDataURL === "") {
newData["mealImg"] = currReview["mealImg"];
} else if (`${key}` === "mealImg") {
newData["mealImg"] = imgDataURL;
}
}
//Take formdata values as newData when submit
form.addEventListener("submit", function(){
/*
* User submits the form for their review.
* We create reviewCard and put in storage
*/
let formData = new FormData(form);
let newData = {};
for (let [key, value] of formData) {
console.log(`${key}`);
console.log(`${value}`);
if (`${key}` !== "tag-form") {
newData[`${key}`] = `${value}`;
}
}
newData["tags"] = [];
newData["tags"] = [];
let tags = document.querySelectorAll(".tag");
for(let i = 0; i < tags.length; i ++) {
newData["tags"].push(tags[i].innerHTML);
tagContainer.removeChild(tags[i]);
}
let tags = document.querySelectorAll(".tag");
for (let i = 0; i < tags.length; i++) {
newData["tags"].push(tags[i].innerHTML);
tagContainer.removeChild(tags[i]);
}
newData["reviewID"] = currID;
newData["reviewID"] = currID;
updateReviewToStorage(currID, newData);
localStorage.setItem("review"+currID, JSON.stringify(newData));
updateDiv.classList.add("hidden");
});
form.style.display = "none";
});
let tagAddBtn = document.getElementById("tag-add-btn");
tagAddBtn.addEventListener("click", ()=> {
let tagField = document.getElementById("tag-form");
if (tagField.value.length > 0) {
// Adding tag to form functionality
let tagAddBtn = document.getElementById("tag-add-btn");
tagAddBtn.addEventListener("click", () => {
let tagField = document.getElementById("tag-form");
if (tagField.value.length > 0) {
let tagSetVal = tagField.value.toLocaleLowerCase();
if (!tagSet.has(tagSetVal)) {
let tagLabel = document.createElement("label");
tagLabel.innerHTML = tagField.value;
tagLabel.setAttribute("class","tag");
tagLabel.addEventListener("click",()=> {
tagLabel.setAttribute("class", "tag");
tagSet.add(tagSetVal);
tagLabel.addEventListener("click", () => {
tagContainer.removeChild(tagLabel);
tagSet.delete(tagSetVal);
});
tagContainer.append(tagLabel);
tagField.value = "";
} else {
window.alert("No duplicate tags allowed");
}
});
}
tagField.value = "";
}
});
});
}

View File

@@ -1,13 +0,0 @@
// Run the init() function when the page has loaded
window.addEventListener("DOMContentLoaded", init);
function init() {
let result = sessionStorage.getItem("currReview");
let main = document.querySelector("main");
main.innerHTML = result;
let p = document.createElement("p");
p.innerHTML = JSON.parse(result)["comments"];
main.append(p);
}

View File

@@ -0,0 +1,72 @@
import { strict as assert } from "node:assert";
/**
* Fills out a create or update review form
* @param {Object} page the page object which contains the create or update form
* @param {Object} review review data to input into the form
*/
export async function setReviewForm(page, review) {
// Set text fields
await page.$eval("#mealName", (el, value) => (el.value = value), review.mealName);
await page.$eval("#comments", (el, value) => (el.value = value), review.comments);
await page.$eval("#restaurant", (el, value) => (el.value = value), review.restaurant);
// Get all tag elements and click them to delete them
let tag_items = await page.$$(".tag");
if (tag_items !== null) {
for (let i = 0; i < tag_items.length; i++) {
await tag_items[i].click();
}
}
// Get the button needed to add new tags
let tag_btn = await page.$("#tag-add-btn");
for (let i = 0; i < review.tags.length; i++) {
await page.$eval("#tag-form", (el, value) => (el.value = value), review.tags[i]);
await tag_btn.click();
}
// Select a new rating
let rating_select = await page.$(`#s${review.rating}-select`);
await rating_select.click({ delay: 100 });
}
/**
* Tests a page or shadowDOM for correct element text or src values
* @param {Object} root page or shodowDOM to test
* @param {string} prefix prefix character for element IDs
* @param {Object} expected values for each element
*/
export async function checkCorrectness(root, prefix, expected) {
// Get the review image and check src
let img = await root.$(`#${prefix}-meal-img`);
let imgSrc = await img.getProperty("src");
// Check src
assert.strictEqual(await imgSrc.jsonValue(), expected.imgSrc);
// Get the title, comment, and restaurant
let title = await root.$(`#${prefix}-meal-name`);
let title_text = await title.getProperty("innerText");
let comment = await root.$(`#${prefix}-comments`);
let comment_text = await comment.getProperty("innerText");
let restaurant = await root.$(`#${prefix}-restaurant`);
let restaurant_text = await restaurant.getProperty("innerText");
// Check title, comment, and restaurant
assert.strictEqual(await title_text.jsonValue(), expected.mealName);
assert.strictEqual(await comment_text.jsonValue(), expected.comments);
assert.strictEqual(await restaurant_text.jsonValue(), expected.restaurant);
// Check tags
let tags = await root.$$(`.${prefix}-tag`);
assert.strictEqual(await tags.length, expected.tags.length);
for (let i = 0; i < expected.tags.length; i++) {
let tag_text = await tags[i].getProperty("innerText");
assert.strictEqual(await tag_text.jsonValue(), expected.tags[i]);
}
// Check stars
let stars = await root.$(`#${prefix}-rating`);
let stars_src = await stars.getProperty("src");
assert.strictEqual(await stars_src.jsonValue(), expected.rating);
}

View File

@@ -0,0 +1,156 @@
// homepage.js
import { getIDsByTag, getIDsFromStorage, getReviewFromStorage, getTopIDsFromStorage } from "./localStorage.js";
// Run the init() function when the page has loaded
window.addEventListener("DOMContentLoaded", init);
function init() {
//initial population of review container
sortAndFilter(false, null);
//Add the event listeners to dropdown and search bar
initFormHandler();
}
/**
* @param {Array<Object>} reviews An array of reviews
*/
function addReviewsToDocument(reviews) {
let reviewBox = document.getElementById("review-container");
reviews.forEach((review) => {
let newReview = document.createElement("review-card");
newReview.data = review;
reviewBox.append(newReview);
});
}
/**
* Adds the necessary event handlers to search-btn and sort
*/
function initFormHandler() {
//grabbing search field
let searchField = document.getElementById("search-bar");
let searchBtn = document.getElementById("search-btn");
let searchTag = null;
//adding search functionality
searchBtn.addEventListener("click", function () {
searchTag = searchField.value;
sortAndFilter(searchTag);
});
//for clearing tag filter
let clearSearchBtn = document.getElementById("clear-search");
clearSearchBtn.addEventListener("click", function () {
searchTag = null;
searchField.value = "";
sortAndFilter(searchTag);
});
//sort by selected method
let sortMethod = document.getElementById("sort");
sortMethod.addEventListener("input", function () {
sortAndFilter(searchTag);
});
}
/**
* Deciphers sort and filter to populate the review-container
* @param {string} searchTag tag name to filter by
*/
function sortAndFilter(searchTag) {
let reviewBox = document.getElementById("review-container");
let sortMethod = document.getElementById("sort");
//clear review container
while (reviewBox.firstChild) {
reviewBox.removeChild(reviewBox.firstChild);
}
let reviewIDs = [];
//sort method: most recent
if (sortMethod.value == "recent") {
//tag filtered most recent
if (searchTag) {
reviewIDs = getIDsByTag(searchTag);
}
//most recent
else {
reviewIDs = getIDsFromStorage();
}
//reversed for recency
loadReviews(0, reviewIDs);
}
//sort method: top rated
else if (sortMethod.value == "top") {
//tag filtered top rated
if (searchTag) {
//intersection of top ids list and ids by tag in top ids order
reviewIDs = getTopIDsFromStorage().filter((x) => getIDsByTag(searchTag).includes(x));
}
//top rated
else {
reviewIDs = getTopIDsFromStorage();
}
loadReviews(0, reviewIDs);
}
}
/**
* Populate review-container with 9 more reviews
* @param {number} index review index to begin with
* @param {number[]} reviewIDs ordered array of reviews
*/
function loadReviews(index, reviewIDs) {
let reviewBox = document.getElementById("review-container");
let footer = document.querySelector("footer");
// label if there are no reviews to display
if (reviewIDs.length == 0) {
let emptyLabel = document.createElement("label");
emptyLabel.setAttribute("id", "empty");
emptyLabel.innerText = "No Reviews To Display";
reviewBox.append(emptyLabel);
} else {
let emptyLabel = document.getElementById("empty");
if (emptyLabel) {
reviewBox.removeChild(emptyLabel);
}
}
let moreBtn = document.getElementById("more-btn");
//delete load more button if exists
if (moreBtn) {
footer.removeChild(moreBtn);
}
let reviewArr = [];
//check if there are more than 9 reviews left
if (index + 9 > reviewIDs.length - 1) {
//add remaining reviews to review container
for (let i = index; i < reviewIDs.length; i++) {
reviewArr.push(getReviewFromStorage(reviewIDs[i]));
}
addReviewsToDocument(reviewArr);
} else {
//add 9 more reviews to container
for (let i = index; i < index + 9; i++) {
reviewArr.push(getReviewFromStorage(reviewIDs[i]));
}
addReviewsToDocument(reviewArr);
//create and add load more button
moreBtn = document.createElement("button");
moreBtn.setAttribute("id", "more-btn");
moreBtn.innerText = "Load More";
//if load more clicked, load 9 more
moreBtn.addEventListener("click", function () {
loadReviews(index + 9, reviewIDs);
});
footer.append(moreBtn);
}
}
//setting up service worker
const registerServiceWorker = async () => {
if ("serviceWorker" in navigator) {
try {
await navigator.serviceWorker.register("./sw.js", { scope: "./" });
} catch (error) {
console.error(`Registration failed with ${error}`);
}
}
};
registerServiceWorker();

View File

@@ -1,27 +1,267 @@
/**
* @returns {Array<Object>} An array of reviews found in localStorage
* Creates a new review to storage and performs related meta tasks
* @param {Object} review to store
* @return {number} ID of the newly added review
*/
export function getReviewsFromStorage() {
if (!(localStorage.getItem("activeIDS"))) {
export function newReviewToStorage(review) {
//grabbing the nextID, and putting our review object in storage associated with the ID
let nextReviewId = JSON.parse(localStorage.getItem("nextID"));
review["reviewID"] = nextReviewId;
// set the review entry to the review object
localStorage.setItem(`review${nextReviewId}`, JSON.stringify(review));
// adding to the tag keys
addTagsToStorage(nextReviewId, review["tags"]);
//adding to the star storage
let starArr = JSON.parse(localStorage.getItem(`star${review["rating"]}`));
if (!starArr) {
starArr = [];
}
starArr.push(nextReviewId);
localStorage.setItem(`star${review["rating"]}`, JSON.stringify(starArr));
//updating our activeIDS list
let tempIdArr = JSON.parse(localStorage.getItem("activeIDS"));
tempIdArr.push(nextReviewId);
localStorage.setItem("activeIDS", JSON.stringify(tempIdArr));
//increment nextID for next review creation
localStorage.setItem("nextID", JSON.stringify(nextReviewId + 1));
return nextReviewId;
}
/**
* Gets a single review by ID from storage
* @param {string} ID of the review to get
* @returns {Object} review object corresponding to param ID
*/
export function getReviewFromStorage(ID) {
return JSON.parse(localStorage.getItem(`review${ID}`));
}
/**
* Updates a single review by ID to storage
* @param {string} ID of review to update
* @param {Object} review to store
*/
export function updateReviewToStorage(ID, review) {
let oldReview = JSON.parse(localStorage.getItem(`review${ID}`));
let starArr = JSON.parse(localStorage.getItem(`star${review["rating"]}`));
//activeID update recency
let activeIDS = JSON.parse(localStorage.getItem("activeIDS"));
for (let i in activeIDS) {
if (activeIDS[i] == ID) {
activeIDS.splice(i, 1);
activeIDS.push(ID);
break;
}
}
localStorage.setItem("activeIDS", JSON.stringify(activeIDS));
//star local storage update
if (oldReview["rating"] !== review["rating"]) {
//first delete from previous rating array in storage
let oldStarArr = JSON.parse(localStorage.getItem(`star${oldReview["rating"]}`));
for (let i in oldStarArr) {
if (oldStarArr[i] == ID) {
//removing from corresponding rating array and updating local Storage
oldStarArr.splice(i, 1);
break;
}
}
if (oldStarArr.length != 0) {
localStorage.setItem(`star${oldReview["rating"]}`, JSON.stringify(oldStarArr));
} else {
localStorage.removeItem(`star${oldReview["rating"]}`);
}
//then add ID to array corresponding to new review rating
let newStarArr = starArr;
if (!newStarArr) {
newStarArr = [];
}
newStarArr.push(ID);
localStorage.setItem(`star${review["rating"]}`, JSON.stringify(newStarArr));
} else if (starArr.length !== 1) {
//stars update recency if unchanged
for (let i in starArr) {
if (starArr[i] == ID) {
starArr.splice(i, 1);
starArr.push(ID);
break;
}
}
localStorage.setItem(`star${review["rating"]}`, JSON.stringify(starArr));
}
//specifically the unchanged tags update recency
let repeatedTags = review["tags"].filter((x) => oldReview["tags"].includes(x));
let tagArr = [];
for (let i in repeatedTags) {
tagArr = JSON.parse(localStorage.getItem(`!${repeatedTags[i].toLocaleLowerCase()}`));
if (tagArr.length !== 1) {
for (let j in tagArr) {
if (tagArr[j] == ID) {
tagArr.splice(j, 1);
tagArr.push(ID);
break;
}
}
localStorage.setItem(`!${repeatedTags[i].toLocaleLowerCase()}`, JSON.stringify(tagArr));
}
}
//Get diff of tags and update storage
let deletedTags = oldReview["tags"].filter((x) => !review["tags"].includes(x));
let addedTags = review["tags"].filter((x) => !oldReview["tags"].includes(x));
deleteTagsFromStorage(ID, deletedTags);
addTagsToStorage(ID, addedTags);
// set the review entry with ID to the review object
localStorage.setItem(`review${ID}`, JSON.stringify(review));
}
/**
* Deletes a review by ID from storage
* @param {string} ID of the review to delete
*/
export function deleteReviewFromStorage(ID) {
//removing id number from activeIDS and star{rating}
let activeIDS = JSON.parse(localStorage.getItem("activeIDS"));
let reviewRating = JSON.parse(localStorage.getItem(`review${ID}`))["rating"];
let starArr = JSON.parse(localStorage.getItem(`star${reviewRating}`));
for (let i in starArr) {
if (starArr[i] == ID) {
//removing from corresponding rating array and updating local Storage
starArr.splice(i, 1);
break;
}
}
if (starArr.length != 0) {
localStorage.setItem(`star${reviewRating}`, JSON.stringify(starArr));
} else {
localStorage.removeItem(`star${reviewRating}`);
}
for (let i in activeIDS) {
if (activeIDS[i] == ID) {
activeIDS.splice(i, 1);
localStorage.setItem("activeIDS", JSON.stringify(activeIDS));
let currReview = JSON.parse(localStorage.getItem(`review${ID}`));
deleteTagsFromStorage(ID, currReview["tags"]);
localStorage.removeItem(`review${ID}`);
return;
}
}
console.error(`could not find review${ID} in localStorage`);
}
/**
* Delete ID from the specified tags' storage
* @param {string} ID to delete from lists
* @param {string[]} deletedTags to modify storage of
*/
function deleteTagsFromStorage(ID, deletedTags) {
for (let i in deletedTags) {
//get local storage of each tag and remove id from tag list
let tagName = "!" + deletedTags[i].toLocaleLowerCase();
let tagArr = JSON.parse(localStorage.getItem(tagName));
for (let j in tagArr) {
if (tagArr[j] == ID) {
tagArr.splice(j, 1);
break;
}
}
if (tagArr.length != 0) {
localStorage.setItem(tagName, JSON.stringify(tagArr));
} else {
localStorage.removeItem(tagName);
}
}
}
/**
* Add ID from the specified tags' storage
* @param {string} ID to add to lists
* @param {string[]} addedTags to modify storage of
*/
function addTagsToStorage(ID, addedTags) {
for (let i in addedTags) {
let tagName = "!" + addedTags[i].toLocaleLowerCase();
let tagArr = JSON.parse(localStorage.getItem(tagName));
if (!tagArr) {
tagArr = [];
}
tagArr.push(ID);
localStorage.setItem(tagName, JSON.stringify(tagArr));
}
}
/**
* Test Helper Function to get all reviews from local storage
* @returns {Object} all active reviews from local storage
*/
export function getAllReviewsFromStorage() {
if (!localStorage.getItem("activeIDS")) {
// we wanna init the active ID array and start the nextID count
localStorage.setItem("activeIDS", JSON.stringify([]));
localStorage.setItem("nextID", JSON.stringify(0));
localStorage.setItem("nextID", JSON.stringify(0));
}
//iterate thru activeIDS
let activeIDS = JSON.parse(localStorage.getItem("activeIDS"));
let reviews = []
let reviews = [];
for (let i = 0; i < activeIDS.length; i++) {
let currReview = JSON.parse(localStorage.getItem('review'+activeIDS[i]));
let currReview = JSON.parse(localStorage.getItem(`review${activeIDS[i]}`));
reviews.push(currReview);
}
return reviews;
}
/**
* Takes in an array of reviews, converts it to a string, and then
* saves that string to 'reviews' in localStorage
* @param {Array<Object>} reviews An array of reviews
* Get all IDs of active reviews (order: most recent)
* @returns {number[]} list of all active IDs by recency
*/
export function saveReviewsToStorage(reviews) {
localStorage.setItem(`review${reviewId}`, JSON.stringify(reviews));
export function getIDsFromStorage() {
if (!localStorage.getItem("activeIDS")) {
// we wanna init the active ID array and start the nextID count
localStorage.setItem("activeIDS", JSON.stringify([]));
localStorage.setItem("nextID", JSON.stringify(0));
}
let activeIDS = JSON.parse(localStorage.getItem("activeIDS"));
return activeIDS.reverse();
}
/**
* Returns all review IDs which contain the same tag specified (order: most recent)
* @param {string} tag to filter by
* @returns {number[]} list of IDs of reviews that all contain the specified tag by recency
*/
export function getIDsByTag(tag) {
let tagArr = JSON.parse(localStorage.getItem("!" + tag.toLocaleLowerCase()));
if (!tagArr) {
tagArr = [];
}
return tagArr.reverse();
}
/**
* Returns the top rated review IDs in order.
* @returns {number[]} list of IDs of reviews in order of top rating (most recent if equal rating)
*/
export function getTopIDsFromStorage() {
let resultArr = [];
for (let i = 5; i > 0; i--) {
let starArr = JSON.parse(localStorage.getItem(`star${i}`));
if (!starArr) {
continue;
}
resultArr = resultArr.concat(starArr.reverse());
}
return resultArr;
}

View File

@@ -1,49 +1,319 @@
import {strict as assert} from "node:assert";
import {describe, it, beforeEach} from "mocha";
import {saveReviewsToStorage, getReviewsFromStorage} from "./localStorage.js";
import { strict as assert } from "node:assert";
import { describe, it, before, after } from "mocha";
import {
newReviewToStorage,
getReviewFromStorage,
updateReviewToStorage,
deleteReviewFromStorage,
getAllReviewsFromStorage,
getIDsByTag,
getTopIDsFromStorage,
} from "./localStorage.js";
describe("test app localStorage interaction", () => {
beforeEach(() => {
describe("test CRUD localStorage interaction", () => {
before(() => {
localStorage.clear();
});
it("get after init", () => {
assert.deepEqual(getReviewsFromStorage(), []);
it("test localStorage state after init", () => {
assert.deepEqual(getAllReviewsFromStorage(), []);
assert.deepEqual(JSON.parse(localStorage.getItem("activeIDS")), []);
assert.strictEqual(JSON.parse(localStorage.getItem("nextID")), 0);
});
it("store one then get", () => {
let reviews = [{
"imgSrc": "sample src",
"imgAlt": "sample alt",
"mealName": "sample name",
"restaurant": "sample restaurant",
"rating": 5,
"tags": ["tag 1", "tag 2", "tag 3"]
}];
saveReviewsToStorage(reviews);
assert.deepEqual(getReviewsFromStorage(), reviews);
it("test localStorage state after adding one review", () => {
let review = {
imgSrc: "sample src",
mealName: "sample name",
restaurant: "sample restaurant",
rating: 5,
tags: ["tag 1", "tag 2", "tag 3"],
};
newReviewToStorage(review);
review.reviewID = 0;
assert.deepEqual(getAllReviewsFromStorage(), [review]);
assert.deepEqual(getReviewFromStorage(0), review);
assert.deepEqual(JSON.parse(localStorage.getItem("activeIDS")), [0]);
assert.strictEqual(JSON.parse(localStorage.getItem("nextID")), 1);
});
it("repeated store one more and get", () => {
let reviews = [];
assert.deepEqual(getReviewsFromStorage(), reviews);
it("test localStorage state during adding 999 reviews", () => {
let reviews = getAllReviewsFromStorage();
let ids = [0];
for(let i = 0; i < 1000; i++){
reviews = getReviewsFromStorage();
for (let i = 1; i < 1000; i++) {
ids.push(i);
let new_review = {
imgSrc: `sample src ${i}`,
mealName: `sample name ${i}`,
restaurant: `sample restaurant ${i}`,
rating: i,
tags: [`tag ${3 * i}`, `tag ${3 * i + 1}`, `tag ${3 * i + 2}`],
};
reviews.push(
{
"imgSrc": `sample src ${i}`,
"imgAlt": `sample alt ${i}`,
"mealName": `sample name ${i}`,
"restaurant": `sample restaurant ${i}`,
"rating": i,
"tags": [`tag ${3*i}`, `tag ${3*i + 1}`, `tag ${3*i + 2}`]
}
);
saveReviewsToStorage(reviews);
assert.deepEqual(getReviewsFromStorage(), reviews);
new_review.reviewID = newReviewToStorage(new_review);
reviews.push(new_review);
assert.deepEqual(getAllReviewsFromStorage(), reviews);
assert.deepEqual(getReviewFromStorage(i), new_review);
assert.deepEqual(JSON.parse(localStorage.getItem("activeIDS")), ids);
assert.strictEqual(JSON.parse(localStorage.getItem("nextID")), i + 1);
}
}).timeout(10000);
}).timeout(5000);
it("test localStorage state during updating 1000 reviews", () => {
for (let i = 0; i < 1000; i++) {
let old_review = getReviewFromStorage(i);
let id = old_review.reviewID;
let new_review = {
imgSrc: `updated sample src ${id}`,
mealName: `updated sample name ${id}`,
restaurant: `updated sample restaurant ${id}`,
reviewID: id,
rating: (id % 5) + 1,
tags: [`tag ${3 * id}`, `tag ${3 * id + 1}`, `tag ${3 * id + 2}`],
};
updateReviewToStorage(id, new_review);
let all_reviews = getAllReviewsFromStorage();
let active_ids = JSON.parse(localStorage.getItem("activeIDS"));
assert.deepEqual(all_reviews[999], new_review);
assert.strictEqual(active_ids[999], id);
assert.deepEqual(getReviewFromStorage(i), new_review);
assert.strictEqual(JSON.parse(localStorage.getItem("nextID")), 1000);
}
}).timeout(5000);
it("test localStorage state during deleting 1000 reviews", () => {
let reviews = getAllReviewsFromStorage();
let ids = JSON.parse(localStorage.getItem("activeIDS"));
for (let i = 999; i >= 0; i--) {
deleteReviewFromStorage(i);
ids.pop();
reviews.pop();
assert.deepEqual(getAllReviewsFromStorage(), reviews);
assert.deepEqual(JSON.parse(localStorage.getItem("activeIDS")), ids);
assert.strictEqual(JSON.parse(localStorage.getItem("nextID")), 1000);
}
}).timeout(5000);
it("test localStorage state after all deletes", () => {
assert.deepEqual(getAllReviewsFromStorage(), []);
});
after(() => {});
});
describe("test sort/filter localStorage interaction", () => {
before(() => {
localStorage.clear();
getAllReviewsFromStorage();
});
it("add sample data for sort and filter", () => {
for (let i = 0; i < 100; i++) {
let review = {
imgSrc: `sample src ${i}`,
mealName: `sample name ${i}`,
restaurant: `sample restaurant ${i}`,
rating: (i % 5) + 1,
tags: [`tag ${i % 3}`, `tag ${i < 50}`, "tag x"],
};
newReviewToStorage(review);
}
});
it("test getTopIDsFromStorage end behavior after create", () => {
let top_reviews = getTopIDsFromStorage();
let prev = Infinity;
for (let i = 0; i < top_reviews.length; i++) {
let review = getReviewFromStorage(top_reviews[i]);
assert.strictEqual(review.rating <= prev, true);
}
});
it("test getIDsByTag end behavior after create", () => {
let specific_tagged_reviews = [];
specific_tagged_reviews = getIDsByTag("tag 0");
assert.strictEqual(specific_tagged_reviews.length, 34);
for (let i = 0; i < specific_tagged_reviews.length; i++) {
let review = getReviewFromStorage(specific_tagged_reviews[i]);
assert.strictEqual(review.tags.includes("tag 0"), true);
assert.strictEqual(review.reviewID % 3, 0);
}
specific_tagged_reviews = getIDsByTag("tag 1");
assert.strictEqual(specific_tagged_reviews.length, 33);
for (let i = 0; i < specific_tagged_reviews.length; i++) {
let review = getReviewFromStorage(specific_tagged_reviews[i]);
assert.strictEqual(review.tags.includes("tag 1"), true);
assert.strictEqual(review.reviewID % 3, 1);
}
specific_tagged_reviews = getIDsByTag("tag 2");
assert.strictEqual(specific_tagged_reviews.length, 33);
for (let i = 0; i < specific_tagged_reviews.length; i++) {
let review = getReviewFromStorage(specific_tagged_reviews[i]);
assert.strictEqual(review.tags.includes("tag 2"), true);
assert.strictEqual(review.reviewID % 3, 2);
}
specific_tagged_reviews = getIDsByTag("tag true");
assert.strictEqual(specific_tagged_reviews.length, 50);
for (let i = 0; i < specific_tagged_reviews.length; i++) {
let review = getReviewFromStorage(specific_tagged_reviews[i]);
assert.strictEqual(review.tags.includes("tag true"), true);
assert.strictEqual(review.reviewID < 50, true);
}
specific_tagged_reviews = getIDsByTag("tag false");
assert.strictEqual(specific_tagged_reviews.length, 50);
for (let i = 0; i < specific_tagged_reviews.length; i++) {
let review = getReviewFromStorage(specific_tagged_reviews[i]);
assert.strictEqual(review.tags.includes("tag false"), true);
assert.strictEqual(review.reviewID >= 50, true);
}
specific_tagged_reviews = getIDsByTag("tag x");
assert.strictEqual(specific_tagged_reviews.length, 100);
specific_tagged_reviews = getIDsByTag("tag y");
assert.deepEqual(specific_tagged_reviews, []);
});
it("update sample data for sort and filter", () => {
for (let i = 0; i < 100; i++) {
let old_review = getReviewFromStorage(i);
let new_review = {
imgSrc: `sample src ${i}`,
mealName: `sample name ${i}`,
restaurant: `sample restaurant ${i}`,
reviewID: old_review.reviewID,
rating: (i % 5) + 1,
tags: [`tag ${i % 4}`, `tag ${i < 37}`, "tag y"],
};
updateReviewToStorage(old_review.reviewID, new_review);
}
});
it("test getTopIDsFromStorage end behavior after create", () => {
let top_reviews = getTopIDsFromStorage();
let prev = Infinity;
for (let i = 0; i < top_reviews.length; i++) {
let review = getReviewFromStorage(top_reviews[i]);
assert.strictEqual(review.rating <= prev, true);
}
});
it("test getIDsByTag end behavior after update", () => {
let specific_tagged_reviews = [];
specific_tagged_reviews = getIDsByTag("tag 0");
assert.strictEqual(specific_tagged_reviews.length, 25);
for (let i = 0; i < specific_tagged_reviews.length; i++) {
let review = getReviewFromStorage(specific_tagged_reviews[i]);
assert.strictEqual(review.tags.includes("tag 0"), true);
assert.strictEqual(review.reviewID % 4, 0);
}
specific_tagged_reviews = getIDsByTag("tag 1");
assert.strictEqual(specific_tagged_reviews.length, 25);
for (let i = 0; i < specific_tagged_reviews.length; i++) {
let review = getReviewFromStorage(specific_tagged_reviews[i]);
assert.strictEqual(review.tags.includes("tag 1"), true);
assert.strictEqual(review.reviewID % 4, 1);
}
specific_tagged_reviews = getIDsByTag("tag 2");
assert.strictEqual(specific_tagged_reviews.length, 25);
for (let i = 0; i < specific_tagged_reviews.length; i++) {
let review = getReviewFromStorage(specific_tagged_reviews[i]);
assert.strictEqual(review.tags.includes("tag 2"), true);
assert.strictEqual(review.reviewID % 4, 2);
}
specific_tagged_reviews = getIDsByTag("tag 3");
assert.strictEqual(specific_tagged_reviews.length, 25);
for (let i = 0; i < specific_tagged_reviews.length; i++) {
let review = getReviewFromStorage(specific_tagged_reviews[i]);
assert.strictEqual(review.tags.includes("tag 3"), true);
assert.strictEqual(review.reviewID % 4, 3);
}
specific_tagged_reviews = getIDsByTag("tag true");
assert.strictEqual(specific_tagged_reviews.length, 37);
for (let i = 0; i < specific_tagged_reviews.length; i++) {
let review = getReviewFromStorage(specific_tagged_reviews[i]);
assert.strictEqual(review.tags.includes("tag true"), true);
assert.strictEqual(review.reviewID < 37, true);
}
specific_tagged_reviews = getIDsByTag("tag false");
assert.strictEqual(specific_tagged_reviews.length, 63);
for (let i = 0; i < specific_tagged_reviews.length; i++) {
let review = getReviewFromStorage(specific_tagged_reviews[i]);
assert.strictEqual(review.tags.includes("tag false"), true);
assert.strictEqual(review.reviewID >= 37, true);
}
specific_tagged_reviews = getIDsByTag("tag x");
assert.deepEqual(specific_tagged_reviews, []);
specific_tagged_reviews = getIDsByTag("tag y");
assert.strictEqual(specific_tagged_reviews.length, 100);
});
it("delete all sample data for sort and filter", () => {
for (let i = 0; i < 100; i++) {
deleteReviewFromStorage(i);
}
});
it("test getTopIDsFromStorage end behavior after delete", () => {
for (let i = 0; i <= 100; i++) {
let top_reviews = getTopIDsFromStorage(i);
assert.deepEqual(top_reviews, []);
}
});
it("test getIDsByTag end behavior after delete", () => {
let specific_tagged_reviews = [];
specific_tagged_reviews = getIDsByTag("tag 0");
assert.deepEqual(specific_tagged_reviews, []);
specific_tagged_reviews = getIDsByTag("tag 1");
assert.deepEqual(specific_tagged_reviews, []);
specific_tagged_reviews = getIDsByTag("tag 2");
assert.deepEqual(specific_tagged_reviews, []);
specific_tagged_reviews = getIDsByTag("tag 3");
assert.deepEqual(specific_tagged_reviews, []);
specific_tagged_reviews = getIDsByTag("tag true");
assert.deepEqual(specific_tagged_reviews, []);
specific_tagged_reviews = getIDsByTag("tag false");
assert.deepEqual(specific_tagged_reviews, []);
specific_tagged_reviews = getIDsByTag("tag x");
assert.deepEqual(specific_tagged_reviews, []);
specific_tagged_reviews = getIDsByTag("tag y");
assert.deepEqual(specific_tagged_reviews, []);
});
after(() => {});
});

View File

@@ -1,30 +1,221 @@
import {strict as assert} from "node:assert";
import {describe, it, beforeEach, afterEach} from "mocha";
import { strict as assert } from "node:assert";
import { describe, it, before, after } from "mocha";
import puppeteer from "puppeteer-core";
import { exit } from "node:process";
import { setReviewForm, checkCorrectness } from "./appTestHelpers.js";
describe("test App end to end", async () => {
let browser;
let page;
beforeEach(async () => {
browser = await puppeteer.launch();
before(async () => {
let root;
try {
root = process.getuid() == 0;
} catch (error) {
root = false;
}
browser = await puppeteer.launch({ args: root ? ["--no-sandbox"] : undefined });
page = await browser.newPage();
try{
await page.goto("http://localhost:8080", {timeout: 1000});
}
catch (error) {
console.log("❌ failed to connect to localhost webserver on port 8080");
exit(1);
try {
await page.goto("http://localhost:8080", { timeout: 2000 });
await console.log(`✔ connected to localhost webserver as ${root ? "root" : "user"}`);
} catch (error) {
await console.log("❌ failed to connect to localhost webserver on port 8080");
}
});
it("page should have correct title", async () => {
assert.strictEqual(await page.title(), "Food Journal");
describe("test simple properties", async () => {
it("page should have correct title", async () => {
assert.strictEqual(await page.title(), "Food Journal");
});
});
afterEach(async () => {
describe("test CRUD on simple inputs and default image", () => {
describe("test create 1 new review", async () => {
it("create 1 new review", async () => {
// Click the button to create a new review
let create_btn = await page.$("#create-btn");
await create_btn.click();
await page.waitForNavigation();
// create a new review
let review = {
mealName: "sample name",
comments: "sample comment",
restaurant: "sample restaurant",
tags: ["tag 0", "tag 1", "tag 2", "tag 3", "tag 4"],
rating: 1,
};
await setReviewForm(page, review);
// Click the save button to save updates
let save_btn = await page.$("#save-btn");
await save_btn.click();
await page.waitForNavigation();
});
it("check details page", async () => {
// check the details page for correctness
let expected = {
imgSrc: "http://localhost:8080/assets/images/default_plate.png",
mealName: "sample name",
comments: "sample comment",
restaurant: "sample restaurant",
tags: ["tag 0", "tag 1", "tag 2", "tag 3", "tag 4"],
rating: "http://localhost:8080/assets/images/1-star.svg",
};
await checkCorrectness(page, "d", expected);
});
it("check home page", async () => {
// Click the button to return to the home page
let home_btn = await page.$("#home-btn");
home_btn.click();
await page.waitForNavigation();
// Get the review card again and get its shadowRoot
let review_card = await page.$("review-card");
let shadowRoot = await review_card.getProperty("shadowRoot");
let expected = {
imgSrc: "http://localhost:8080/assets/images/default_plate.png",
mealName: "sample name",
comments: "sample comment",
restaurant: "sample restaurant",
tags: ["tag 0", "tag 1", "tag 2", "tag 3", "tag 4"],
rating: "http://localhost:8080/assets/images/1-star.svg",
};
await checkCorrectness(shadowRoot, "a", expected);
});
});
describe("test read 1 review after refresh", async () => {
it("refresh page", async () => {
// Reload the page
await page.reload({ waitUntil: ["networkidle0", "domcontentloaded"] });
});
it("check details page", async () => {
// click review card
let review_card = await page.$("review-card");
await review_card.click();
await page.waitForNavigation();
// check the details page for correctness
let expected = {
imgSrc: "http://localhost:8080/assets/images/default_plate.png",
mealName: "sample name",
comments: "sample comment",
restaurant: "sample restaurant",
tags: ["tag 0", "tag 1", "tag 2", "tag 3", "tag 4"],
rating: "http://localhost:8080/assets/images/1-star.svg",
};
await checkCorrectness(page, "d", expected);
});
it("check home page", async () => {
// Click the button to return to the home page
let home_btn = await page.$("#home-btn");
home_btn.click();
await page.waitForNavigation();
// Get the review card again and get its shadowRoot
let review_card = await page.$("review-card");
let shadowRoot = await review_card.getProperty("shadowRoot");
// check the details page for correctness
let expected = {
imgSrc: "http://localhost:8080/assets/images/default_plate.png",
mealName: "sample name",
comments: "sample comment",
restaurant: "sample restaurant",
tags: ["tag 0", "tag 1", "tag 2", "tag 3", "tag 4"],
rating: "http://localhost:8080/assets/images/1-star.svg",
};
await checkCorrectness(shadowRoot, "a", expected);
});
});
describe("test update 1 review", async () => {
it("update 1 review", async () => {
// Get the only review card and click it
let review_card = await page.$("review-card");
await review_card.click();
await page.waitForNavigation();
// Click the button to show update form
let update_btn = await page.$("#update-btn");
await update_btn.click();
// create a new review
let review = {
mealName: "updated name",
comments: "updated comment",
restaurant: "updated restaurant",
tags: ["tag -0", "tag -1", "tag -2", "tag -3", "tag -4", "tag -5"],
rating: 5,
};
await setReviewForm(page, review);
// Click the save button to save updates
let save_btn = await page.$("#save-btn");
await save_btn.click();
await page.waitForNavigation();
}).timeout(10000);
it("check details page", async () => {
// check the details page for correctness
let expected = {
imgSrc: "http://localhost:8080/assets/images/default_plate.png",
mealName: "updated name",
comments: "updated comment",
restaurant: "updated restaurant",
tags: ["tag -0", "tag -1", "tag -2", "tag -3", "tag -4", "tag -5"],
rating: "http://localhost:8080/assets/images/5-star.svg",
};
await checkCorrectness(page, "d", expected);
});
it("check home page", async () => {
// Click the button to return to the home page
let home_btn = await page.$("#home-btn");
home_btn.click();
await page.waitForNavigation();
// Get the review card again and get its shadowRoot
let review_card = await page.$("review-card");
let shadowRoot = await review_card.getProperty("shadowRoot");
// check the details page for correctness
let expected = {
imgSrc: "http://localhost:8080/assets/images/default_plate.png",
mealName: "updated name",
comments: "updated comment",
restaurant: "updated restaurant",
tags: ["tag -0", "tag -1", "tag -2", "tag -3", "tag -4", "tag -5"],
rating: "http://localhost:8080/assets/images/5-star.svg",
};
await checkCorrectness(shadowRoot, "a", expected);
});
});
describe("test delete 1 review", async () => {
it("delete 1 review", async () => {
// Get the only review card and click it
let review_card = await page.$("review-card");
await review_card.click();
await page.waitForNavigation();
page.on("dialog", async (dialog) => {
console.log(dialog.message());
await dialog.accept();
});
});
});
});
after(async () => {
await page.close();
await browser.close();
});

View File

@@ -1,123 +0,0 @@
// main.js
import {getReviewsFromStorage, saveReviewsToStorage} from "./localStorage.js";
// Run the init() function when the page has loaded
window.addEventListener("DOMContentLoaded", init);
function init() {
// Get the reviews from localStorage
let reviews = getReviewsFromStorage();
// Add each reviews to the <main> element
addReviewsToDocument(reviews);
// Add the event listeners to the form elements
initFormHandler();
}
/**
* @param {Array<Object>} reviews An array of reviews
*/
function addReviewsToDocument(reviews) {
let mainEl = document.querySelector("main");
reviews.forEach(review => {
let newReview = document.createElement("review-card");
newReview.data = review;
//TODO: want to append it to whatever the box is in layout
mainEl.append(newReview);
});
}
/**
* Adds the necessary event handlers to <form> and the clear storage
* <button>.
*/
function initFormHandler() {
//btn to create form (could be its own function?)
let createBtn = document.getElementById("create-btn");
createBtn.addEventListener("click", function(){
window.location.assign("./CreatePage.html");
});
//accessing form components
/*
let tagContainer = document.getElementById("tag-container-form");
let form = document.querySelector("form");
form.addEventListener("submit", function(){
/*
* User submits the form for their review.
* We create reviewCard and put in storage
let formData = new FormData(form);
let reviewObject = {};
for (let [key, value] of formData) {
console.log(`${key}`);
console.log(`${value}`);
if (`${key}` !== "tag-form") {
reviewObject[`${key}`] = `${value}`;
}
}
reviewObject["tags"] = [];
let tags = document.querySelectorAll(".tag");
for(let i = 0; i < tags.length; i ++) {
reviewObject["tags"].push(tags[i].innerHTML);
tagContainer.removeChild(tags[i]);
}
let newReview = document.createElement("review-card");
newReview.data = reviewObject;
//TODO: want to append it to whatever the box is in layout
let mainEl = document.querySelector("main");
mainEl.append(newReview);
// TODO: assign an ID to be used for referencing this object form the activeIDs array and the tag arrays
let ID = localStorage.nextID;
let storedReviews = getReviewsFromStorage();
storedReviews.push(reviewObject);
saveReviewsToStorage(storedReviews);
document.getElementById("new-food-entry").reset();
});
// DEV-MODE: for testing purposes
let clearBtn = document.querySelector(".danger");
clearBtn.addEventListener("click", function() {
localStorage.clear();
let mainEl = document.querySelector("main");
while (mainEl.firstChild) {
mainEl.removeChild(mainEl.firstChild);
}
let deleteTags = document.querySelectorAll(".tag");
for(let i = 0; i < deleteTags.length; i ++) {
tagContainer.removeChild(deleteTags[i]);
}
//clears reviews AS WELL as resets form
document.getElementById("new-food-entry").reset();
});
let tagAddBtn = document.getElementById("tagAdd");
tagAddBtn.addEventListener("click", ()=> {
let tagField = document.getElementById("tag-form");
if (tagField.value.length > 0) {
let tagLabel = document.createElement("label");
tagLabel.innerHTML = tagField.value;
tagLabel.setAttribute("class","tag");
tagLabel.addEventListener("click",()=> {
tagContainer.removeChild(tagLabel);
});
tagContainer.append(tagLabel);
tagField.value = "";
}
});
*/
}

View File

@@ -1,79 +1,64 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Food Journal</title>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Food Journal</title>
<!-- Recipe Card Custom Element -->
<script src="assets/scripts/ReviewCard.js" type="module"></script>
<!--Add Favicon-->
<link rel="icon" type="image/x-icon" href="./assets/images/favicon.ico" />
<!-- Recipe Card Custom Element -->
<script src="assets/scripts/ReviewCard.js" type="module"></script>
<!-- Main Stylesheets & Scripts -->
<!-- Temporarily commented out reset.css due to furthur discussion needed on the values of the default config-->
<!-- <link rel="stylesheet" href="/static/reset.css" /> -->
<link rel="stylesheet" href="./static/ReviewCard.css" />
<script src="assets/scripts/main.js" type="module"></script>
<!-- Main Stylesheets & Scripts -->
<link rel="stylesheet" href="./static/homepage.css" />
<script src="assets/scripts/homepage.js" type="module"></script>
</head>
</head>
<body>
<main>
<!-- Add Food Entries Here -->
</main>
<button type="button" id="create-btn"><a href='./CreatePage.html'></a>CREATE</button>
<!-- <form id="new-food-entry">
<fieldset>
<legend>Pic:</legend>
<label for="mealImage">
Source:
<input type="text" id="mealImg" name="mealImg">
</label>
<label for="image-alt">
Alt Text:
<input type="text" id="imgAlt" name="imgAlt">
</label>
</fieldset>
<fieldset>
<body>
<header>
<div class="top-bar">
<img src="./assets/images/Logo.png" alt="logo" />
<h1>My Meal Journal</h1>
<img src="./assets/images/Logo.png" alt="logo" />
</div>
</header>
<main>
<div class="body-container">
<div style="width: 20%"></div>
<div style="width: 60%">
<div class="search-bar">
<form id="form">
<label for="sort">Sorting Method:</label>
<select id="sort">
<option value="recent">Most Recent</option>
<option value="top">Top Rated</option>
</select>
<input type="search" id="search-bar" name="searchBar" placeholder="Search by tags..." />
<button id="clear-search">Clear Search</button>
</form>
<img src="./assets/images/search_button.png" alt="SEARCH BTN" id="search-btn" />
</div>
<legend> Meal: </legend>
<label for="Meal: ">Meal:
<input type="text" id="mealName" name="mealName" required>
</label>
<label for="comments">Comments:
<br>
<textarea name="comments" id="comments"></textarea>
</label>
</fieldset>
<div class="center-display">
<img
src="./assets/images/create_button.png"
alt="CREATE"
id="create-btn"
title="Add an entry!"
onclick="window.location.assign('./CreatePage.html')"
/>
<h2 id="recent-reviews-text">Recent Reviews</h2>
<img src="./assets/images/create_button.png" id="create-btn-invis" draggable="false" />
</div>
<fieldset class="rating">
<legend> Rating: </legend>
<input type="radio" id="s5" name="rating" value="5"/> <label for="s5"> 5 stars </label>
<input type="radio" id="s4" name="rating" value="4"/> <label for="s4"> 4 stars </label>
<input type="radio" id="s3" name="rating" value="3"/> <label for="s3"> 3 stars </label>
<input type="radio" id="s2" name="rating" value="2"/> <label for="s2"> 2 stars </label>
<input type="radio" id="s1" name="rating" value="1"/> <label for="s1"> 1 star </label>
</fieldset>
<fieldset>
<legend>Other Info:</legend>
<label for="restaurant">
Restaurant:
<input type="text" id="restaurant" name="restaurant" required>
</label>
<label for="tag-form">
Tags:
<input type="text" id="tag-form" name="tag-form">
<div class='tag-container' id="tag-container-form">
</div>
<button type="button" id="tagAdd">Add Tag</button>
</label>
</fieldset>
<button type="submit" value="Submit">Add Review</button>
<button type="button" class="danger">Clear Review Journal</button>
</form> -->
</body>
<div class="review-container" id="review-container"></div>
</div>
<div style="width: 20%"></div>
</div>
</main>
<footer></footer>
</body>
</html>

View File

@@ -1,16 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Food Journal</title>
<script src="assets/scripts/reviewpage.js" type="module"></script>
</head>
<body>
<h1>Current Review:</h1>
<main>
</main>
</body>
</html>

View File

@@ -1,19 +0,0 @@
[
{
"imgSrc": "https://cdn.vox-cdn.com/thumbor/Cj5J-5WqSCjlC2tWCOXEB536CJY=/0x0:1810x1182/1200x800/filters:focal(761x447:1049x735)/cdn.vox-cdn.com/uploads/chorus_image/image/69422966/Tacos_Lined_Up.0.png",
"imgAlt": "tacos pic",
"mealName": "Birria Tacos",
"restaurant": "Mike's Red Tacos",
"rating": 5,
"tags": ["delicious", "#worthit","omg"]
},
{
"imgSrc": "https://www.redwormcomposting.com/images/worm-burrito.JPG",
"imgAlt": "wolftown pic",
"mealName": "Carnitas Burrito",
"restaurant": "Wolftown UCSD",
"rating": 0,
"tags": ["gross", "why","no"]
}
]

Binary file not shown.

View File

@@ -1,83 +1,32 @@
/* CreatePage.css */
* {
font-family: sans-serif;
@font-face {
font-family: testFont;
src: url("CoveredByYourGrace-Regular.ttf");
}
body {
height: 100%;
width: 100%;
background-color: #f8f3f1;
}
fieldset {
border: 2px solid rgb(214 214 214);
box-sizing: border-box;
display: block;
width: max-content;
.top-bar {
display: flex;
justify-content: center;
}
form button {
display: block;
margin-top: 5px;
.top-bar > img {
position: relative;
align-self: center;
padding-left: 2.5%;
padding-right: 2.5%;
width: 7.5%;
height: 7.5%;
}
label[for="ingredients"] p {
margin: 0;
}
label[for="numRatings"] {
margin: 10px 0 0;
}
label[for^="rating"] {
padding-right: 10px;
}
label:not([for^="rating"]) {
display: block;
margin-bottom: 5px;
}
main {
column-gap: 10px;
display: flex;
flex-wrap: wrap;
height: auto;
max-width: 660px;
row-gap: 10px;
width: 100%;
}
.tag-container {
display: flex;
flex-flow: row wrap;
}
.tag {
background-color: grey;
border-radius: 7px;
color: white;
padding-right: 7px;
padding-left: 7px;
margin: 3px;
}
.tag::before {
display: inline-block;
content: "x";
height: 15px;
width: 15px;
margin-right: 4px;
text-align: center;
color: white;
cursor: pointer;
}
.tag:hover::before {
color: red;
}
.danger {
background-color: rgb(254 171 171);
border-color: red;
.top-bar > h1 {
position: relative;
text-align: center;
color: #516754;
font-size: 6rem;
font-family: testFont, sans-serif;
}

160
source/static/Form.css Normal file
View File

@@ -0,0 +1,160 @@
@font-face {
font-family: testFont;
src: url("CoveredByYourGrace-Regular.ttf");
}
.journal-form h1 {
font-family: testFont, sans-serif;
text-align: center;
}
.journal-form {
font-size: 120%;
font-family: "Century Gothic", sans-serif;
width: 50%;
margin: auto;
color: #516754;
border: 2px solid rgb(31 41 32);
border-radius: 8px;
background-color: #f7dfd5;
word-break: break-all;
}
#d-meal-img {
border: 2px solid rgb(31 41 32);
border-radius: 8px;
}
fieldset {
border: none;
}
input[type="text"] {
width: 100%;
box-sizing: border-box;
background-color: #f7dfd5;
border: none;
border-bottom: 1px solid rgb(0 0 0);
}
input[type="text"]:focus {
outline: none;
border-bottom: 1px solid rgb(0 0 0);
}
.rating {
display: flex;
flex-flow: nowrap row-reverse;
}
.hidden,
.rating:not(:checked) > input {
/* Hide radio circles while star rating */
display: none;
}
/* Unchecked stars */
.rating:not(:checked) > label {
/* Make stars line up sideways and not vertically */
float: right;
/* Hide label text */
width: 1em;
overflow: hidden;
white-space: nowrap;
/* Star default color and size */
font-size: 200%;
line-height: 1.2;
color: #b3b3cc;
}
.rating > label:active {
position: relative;
}
.rating:not(:checked) > label::before {
content: "★";
}
/* Checked star color */
.rating > input:checked ~ label {
color: #ffbf00;
}
.rating:not(:checked) > label:hover,
.rating:not(:checked) > label:hover ~ label {
color: orangered;
}
.rating > input:checked + label:hover,
.rating > input:checked ~ label:hover,
.rating > input:checked + label:hover ~ label,
.rating > input:checked ~ label:hover ~ label,
.rating > label:hover ~ input:checked ~ label {
color: orangered;
}
.tag-container {
display: flex;
flex-flow: wrap row;
}
.tag {
background-color: grey;
border-radius: 7px;
color: white;
padding-right: 7px;
padding-left: 7px;
margin: 3px;
}
.tag::before {
display: inline-block;
content: "x";
height: 15px;
width: 15px;
margin-right: 4px;
text-align: center;
color: white;
cursor: pointer;
}
.tag:hover::before {
color: red;
}
#tag-add-btn {
background-color: #94da97; /* Green */
border: round;
color: rgb(206 83 179);
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 20px;
cursor: pointer;
border-radius: 10%;
margin-top: 5px;
}
#tag-add-btn:hover {
background-color: rgb(206 83 179); /* Green */
border: round;
color: #94da97;
text-align: center;
text-decoration: none;
display: inline-block;
font-size: 20px;
cursor: pointer;
border-radius: 10%;
margin-top: 5px;
}
.hidden {
display: none;
}
.tag-container * {
max-width: 100%;
overflow-wrap: anywhere;
}

93
source/static/OFL.txt Normal file
View File

@@ -0,0 +1,93 @@
Copyright (c) 2010, Kimberly Geswein (kimberlygeswein.com)
This Font Software is licensed under the SIL Open Font License, Version 1.1.
This license is copied below, and is also available with a FAQ at:
http://scripts.sil.org/OFL
-----------------------------------------------------------
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
-----------------------------------------------------------
PREAMBLE
The goals of the Open Font License (OFL) are to stimulate worldwide
development of collaborative font projects, to support the font creation
efforts of academic and linguistic communities, and to provide a free and
open framework in which fonts may be shared and improved in partnership
with others.
The OFL allows the licensed fonts to be used, studied, modified and
redistributed freely as long as they are not sold by themselves. The
fonts, including any derivative works, can be bundled, embedded,
redistributed and/or sold with any software provided that any reserved
names are not used by derivative works. The fonts and derivatives,
however, cannot be released under any other type of license. The
requirement for fonts to remain under this license does not apply
to any document created using the fonts or their derivatives.
DEFINITIONS
"Font Software" refers to the set of files released by the Copyright
Holder(s) under this license and clearly marked as such. This may
include source files, build scripts and documentation.
"Reserved Font Name" refers to any names specified as such after the
copyright statement(s).
"Original Version" refers to the collection of Font Software components as
distributed by the Copyright Holder(s).
"Modified Version" refers to any derivative made by adding to, deleting,
or substituting -- in part or in whole -- any of the components of the
Original Version, by changing formats or by porting the Font Software to a
new environment.
"Author" refers to any designer, engineer, programmer, technical
writer or other person who contributed to the Font Software.
PERMISSION & CONDITIONS
Permission is hereby granted, free of charge, to any person obtaining
a copy of the Font Software, to use, study, copy, merge, embed, modify,
redistribute, and sell modified and unmodified copies of the Font
Software, subject to the following conditions:
1) Neither the Font Software nor any of its individual components,
in Original or Modified Versions, may be sold by itself.
2) Original or Modified Versions of the Font Software may be bundled,
redistributed and/or sold with any software, provided that each copy
contains the above copyright notice and this license. These can be
included either as stand-alone text files, human-readable headers or
in the appropriate machine-readable metadata fields within text or
binary files as long as those fields can be easily viewed by the user.
3) No Modified Version of the Font Software may use the Reserved Font
Name(s) unless explicit written permission is granted by the corresponding
Copyright Holder. This restriction only applies to the primary font name as
presented to the users.
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
Software shall not be used to promote, endorse or advertise any
Modified Version, except to acknowledge the contribution(s) of the
Copyright Holder(s) and the Author(s) or with their explicit written
permission.
5) The Font Software, modified or unmodified, in part or in whole,
must be distributed entirely under this license, and must not be
distributed under any other license. The requirement for fonts to
remain under this license does not apply to any document created
using the Font Software.
TERMINATION
This license becomes null and void if any of the above conditions are
not met.
DISCLAIMER
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
OTHER DEALINGS IN THE FONT SOFTWARE.

View File

@@ -1,130 +0,0 @@
/* main.css */
* {
font-family: sans-serif;
}
body {
height: 100%;
width: 100%;
}
fieldset {
border: 2px solid rgb(214 214 214);
box-sizing: border-box;
display: block;
width: max-content;
}
form button {
display: block;
margin-top: 5px;
}
label[for="ingredients"] p {
margin: 0;
}
label[for="numRatings"] {
margin: 10px 0 0;
}
label[for^="rating"] {
padding-right: 10px;
}
label:not([for^="rating"]) {
display: block;
margin-bottom: 5px;
}
main {
column-gap: 10px;
display: flex;
flex-wrap: wrap;
height: auto;
max-width: 660px;
row-gap: 10px;
width: 100%;
}
.tag-container {
display: flex;
flex-flow: row wrap;
}
.tag {
background-color: grey;
border-radius: 7px;
color: white;
padding-right: 7px;
padding-left: 7px;
margin: 3px;
}
.tag::before {
display: inline-block;
content: "x";
height: 15px;
width: 15px;
margin-right: 4px;
text-align: center;
color: white;
cursor: pointer;
}
.tag:hover::before {
color: red;
}
.danger {
background-color: rgb(254 171 171);
border-color: red;
}
.hidden,
.rating:not(:checked) > input { /* Hide radio circles while star rating */
display: none;
}
/* Unchecked stars */
.rating:not(:checked) > label {
/* Make stars line up sideways and not vertically */
float: right;
/* Hide label text */
width: 1em;
overflow: hidden;
white-space: nowrap;
/* Star default color and size */
font-size: 200%;
line-height: 1.2;
color: #b3b3cc;
}
.rating > label:active {
position: relative;
}
.rating:not(:checked) > label::before {
content: "★";
}
/* Checked star color */
.rating > input:checked ~ label {
color: #ffbf00;
}
.rating:not(:checked) > label:hover,
.rating:not(:checked) > label:hover ~ label {
color: orangered;
}
.rating > input:checked + label:hover,
.rating > input:checked ~ label:hover,
.rating > input:checked + label:hover ~ label,
.rating > input:checked ~ label:hover ~ label,
.rating > label:hover ~ input:checked ~ label {
color: orangered;
}

View File

@@ -0,0 +1,47 @@
/* ReviewDetails.css */
@font-face {
font-family: testFont;
src: url("CoveredByYourGrace-Regular.ttf");
}
body {
background-color: #f8f3f1;
}
h1 {
text-align: center;
}
.top-bar {
display: flex;
justify-content: center;
}
.top-bar > img {
position: relative;
align-self: center;
padding-left: 2.5%;
padding-right: 2.5%;
width: 7.5%;
height: 7.5%;
}
.top-bar > h1 {
position: relative;
text-align: center;
/* color: #e4c3d2; */
color: #516754;
font-size: 6rem;
font-family: testFont, sans-serif;
}
.d-tag {
background-color: grey;
border-radius: 7px;
color: white;
padding-right: 7px;
padding-left: 7px;
margin: 10px;
}

127
source/static/homepage.css Normal file
View File

@@ -0,0 +1,127 @@
/* homepage.css */
@font-face {
font-family: testFont;
src: url("CoveredByYourGrace-Regular.ttf");
}
/* Color */
body {
/* background-color: #97a5bd */
/* background-color: #E3E3EC; */
background-color: #f8f3f1;
}
.top-bar {
display: flex;
justify-content: center;
}
.top-bar > img {
position: relative;
align-self: center;
padding-left: 2.5%;
padding-right: 2.5%;
width: 7.5%;
height: 7.5%;
}
.top-bar > h1 {
position: relative;
text-align: center;
/* color: #e4c3d2; */
/* color: rgb(145, 124, 175); */
color: #516754;
font-size: 6rem;
font-family: testFont, sans-serif;
}
.body-container {
display: flex;
max-height: 100%;
}
.center-display {
display: flex;
flex-direction: row;
justify-content: center;
align-items: center;
}
.search-bar {
display: flex;
justify-content: center;
font-family: "Century Gothic", sans-serif;
font-weight: bold;
color: #516754;
}
#sort {
margin-right: 1em;
}
.search-bar > form {
float: right;
padding: 6px 10px;
/*
margin-top: 8px;
margin-right: 16px;
*/
background: rgb(239 183 183);
font-size: 17px;
border: none;
border-radius: 12px;
}
#search-btn {
position: relative;
align-self: center;
width: 30px;
height: 30px;
}
#recent-reviews-text {
text-align: center;
font-size: 4rem;
color: #516754;
font-family: testFont, sans-serif;
}
img#create-btn {
position: relative;
align-self: center;
padding-left: 2.5%;
padding-right: 2.5%;
cursor: pointer;
width: 10%;
height: 10%;
}
img#create-btn-invis {
opacity: 0;
padding-left: 2.5%;
padding-right: 2.5%;
width: 10%;
height: 10%;
}
.review-container {
display: flex;
position: relative;
flex-wrap: wrap;
justify-content: center;
}
.review-container > div {
background-color: #f1f1f1;
text-align: center;
}
footer {
display: flex;
justify-content: center;
}

View File

@@ -1,158 +0,0 @@
/* This is a generic CSS file that sets preliminary rules for content that should be the same across pages */
html,
body,
div,
span,
object,
iframe,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
abbr,
address,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
samp,
small,
strong,
sub,
sup,
var,
b,
i,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section,
summary,
time,
mark,
audio,
video {
margin: 0;
padding: 0;
border: 0;
outline: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent;
}
body {
line-height: 1;
}
article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
display: block;
}
nav ul {
list-style: none;
}
blockquote,
q {
quotes: none;
}
blockquote::before,
blockquote::after,
q::before,
q::after {
content: "";
content: none;
}
a {
margin: 0;
padding: 0;
font-size: 100%;
vertical-align: baseline;
background: transparent;
}
table {
border-collapse: collapse;
border-spacing: 0;
}
input,
select {
vertical-align: middle;
}
img,
fieldset,
object {
border: none;
}
*,
*::after,
*::before {
box-sizing: border-box;
}
button,
label {
cursor: pointer;
}
html,
body {
height: 100%;
}
form {
border: solid;
}

67
source/sw.js Normal file
View File

@@ -0,0 +1,67 @@
const CACHE_NAME = "food-journal-v1";
const ASSETS = [
"index.html",
"ReviewDetails.html",
"CreatePage.html",
"static/CoveredByYourGrace-Regular.ttf",
"static/CreatePage.css",
"static/Form.css",
"static/homepage.css",
"static/ReviewDetails.css",
"assets/images/0-star.svg",
"assets/images/1-star.svg",
"assets/images/2-star.svg",
"assets/images/3-star.svg",
"assets/images/4-star.svg",
"assets/images/5-star.svg",
"assets/images/create_button.png",
"assets/images/default_plate.png",
"assets/images/delete_icon_for_interface.png",
"assets/images/edit_button_for_interface.png",
"assets/images/home_button_for_interface.png",
"assets/images/favicon.ico",
"assets/images/Logo.png",
"assets/images/search_button.png",
"assets/scripts/CreatePage.js",
"assets/scripts/localStorage.js",
"assets/scripts/homepage.js",
"assets/scripts/ReviewCard.js",
"assets/scripts/ReviewDetails.js",
];
/**
* Adds the install listener where the app assets are added to the cache
*/
self.addEventListener("install", async () => {
// open the cace
const cache = await caches.open(CACHE_NAME);
// add all elements in ASSETS to the cache, these are all the files requried for the app to run
await cache.addAll(ASSETS);
});
/**
* Adds an event listener on fetch events to serve cached resources while offline
* Uses a network first structure to prioritize fetching from network in case of app updates.
* If there are important updates, we want the user to get those if possible.
*/
self.addEventListener("fetch", (event) => {
// add a response to the fetch event
event.respondWith(
caches.open(CACHE_NAME).then((cache) => {
// try to return a network fetch response
return fetch(event.request)
.then((fetchedResponse) => {
// if there is a response, add it to the cache
cache.put(event.request, fetchedResponse.clone());
// return the network response
return fetchedResponse;
})
.catch(() => {
// If there is not a network response, return the cached response
// The ignoreVary option is used here to fix an issue where the service worker
// would not serve certain requests unless the page was refreshed at least once
return cache.match(event.request, { ignoreVary: true, ignoreSearch: true });
});
})
);
});

View File

@@ -1,16 +1,20 @@
# Final Project Topic Decision
- Status: accept
- Deciders: team members and TA
- Date: 10 / 27 / 22
- Status: accept
- Deciders: team members and TA
- Date: 10 / 27 / 22
## Decision Drivers
- Needed to develop a local-first, CRUD application that would be simple enough to implement in the next few weeks
- Needed to develop a local-first, CRUD application that would be simple enough to implement in the next few weeks
## Considered Options:
- Social Media Archive
- Resume Builder
- Copy/Paste
- Food Journal
- Social Media Archive
- Resume Builder
- Copy/Paste
- Food Journal
## Decision Outcome
Chosen Option: Food Journal, which allows users to hold their thoughts and ratings on meals and restaurants that they have been to. It is local-first, CRUD app, and fun. Therefore, we decided to choose this.

View File

@@ -1,15 +1,19 @@
# Finalized App Design on Figma
- Status: accept
- Deciders: Isaac Otero
- Date: 11 / 08 / 22
- Status: accept
- Deciders: Isaac Otero
- Date: 11 / 08 / 22
## Decision Drivers:
- Needed to figure out the wireframe and flow of our app
- Needed to visualize the different features
- Needed to figure out the wireframe and flow of our app
- Needed to visualize the different features
## Considered Option:
- Different feature option
- Color Scheme, font, spacing, and other design options were discussed
- Different feature option
- Color Scheme, font, spacing, and other design options were discussed
## Decision Outcome:
- Chosen Option: Design can be found at this link: https://www.figma.com/file/Qhugp1Dd0gPnJTbmmUIvsa/Wireframe?node-id=36%3A2
- Chosen Option: Design can be found at this link: https://www.figma.com/file/Qhugp1Dd0gPnJTbmmUIvsa/Wireframe?node-id=36%3A2

View File

@@ -1,18 +1,18 @@
# Use multiple CI/CD pipelines in parallel
- Status: accept
- Deciders: Arthur Lu, Marc Reta
- Date: 11 / 12 / 22
- Status: accept
- Deciders: Arthur Lu, Marc Reta
- Date: 11 / 12 / 22
## Decision Drivers
- Need to perform many different CI/CD tasks
- Need pipeline to be durable against any single failure
- Need to perform many different CI/CD tasks
- Need pipeline to be durable against any single failure
## Considered Options
- Single deep pipeline
- Multiple short pipelines in parallel
- Single deep pipeline
- Multiple short pipelines in parallel
## Decision Outcone

View File

@@ -1,18 +1,18 @@
# Use eslint for JS linting framework
- Status: accept
- Deciders: Arthur Lu, Marc Reta
- Date: 11 / 12 / 22
- Status: accept
- Deciders: Arthur Lu, Marc Reta
- Date: 11 / 12 / 22
## Decision Drivers
- Need linting to work with multiple style standards
- Need linting to be fast and informative
- Need linting to work with multiple style standards
- Need linting to be fast and informative
## Considered Options
- JSLint
- eslint
- JSLint
- eslint
## Decision Outcome

View File

@@ -1,18 +1,19 @@
# Use mocha for JS unit testing framework
- Status: accept
- Deciders: Arthur Lu, Marc Reta
- Date: 11 / 12 / 22
- Status: accept
- Deciders: Arthur Lu, Marc Reta
- Date: 11 / 12 / 22
## Decision Drivers
- Need specification on how to write unit testing assertion statements
- Need framework to perform unit testing quickly for immediate code feedback
- Need specification on how to write unit testing assertion statements
- Need framework to perform unit testing quickly for immediate code feedback
## Considered Options
- JUnit5
- Jest
- Mocha
- JUnit5
- Jest
- Mocha
## Decision Outcome

View File

@@ -0,0 +1,19 @@
# Use Stylelint for CSS linting framework
- Status: accept
- Deciders: Arthur Lu, Marc Reta
- Date: 11 / 14 / 22
## Decision Drivers
- Need linting to work with multiple style standards
- Need linting to be fast and informative
## Considered Options
- Stylelint
- Prettier
## Decision Outcome
Chosen Option: Stylelint for its easy installation and unopinionated.

View File

@@ -0,0 +1,19 @@
# Use HTMLhint for HTML linting framework
- Status: accept
- Deciders: Arthur Lu, Marc Reta
- Date: 11 / 14 / 22
## Decision Drivers
- Need linting to work with multiple style standards
- Need linting to be fast and informative
## Considered Options
- HTMLhint
- HTML-validate
## Decision Outcome
Chosen Option: HTMLhint for its low configuration complexity.

View File

@@ -1,18 +1,19 @@
# Use puppeteer for JS unit testing framework
- Status: accept
- Deciders: Arthur Lu, Marc Reta
- Date: 11 / 16 / 22
- Status: accept
- Deciders: Arthur Lu, Marc Reta
- Date: 11 / 16 / 22
## Decision Drivers
- Need end to end testing framework which runs headlessly and quickly
- Framework should integrate well with Mocha, the existing unit testing framework
- Framework should be easy to implement end to end tests with
- Need end to end testing framework which runs headlessly and quickly
- Framework should integrate well with Mocha, the existing unit testing framework
- Framework should be easy to implement end to end tests with
## Considered Options
- puppeteer
- selenium-webdriver
- puppeteer
- selenium-webdriver
## Decision Outcome

Some files were not shown because too many files have changed in this diff Show More