From 3c35cfc3e13d985d7dc408bbfa5cf16b5729edeb Mon Sep 17 00:00:00 2001 From: Kevin Wu Date: Fri, 22 Dec 2023 21:06:06 -0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E2=9C=A8=20create=20summary=20page=20(?= =?UTF-8?q?#9)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * feat: ✨ create summary page * style: 🎨 restyle meeting componentt * feat: ✨ extract GroupList component to lib * feat: ✨ add radiogroup confirmation, styling * feat: ✨ add tabs * style: 🎨 add border to groups heading * style: 🎨 mobile styling for tabs * chore: 🔧 add iconify icon set * style: 🎨 add icons * style: 🎨 left-align attendance radio on mobile * refactor: ♻️ meeting to scheduledmeeting * style: 🎨 adjust card style * feat: ✨ add unscheduled * fix: 🐛 correct timezone * refactor: ♻️ rename profile to summary * style: 🎨 add hover style * style: 🎨 slightly restyle groups * style: 🎨 meeting cards are more muted in color * refactor: ♻️ rename GroupList to GroupsCarousel * style: 🎨 extract Groups heading into parent * style: 🎨 show scrollbar * feat: ✨ move meeting link to title * style: 🎨 apply styling changes to unscheduled meetings * refactor: ♻️ extract meeting list components and time utilities * refactor: ♻️ extract types to lib * refactor: ♻️ extract data to stores * feat: ✨ create helper functions for sorting * style: 🎨 center radio on small screens * style: 🎨 adjust tabs --- package.json | 4 +- pnpm-lock.yaml | 164 ++++++++++++------ src/app.d.ts | 2 + .../components/summary/GroupsCarousel.svelte | 18 ++ .../summary/ScheduledMeetingsList.svelte | 69 ++++++++ .../summary/UnscheduledMeetingsList.svelte | 46 +++++ src/lib/stores/summaryStores.ts | 132 ++++++++++++++ src/lib/types/meetings.ts | 25 +++ src/lib/utils/summary-helpers.ts | 99 +++++++++++ src/routes/summary/+page.svelte | 40 +++++ vite.config.ts | 12 +- 11 files changed, 551 insertions(+), 60 deletions(-) create mode 100644 src/lib/components/summary/GroupsCarousel.svelte create mode 100644 src/lib/components/summary/ScheduledMeetingsList.svelte create mode 100644 src/lib/components/summary/UnscheduledMeetingsList.svelte create mode 100644 src/lib/stores/summaryStores.ts create mode 100644 src/lib/types/meetings.ts create mode 100644 src/lib/utils/summary-helpers.ts create mode 100644 src/routes/summary/+page.svelte diff --git a/package.json b/package.json index 2382fb8b..da204318 100644 --- a/package.json +++ b/package.json @@ -20,9 +20,11 @@ "test:unit": "vitest" }, "dependencies": { + "@iconify/json": "^2.2.160", "@lucia-auth/adapter-prisma": "3.0.2", "@prisma/client": "5.6.0", - "lucia": "2.7.4" + "lucia": "2.7.4", + "unplugin-icons": "^0.18.1" }, "devDependencies": { "@commitlint/cli": "18.4.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d3b6b6d2..ecf6164d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,6 +5,9 @@ settings: excludeLinksFromLockfile: false dependencies: + '@iconify/json': + specifier: ^2.2.160 + version: 2.2.160 '@lucia-auth/adapter-prisma': specifier: 3.0.2 version: 3.0.2(@prisma/client@5.6.0)(lucia@2.7.4) @@ -14,6 +17,9 @@ dependencies: lucia: specifier: 2.7.4 version: 2.7.4 + unplugin-icons: + specifier: ^0.18.1 + version: 0.18.1 devDependencies: '@commitlint/cli': @@ -162,6 +168,23 @@ packages: '@jridgewell/trace-mapping': 0.3.20 dev: true + /@antfu/install-pkg@0.1.1: + resolution: {integrity: sha512-LyB/8+bSfa0DFGC06zpCEfs89/XoWZwws5ygEa5D+Xsm3OfI+aXQ86VgVG7Acyef+rSZ5HE7J8rrxzrQeM3PjQ==} + dependencies: + execa: 5.1.1 + find-up: 5.0.0 + dev: false + + /@antfu/install-pkg@0.3.1: + resolution: {integrity: sha512-A3zWY9VeTPnxlMiZtsGHw2lSd3ghwvL8s9RiGOtqvDxhhFfZ781ynsGBa/iUnDJ5zBrmTFQrJDud3TGgRISaxw==} + dependencies: + execa: 8.0.1 + dev: false + + /@antfu/utils@0.7.7: + resolution: {integrity: sha512-gFPqTG7otEJ8uP6wrhDv6mqwGWYZKNvAcCq6u9hOj0c+IKCEsY4L1oC9trPq2SaWIzAfHvqfBDxF591JkMf+kg==} + dev: false + /@aws-cdk/asset-awscli-v1@2.2.201: resolution: {integrity: sha512-INZqcwDinNaIdb5CtW3ez5s943nX5stGBQS6VOP2JDlOFP81hM3fds/9NDknipqfUkZM43dx+HgVvkXYXXARCQ==} dev: true @@ -2398,6 +2421,30 @@ packages: resolution: {integrity: sha512-dvuCeX5fC9dXgJn9t+X5atfmgQAzUOWqS1254Gh0m6i8wKd10ebXkfNKiRK+1GWi/yTvvLDHpoxLr0xxxeslWw==} dev: true + /@iconify/json@2.2.160: + resolution: {integrity: sha512-mjVikrD2ohux47NDrG22qzVBIf0BGS3W4HUZO3d+dnk7Sk3AYrmWVsGiMW6aoSGrBMIKAXpkLqCqgu57eu1oIw==} + dependencies: + '@iconify/types': 2.0.0 + pathe: 1.1.1 + dev: false + + /@iconify/types@2.0.0: + resolution: {integrity: sha512-+wluvCrRhXrhyOmRDJ3q8mux9JkKy5SJ/v8ol2tu4FVjyYvtEzkc/3pK15ET6RKg4b4w4BmTk1+gsCUhf21Ykg==} + dev: false + + /@iconify/utils@2.1.13: + resolution: {integrity: sha512-6uWvJIo715xYRy1KmCCyZYW0YYkLjaojEExoEkxpOHKhi9cyHW8hVKo+m8zrxzNVSqjUx9OuVRa2BWXeXfkp5A==} + dependencies: + '@antfu/install-pkg': 0.1.1 + '@antfu/utils': 0.7.7 + '@iconify/types': 2.0.0 + debug: 4.3.4 + kolorist: 1.8.0 + local-pkg: 0.4.3 + transitivePeerDependencies: + - supports-color + dev: false + /@isaacs/cliui@8.0.2: resolution: {integrity: sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==} engines: {node: '>=12'} @@ -3692,7 +3739,6 @@ packages: resolution: {integrity: sha512-nc0Axzp/0FILLEVsm4fNwLCwMttvhEI263QtVPQcbpfZZ3ts0hLsZGOpE6czNlid7CJ9MlyH8reXkpsf3YUY4w==} engines: {node: '>=0.4.0'} hasBin: true - dev: true /adm-zip@0.5.10: resolution: {integrity: sha512-x0HvcHqVJNTPk/Bw8JbLWlWoo6Wwnsug0fnYYro1HBrjxZ3G7/AZk7Ahv8JwDe1uIcz8eBqvu86FuF1POiG7vQ==} @@ -3793,7 +3839,6 @@ packages: dependencies: normalize-path: 3.0.0 picomatch: 2.3.1 - dev: true /archiver-utils@2.1.0: resolution: {integrity: sha512-bEL/yUb/fNNiNTuUz979Z0Yg5L+LzLxGJz8x79lYmR54fmTIb6ob/hNQgkQnIUDWIFjZVQwl9Xs356I6BAMHfw==} @@ -4112,7 +4157,6 @@ packages: /binary-extensions@2.2.0: resolution: {integrity: sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==} engines: {node: '>=8'} - dev: true /bl@4.1.0: resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==} @@ -4183,7 +4227,6 @@ packages: engines: {node: '>=8'} dependencies: fill-range: 7.0.1 - dev: true /browserslist@4.22.1: resolution: {integrity: sha512-FEVc202+2iuClEhZhrWy6ZiAcRLvNMyYcxZ8raemul1DYVOVdFsbqckWLdsixQZCpJlwe77Z3UTalE7jsjnKfQ==} @@ -4368,7 +4411,6 @@ packages: readdirp: 3.6.0 optionalDependencies: fsevents: 2.3.3 - dev: true /ci-info@3.9.0: resolution: {integrity: sha512-NIxF55hv4nSqQswkAeiOi1r83xy8JldOFDTWiug55KBu9Jnblncd2U6ViHmYgHf01TPZS77NJBhBMKdWj9HQMQ==} @@ -4696,7 +4738,6 @@ packages: path-key: 3.1.1 shebang-command: 2.0.0 which: 2.0.2 - dev: true /crypto-js@4.2.0: resolution: {integrity: sha512-KALDyEYgpY+Rlob/iriUtjV6d5Eq+Y191A5g4UqLAi8CyGP9N1+FdVbkc1SxKc2r4YAYqG8JzO2KGL+AizD70Q==} @@ -4776,7 +4817,6 @@ packages: optional: true dependencies: ms: 2.1.2 - dev: true /decamelize-keys@1.1.1: resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} @@ -5458,7 +5498,6 @@ packages: onetime: 5.1.2 signal-exit: 3.0.7 strip-final-newline: 2.0.0 - dev: true /execa@7.2.0: resolution: {integrity: sha512-UduyVP7TLB5IcAQl+OzLyLcS/l32W/GLg+AhHJ+ow40FOk2U3SAllPwR44v4vmdFwIWqpdwxxpQbF1n5ta9seA==} @@ -5488,7 +5527,6 @@ packages: onetime: 6.0.0 signal-exit: 4.1.0 strip-final-newline: 3.0.0 - dev: true /expand-tilde@2.0.2: resolution: {integrity: sha512-A5EmesHW6rfnZ9ysHQjPdJRni0SRar0tjtG5MNtm9n5TUvsYU8oozprtRD4AqHxcZWWlVuAmQo2nWKfN9oyjTw==} @@ -5626,7 +5664,6 @@ packages: engines: {node: '>=8'} dependencies: to-regex-range: 5.0.1 - dev: true /finalhandler@1.2.0: resolution: {integrity: sha512-5uXcUVftlQMFnWC9qu/svkWv3GTd2PfUhK/3PLkYNAe7FbqJMt3515HaxE6eRL74GdsriiwujiawdaB1BpEISg==} @@ -5675,7 +5712,6 @@ packages: dependencies: locate-path: 6.0.0 path-exists: 4.0.0 - dev: true /findup-sync@4.0.0: resolution: {integrity: sha512-6jvvn/12IC4quLBL1KNokxC7wWTvYncaVUYSoxWw7YykPLuRrnv4qdHcSOywOI5RpkOVGeQRtWM8/q+G6W6qfQ==} @@ -5787,7 +5823,6 @@ packages: engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} os: [darwin] requiresBuild: true - dev: true optional: true /function-bind@1.1.2: @@ -5844,12 +5879,10 @@ packages: /get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} - dev: true /get-stream@8.0.1: resolution: {integrity: sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==} engines: {node: '>=16'} - dev: true /get-symbol-description@1.0.0: resolution: {integrity: sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==} @@ -5880,7 +5913,6 @@ packages: engines: {node: '>= 6'} dependencies: is-glob: 4.0.3 - dev: true /glob-parent@6.0.2: resolution: {integrity: sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==} @@ -6131,7 +6163,6 @@ packages: /human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} - dev: true /human-signals@4.3.1: resolution: {integrity: sha512-nZXjEF2nbo7lIw3mgYjItAfgQXog3OjJogSbKa2CQIIvSGWcKgeJnQlNXip6NglNzYH45nSRiEVimMvYL8DDqQ==} @@ -6141,7 +6172,6 @@ packages: /human-signals@5.0.0: resolution: {integrity: sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==} engines: {node: '>=16.17.0'} - dev: true /husky@8.0.3: resolution: {integrity: sha512-+dQSyqPh4x1hlO1swXBiNb2HzTDN1I2IGLQx1GrBuiqFJfoMrnZWwVmatvSiO+Iz8fBUnf+lekwNo4c2LlXItg==} @@ -6338,7 +6368,6 @@ packages: engines: {node: '>=8'} dependencies: binary-extensions: 2.2.0 - dev: true /is-boolean-object@1.1.2: resolution: {integrity: sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==} @@ -6388,7 +6417,6 @@ packages: /is-extglob@2.1.1: resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==} engines: {node: '>=0.10.0'} - dev: true /is-fullwidth-code-point@3.0.0: resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==} @@ -6412,7 +6440,6 @@ packages: engines: {node: '>=0.10.0'} dependencies: is-extglob: 2.1.1 - dev: true /is-inside-container@1.0.0: resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==} @@ -6453,7 +6480,6 @@ packages: /is-number@7.0.0: resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==} engines: {node: '>=0.12.0'} - dev: true /is-obj@2.0.0: resolution: {integrity: sha512-drqDG3cbczxxEJRoOXcOjtdp1J/lyp1mNn0xaznRs8+muBhgQcrnbspox5X5fOw0HnMnbfDzvnEMEtqDEJEo8w==} @@ -6498,12 +6524,10 @@ packages: /is-stream@2.0.1: resolution: {integrity: sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==} engines: {node: '>=8'} - dev: true /is-stream@3.0.0: resolution: {integrity: sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - dev: true /is-string@1.0.7: resolution: {integrity: sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==} @@ -6581,7 +6605,6 @@ packages: /isexe@2.0.0: resolution: {integrity: sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==} - dev: true /isomorphic-ws@4.0.1(ws@8.14.2): resolution: {integrity: sha512-BhBvN2MBpWTaSHdWRb/bwdZJ1WaehQ2L1KngkCkfLUGF0mAWAT1sQUQacEmQ0jXkFw/czDXPNQSL5u2/Krsz1w==} @@ -6675,7 +6698,6 @@ packages: /jsonc-parser@3.2.0: resolution: {integrity: sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==} - dev: true /jsonfile@6.1.0: resolution: {integrity: sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==} @@ -6714,6 +6736,10 @@ packages: resolution: {integrity: sha512-Ne7wqW7/9Cz54PDt4I3tcV+hAyat8ypyOGzYRJQfdxnnjeWsTxt1cy8pjvvKeI5kfXuyvULyeeAvwvvtAX3ayQ==} dev: true + /kolorist@1.8.0: + resolution: {integrity: sha512-Y+60/zizpJ3HRH8DCss+q95yr6145JXZo46OTpFvDZWLfRCE4qChOyk1b26nMaNpfHHgxagk9dXT5OP0Tfe+dQ==} + dev: false + /kysely-codegen@0.10.1(kysely@0.25.0): resolution: {integrity: sha512-8Bslh952gN5gtucRv4jTZDFD18RBioS6M50zHfe5kwb5iSyEAunU4ZYMdHzkHraa4zxjg5/183XlOryBCXLRIw==} hasBin: true @@ -6820,7 +6846,14 @@ packages: /local-pkg@0.4.3: resolution: {integrity: sha512-SFppqq5p42fe2qcZQqqEOiVRXl+WCP1MdT6k7BDEW1j++sp5fIY+/fdRQitvKgB5BrBcmrs5m/L0v2FrU5MY1g==} engines: {node: '>=14'} - dev: true + + /local-pkg@0.5.0: + resolution: {integrity: sha512-ok6z3qlYyCDS4ZEU27HaU6x/xZa9Whf8jD4ptH5UZTQYZVYeb9bnZ3ojVhiJNLiXK1Hfc0GNbLXcmZ5plLDDBg==} + engines: {node: '>=14'} + dependencies: + mlly: 1.4.2 + pkg-types: 1.0.3 + dev: false /locate-character@3.0.0: resolution: {integrity: sha512-SW13ws7BjaeJ6p7Q6CO2nchbYEc3X3J6WrmTTDto7yMPqVSZTUyY5Tjbid+Ab8gLnATtygYtiDIJGQRRn2ZOiA==} @@ -6846,7 +6879,6 @@ packages: engines: {node: '>=10'} dependencies: p-locate: 5.0.0 - dev: true /lodash.camelcase@4.3.0: resolution: {integrity: sha512-TwuEnCnxbc3rAvhf/LbG7tJUDzhqXyFnv3dtzLOPgCG/hODL7WFnsbwktkD7yUV0RrreP/l1PALq/YSg6VvjlA==} @@ -7051,7 +7083,6 @@ packages: /merge-stream@2.0.0: resolution: {integrity: sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==} - dev: true /merge2@1.4.1: resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==} @@ -7102,7 +7133,6 @@ packages: /mimic-fn@2.1.0: resolution: {integrity: sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==} engines: {node: '>=6'} - dev: true /mimic-fn@3.1.0: resolution: {integrity: sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==} @@ -7112,7 +7142,6 @@ packages: /mimic-fn@4.0.0: resolution: {integrity: sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==} engines: {node: '>=12'} - dev: true /min-indent@1.0.1: resolution: {integrity: sha512-I9jwMn07Sy/IwOj3zVkVik2JTvgpaykDZEigL6Rx6N9LbMywwUSMtxET+7lVoDLLd3O3IXwJwvuuns8UB/HeAg==} @@ -7190,7 +7219,6 @@ packages: pathe: 1.1.1 pkg-types: 1.0.3 ufo: 1.3.2 - dev: true /mnemonist@0.39.5: resolution: {integrity: sha512-FPUtkhtJ0efmEFGpU14x7jGbTB+s18LrzRL2KgoWz9YvcY3cPomz8tih01GbHwnGk/OmkOKfqd/RAQoc8Lm7DQ==} @@ -7277,7 +7305,6 @@ packages: /ms@2.1.2: resolution: {integrity: sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==} - dev: true /ms@2.1.3: resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==} @@ -7336,7 +7363,6 @@ packages: /normalize-path@3.0.0: resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==} engines: {node: '>=0.10.0'} - dev: true /normalize-range@0.1.2: resolution: {integrity: sha512-bdok/XvKII3nUpklnV6P2hxtMNrCboOjAcyBuQnWEhO665FwrSNRxU+AqpsyvO6LgGYPspN+lu5CLtw4jPRKNA==} @@ -7348,14 +7374,12 @@ packages: engines: {node: '>=8'} dependencies: path-key: 3.1.1 - dev: true /npm-run-path@5.1.0: resolution: {integrity: sha512-sJOdmRGrY2sjNTRMbSvluQqg+8X7ZK61yvzBEIDhz4f8z1TZFYABsqjjCBd/0PUNE9M6QDgHJXQkGUEm7Q+l9Q==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} dependencies: path-key: 4.0.0 - dev: true /number-allocator@1.0.14: resolution: {integrity: sha512-OrL44UTVAvkKdOdRQZIJpLkAdjXGTRda052sN4sO77bKEzYYqWKMBjQvrJFzqygI99gL6Z4u2xctPW1tB8ErvA==} @@ -7454,14 +7478,12 @@ packages: engines: {node: '>=6'} dependencies: mimic-fn: 2.1.0 - dev: true /onetime@6.0.0: resolution: {integrity: sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==} engines: {node: '>=12'} dependencies: mimic-fn: 4.0.0 - dev: true /open@9.1.0: resolution: {integrity: sha512-OS+QTnw1/4vrf+9hh1jc1jnYjzSG4ttTBB8UxOwAnInG3Uo4ssetzC1ihqaIHjLJnA5GGlRl6QlZXOTQhRBUvg==} @@ -7541,7 +7563,6 @@ packages: engines: {node: '>=10'} dependencies: yocto-queue: 0.1.0 - dev: true /p-limit@4.0.0: resolution: {integrity: sha512-5b0R4txpzjPWVw/cXXUResoD4hb6U/x9BH08L7nw+GN1sezDzPdxeRvpc9c433fZhBan/wusjbCsqwqm4EIBIQ==} @@ -7569,7 +7590,6 @@ packages: engines: {node: '>=10'} dependencies: p-limit: 3.1.0 - dev: true /p-try@2.2.0: resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==} @@ -7616,7 +7636,6 @@ packages: /path-exists@4.0.0: resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==} engines: {node: '>=8'} - dev: true /path-is-absolute@1.0.1: resolution: {integrity: sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==} @@ -7626,12 +7645,10 @@ packages: /path-key@3.1.1: resolution: {integrity: sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==} engines: {node: '>=8'} - dev: true /path-key@4.0.0: resolution: {integrity: sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==} engines: {node: '>=12'} - dev: true /path-parse@1.0.7: resolution: {integrity: sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==} @@ -7656,7 +7673,6 @@ packages: /pathe@1.1.1: resolution: {integrity: sha512-d+RQGp0MAYTIaDBIMmOfMwz3E+LOZnxx1HZd5R18mmCZY0QBlK0LDZfPc8FW8Ed2DlvsuE6PRjroDY+wg4+j/Q==} - dev: true /pathval@1.1.1: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} @@ -7677,7 +7693,6 @@ packages: /picomatch@2.3.1: resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==} engines: {node: '>=8.6'} - dev: true /pidtree@0.6.0: resolution: {integrity: sha512-eG2dWTVw5bzqGRztnHExczNxt5VGsE6OwTeCG3fdUf9KBsZzO3R5OIIIzWR+iZA0NtZ+RDVdaoE2dK1cn6jH4g==} @@ -7701,7 +7716,6 @@ packages: jsonc-parser: 3.2.0 mlly: 1.4.2 pathe: 1.1.1 - dev: true /pkg-up@3.1.0: resolution: {integrity: sha512-nDywThFk1i4BQK4twPQ6TA4RT8bDY96yeuCVBWL3ePARCiEKDRSrNGbFIgUJpLp+XeIR65v8ra7WuJOFUBtkMA==} @@ -8073,7 +8087,6 @@ packages: engines: {node: '>=8.10.0'} dependencies: picomatch: 2.3.1 - dev: true /redent@3.0.0: resolution: {integrity: sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg==} @@ -8366,12 +8379,10 @@ packages: engines: {node: '>=8'} dependencies: shebang-regex: 3.0.0 - dev: true /shebang-regex@3.0.0: resolution: {integrity: sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==} engines: {node: '>=8'} - dev: true /side-channel@1.0.4: resolution: {integrity: sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==} @@ -8387,12 +8398,10 @@ packages: /signal-exit@3.0.7: resolution: {integrity: sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==} - dev: true /signal-exit@4.1.0: resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==} engines: {node: '>=14'} - dev: true /sirv@2.0.3: resolution: {integrity: sha512-O9jm9BsID1P+0HOi81VpXPoDxYP374pkOLzACAoyUQ/3OUVndNpsz6wMnY2z+yOxzbllCKZrM+9QrWsv4THnyA==} @@ -8731,12 +8740,10 @@ packages: /strip-final-newline@2.0.0: resolution: {integrity: sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==} engines: {node: '>=6'} - dev: true /strip-final-newline@3.0.0: resolution: {integrity: sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==} engines: {node: '>=12'} - dev: true /strip-indent@3.0.0: resolution: {integrity: sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ==} @@ -9055,7 +9062,6 @@ packages: engines: {node: '>=8.0'} dependencies: is-number: 7.0.0 - dev: true /toidentifier@1.0.1: resolution: {integrity: sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==} @@ -9221,7 +9227,6 @@ packages: /ufo@1.3.2: resolution: {integrity: sha512-o+ORpgGwaYQXgqGDwd+hkS4PuZ3QnmqMMxRuajK/a38L6fTpcE5GPIfrf+L/KemFzfUpeUQc1rRS1iDBozvnFA==} - dev: true /ultron@1.1.1: resolution: {integrity: sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==} @@ -9264,6 +9269,46 @@ packages: engines: {node: '>= 0.8'} dev: true + /unplugin-icons@0.18.1: + resolution: {integrity: sha512-WzKu/eoq74YC7vyEAGsFebkRzsZrRkR4FUzLU6gbpfa7WRaVVpQS2n7LSxE1iRUN0scKL5b9bq+i0wucR+ttFQ==} + peerDependencies: + '@svgr/core': '>=7.0.0' + '@svgx/core': ^1.0.1 + '@vue/compiler-sfc': ^3.0.2 || ^2.7.0 + vue-template-compiler: ^2.6.12 + vue-template-es2015-compiler: ^1.9.0 + peerDependenciesMeta: + '@svgr/core': + optional: true + '@svgx/core': + optional: true + '@vue/compiler-sfc': + optional: true + vue-template-compiler: + optional: true + vue-template-es2015-compiler: + optional: true + dependencies: + '@antfu/install-pkg': 0.3.1 + '@antfu/utils': 0.7.7 + '@iconify/utils': 2.1.13 + debug: 4.3.4 + kolorist: 1.8.0 + local-pkg: 0.5.0 + unplugin: 1.5.1 + transitivePeerDependencies: + - supports-color + dev: false + + /unplugin@1.5.1: + resolution: {integrity: sha512-0QkvG13z6RD+1L1FoibQqnvTwVBXvS4XSPwAyinVgoOCl2jAgwzdUKmEj05o4Lt8xwQI85Hb6mSyYkcAGwZPew==} + dependencies: + acorn: 8.11.2 + chokidar: 3.5.3 + webpack-sources: 3.2.3 + webpack-virtual-modules: 0.6.1 + dev: false + /untildify@4.0.0: resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} engines: {node: '>=8'} @@ -9503,6 +9548,15 @@ packages: tslib: 2.6.2 dev: true + /webpack-sources@3.2.3: + resolution: {integrity: sha512-/DyMEOrDgLKKIG0fmvtz+4dUX/3Ghozwgm6iPp8KRhvn+eQf9+Q7GWxVNMk3+uCPWfdXYC4ExGBckIXdFEfH1w==} + engines: {node: '>=10.13.0'} + dev: false + + /webpack-virtual-modules@0.6.1: + resolution: {integrity: sha512-poXpCylU7ExuvZK8z+On3kX+S8o/2dQ/SVYueKA0D4WEMXROXgY8Ez50/bQEUmvoSMMrWcrJqCHuhAbsiwg7Dg==} + dev: false + /websocket-stream@5.5.2: resolution: {integrity: sha512-8z49MKIHbGk3C4HtuHWDtYX8mYej1wWabjthC/RupM9ngeukU4IWoM46dgth1UOS/T4/IqgEdCDJuMe2039OQQ==} dependencies: @@ -9551,7 +9605,6 @@ packages: hasBin: true dependencies: isexe: 2.0.0 - dev: true /why-is-node-running@2.2.2: resolution: {integrity: sha512-6tSwToZxTOcotxHeA+qGCq1mVzKR3CwcJGmVcY+QE8SHy6TnpFnh8PAvPNHYr7EcuVeG0QSMxtYCuO1ta/G/oA==} @@ -9718,7 +9771,6 @@ packages: /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} - dev: true /yocto-queue@1.0.0: resolution: {integrity: sha512-9bnSc/HEW2uRy67wc+T8UwauLuPJVn28jb+GtJY16iiKWyvmYJRXVT4UamsAEGQfPohgr2q4Tq0sQbQlxTfi1g==} diff --git a/src/app.d.ts b/src/app.d.ts index f16747bd..747f55e4 100644 --- a/src/app.d.ts +++ b/src/app.d.ts @@ -1,5 +1,7 @@ // See https://kit.svelte.dev/docs/types#app // for information about these interfaces +import "unplugin-icons/types/svelte"; + declare global { namespace App { interface Locals { diff --git a/src/lib/components/summary/GroupsCarousel.svelte b/src/lib/components/summary/GroupsCarousel.svelte new file mode 100644 index 00000000..194a3573 --- /dev/null +++ b/src/lib/components/summary/GroupsCarousel.svelte @@ -0,0 +1,18 @@ + + +
+ {#each $groups as group (group.id)} + +
+

+ {group.name} +

+
+
+ {/each} +
diff --git a/src/lib/components/summary/ScheduledMeetingsList.svelte b/src/lib/components/summary/ScheduledMeetingsList.svelte new file mode 100644 index 00000000..5fce228b --- /dev/null +++ b/src/lib/components/summary/ScheduledMeetingsList.svelte @@ -0,0 +1,69 @@ + + +{#each Object.keys(sortedMeetings) as date} +
+

{convertIsoToWeekdayDate(date)}

+ +
+ {#each sortedMeetings[date] as meeting} +
+
+
+ +

+ {meeting.name} +

+
+ +
+

+ + {convertTo12HourFormat(meeting.startTime)} - {convertTo12HourFormat( + meeting.endTime, + )} +

+

+ + {meeting.location} +

+
+
+
+ +
+ + Yes + No + Maybe + +
+
+ {/each} +
+
+{/each} diff --git a/src/lib/components/summary/UnscheduledMeetingsList.svelte b/src/lib/components/summary/UnscheduledMeetingsList.svelte new file mode 100644 index 00000000..3bd873a6 --- /dev/null +++ b/src/lib/components/summary/UnscheduledMeetingsList.svelte @@ -0,0 +1,46 @@ + + +
+ {#each sortedMeetings as meeting} +
+
+
+ +

+ {meeting.name} +

+
+ +
+

+ + {convertIsoToDate(meeting.startDate)} - {convertIsoToDate(meeting.endDate)} +

+

+ + {convertTo12HourFormat(meeting.startTime)} - {convertTo12HourFormat(meeting.endTime)} +

+

+ + {meeting.location} +

+
+
+
+
+ {/each} +
diff --git a/src/lib/stores/summaryStores.ts b/src/lib/stores/summaryStores.ts new file mode 100644 index 00000000..f627d08f --- /dev/null +++ b/src/lib/stores/summaryStores.ts @@ -0,0 +1,132 @@ +import { writable } from "svelte/store"; + +import type { Group, ScheduledMeeting, UnscheduledMeeting } from "$lib/types/meetings"; + +const dummyGroups: Group[] = [ + { + name: "AntAlmanac", + id: 1, + img: "https://hips.hearstapps.com/goodhousekeeping/assets/17/30/pembroke-welsh-corgi.jpg", + link: "https://google.com", + }, + { + name: "Group Two", + id: 2, + img: "https://hips.hearstapps.com/goodhousekeeping/assets/17/30/pembroke-welsh-corgi.jpg", + link: "https://google.com", + }, + { + name: "Group Three", + id: 3, + img: "https://hips.hearstapps.com/goodhousekeeping/assets/17/30/pembroke-welsh-corgi.jpg", + link: "https://google.com", + }, + { + name: "Group Three", + id: 4, + img: "https://hips.hearstapps.com/goodhousekeeping/assets/17/30/pembroke-welsh-corgi.jpg", + link: "https://google.com", + }, + { + name: "Group Three", + id: 5, + img: "https://hips.hearstapps.com/goodhousekeeping/assets/17/30/pembroke-welsh-corgi.jpg", + link: "https://google.com", + }, + { + name: "Group Three", + id: 6, + img: "https://hips.hearstapps.com/goodhousekeeping/assets/17/30/pembroke-welsh-corgi.jpg", + link: "https://google.com", + }, +]; + +const dummyScheduledMeetings: ScheduledMeeting[] = [ + { + name: "AntAlmanac", + id: 1, + link: "https://google.com", + date: "2023-12-08", + startTime: "11:00", + endTime: "13:30", + attending: "Yes", + location: "CSL 8", + }, + { + name: "Meeting Two", + id: 2, + link: "https://google.com", + date: "2023-12-08", + startTime: "8:00", + endTime: "15:00", + attending: "No", + location: "CSL 8", + }, + { + name: "Meeting Three", + id: 3, + link: "https://google.com", + date: "2023-12-09", + startTime: "8:00", + endTime: "15:00", + attending: "Yes", + location: "CSL 8", + }, + { + name: "Meeting Four", + id: 4, + link: "https://google.com", + date: "2023-12-09", + startTime: "8:00", + endTime: "15:00", + attending: "Maybe", + location: "CSL 8", + }, +]; + +const dummyUnscheduledMeetings: UnscheduledMeeting[] = [ + { + name: "Unscheduled ZotMeet", + id: 1, + link: "https://google.com", + startDate: "2023-12-03", + endDate: "2023-12-09", + startTime: "11:00", + endTime: "13:30", + location: "CSL 8", + }, + { + name: "Meeting Dos", + id: 2, + link: "https://google.com", + startDate: "2023-12-03", + endDate: "2023-12-09", + startTime: "8:00", + endTime: "15:00", + location: "CSL 8", + }, + { + name: "Meeting Tres", + id: 3, + link: "https://google.com", + startDate: "2023-12-08", + endDate: "2023-12-20", + startTime: "8:00", + endTime: "15:00", + location: "CSL 8", + }, + { + name: "Meeting Quatro", + id: 4, + link: "https://google.com", + startDate: "2023-12-08", + endDate: "2023-12-19", + startTime: "8:00", + endTime: "15:00", + location: "CSL 8", + }, +]; + +export const groups = writable(dummyGroups); +export const scheduledMeetings = writable(dummyScheduledMeetings); +export const unscheduledMeetings = writable(dummyUnscheduledMeetings); diff --git a/src/lib/types/meetings.ts b/src/lib/types/meetings.ts new file mode 100644 index 00000000..ad6105da --- /dev/null +++ b/src/lib/types/meetings.ts @@ -0,0 +1,25 @@ +export type Group = { name: string; id: number; img: string; link: string }; + +export type Meeting = ScheduledMeeting | UnscheduledMeeting; + +export type ScheduledMeeting = { + name: string; + id: number; + link: string; + date: string; + startTime: string; + endTime: string; + attending: string; + location: string; +}; + +export type UnscheduledMeeting = { + name: string; + id: number; + link: string; + startDate: string; + endDate: string; + startTime: string; + endTime: string; + location: string; +}; diff --git a/src/lib/utils/summary-helpers.ts b/src/lib/utils/summary-helpers.ts new file mode 100644 index 00000000..fe89f5f9 --- /dev/null +++ b/src/lib/utils/summary-helpers.ts @@ -0,0 +1,99 @@ +import type { Meeting, ScheduledMeeting, UnscheduledMeeting } from "$lib/types/meetings"; + +export function convertIsoToDate(isoDateString: string): string { + const options: Intl.DateTimeFormatOptions = { + month: "short", + day: "numeric", + }; + + const date = new Date(isoDateString); + return date.toLocaleDateString("en-US", { ...options, timeZone: "UTC" }); +} + +export function convertIsoToWeekdayDate(isoDateString: string): string { + const options: Intl.DateTimeFormatOptions = { + weekday: "short", + month: "short", + day: "numeric", + }; + + const date = new Date(isoDateString); + return date.toLocaleDateString("en-US", { ...options, timeZone: "UTC" }); +} + +export function convertTo12HourFormat(time: string): string { + const [hours, minutes] = time.split(":"); + let period = "am"; + + let hours12 = parseInt(hours, 10); + + if (hours12 >= 12) { + period = "pm"; + if (hours12 > 12) { + hours12 -= 12; + } + } + + return `${hours12}:${minutes} ${period}`; +} + +export function groupAndSortScheduledMeetings(scheduledMeetings: ScheduledMeeting[]) { + const groupedMeetings = scheduledMeetings.reduce( + (groups: Record, meeting) => { + const date = meeting.date; + if (!groups[date]) { + groups[date] = []; + } + groups[date].push(meeting); + return groups; + }, + {}, + ); + + for (const date in groupedMeetings) { + groupedMeetings[date] = sortScheduledMeetingsByDateAndTime(groupedMeetings[date]); + } + + return groupedMeetings; +} + +export function sortScheduledMeetingsByDateAndTime(scheduledMeetings: ScheduledMeeting[]) { + return scheduledMeetings.sort((a, b) => { + const dateComparison = a.date.localeCompare(b.date); + + if (dateComparison === 0) { + return sortMeetingsByTime(a, b); + } + + return dateComparison; + }); +} + +export function sortUnscheduledMeetingsByDateAndTime(unscheduledMeetings: UnscheduledMeeting[]) { + return unscheduledMeetings.sort((a, b) => { + const startDateComparison = a.startDate.localeCompare(b.startDate); + + if (startDateComparison === 0) { + const endDateComparison = a.endDate.localeCompare(b.endDate); + + if (endDateComparison === 0) { + return sortMeetingsByTime(a, b); + } + return endDateComparison; + } + return startDateComparison; + }); +} + +function sortMeetingsByTime(meetingA: Meeting, meetingB: Meeting) { + const startTimeA = meetingA.startTime.split(":"); + const startTimeB = meetingB.startTime.split(":"); + const startTimeComparison = Number(startTimeA[0]) - Number(startTimeB[0]); + + if (startTimeComparison === 0) { + const endTimeA = meetingA.endTime.split(":"); + const endTimeB = meetingB.endTime.split(":"); + return Number(endTimeA[0]) - Number(endTimeB[0]) || Number(endTimeA[1]) - Number(endTimeB[1]); + } + return startTimeComparison; +} diff --git a/src/routes/summary/+page.svelte b/src/routes/summary/+page.svelte new file mode 100644 index 00000000..590b149e --- /dev/null +++ b/src/routes/summary/+page.svelte @@ -0,0 +1,40 @@ + + + + +
+
+

Groups

+ +
+ +
+ +
+

Meetings

+
+ Scheduled + Unscheduled +
+
+ + + {#if tabSet === 0} +
+ {:else if tabSet === 1} +
+ +
+ {/if} +
+
+
+
diff --git a/vite.config.ts b/vite.config.ts index 49c9e7c1..23b6d717 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -1,8 +1,14 @@ import { sveltekit } from "@sveltejs/kit/vite"; -import { defineConfig } from "vitest/config"; +import Icons from "unplugin-icons/vite"; +import { defineProject } from "vitest/config"; -export default defineConfig({ - plugins: [sveltekit()], +export default defineProject({ + plugins: [ + sveltekit(), + Icons({ + compiler: "svelte", + }), + ], test: { include: ["src/**/*.{test,spec}.{js,ts}"], },