Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

議程篩選&收藏議程 #20

Open
wants to merge 21 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
3dddedd
Add feature: mark sessions
mirumodapon Mar 3, 2023
c46a3d6
Fix: mark icon in mobile screen styling
mirumodapon Mar 4, 2023
c06756a
Modify: try another position for session mark icon
mirumodapon Mar 4, 2023
d7d6048
Feat: collect session and my collection page
mirumodapon Mar 5, 2023
74be48f
Feat: Session filter in session page
mirumodapon Mar 7, 2023
a1557f7
Feat: beautify filter selector
mirumodapon Mar 8, 2023
a197f17
Fix: collection page can't show current sessions
mirumodapon Mar 10, 2023
a4ddace
Merge branch 'feat#12/filter-sessions' into dev
mirumodapon Mar 10, 2023
a5485b1
Merge branch 'feat#11/save-session' into dev
mirumodapon Mar 10, 2023
f3c9f96
Feat: add filter for collect session
mirumodapon Mar 10, 2023
a62247a
Feat: remove speaker filter options
mirumodapon Mar 22, 2023
f6e98b9
Feat: use query with session filter
mirumodapon Mar 22, 2023
334aa97
Refactor: function of filter options generate
mirumodapon Mar 22, 2023
fd253aa
Perf: use watch method to replace update method
mirumodapon Apr 16, 2023
8bac169
Perf: put variable into computed method(Collection.vue)
mirumodapon Apr 16, 2023
b900dea
Perf: rename the marked variable to favorite
mirumodapon Jun 8, 2023
7e1ecf8
Perf: filter select change method
mirumodapon Jun 8, 2023
d608660
Perf: use writable computed on filter value
mirumodapon Jun 8, 2023
de32467
Perf: push query in filtervalue setter func
mirumodapon Jun 29, 2023
4cb77db
Style: code style for clean code
mirumodapon Jun 29, 2023
b029e84
Improve session page
yoyo930021 Jul 1, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion locales/en/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"blog": "Blog",
"press-release": "Press Release",
"coc": "CoC",
"languageSwitch": "EN"
"languageSwitch": "EN",
"collection": "My Collection"
},
"offline": "Offline mode",
"footer": {
Expand Down
8 changes: 8 additions & 0 deletions locales/en/session.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,13 @@
"room-status": {
"vacancy": "Available",
"full": "Full"
},
"filter": {
"speakers": "Speaker",
"room": "Room",
"type": "Type",
"tags": "Tag",
"all": "All",
"collection": "Collection"
}
}
3 changes: 2 additions & 1 deletion locales/zh-TW/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
"blog": "部落格",
"press-release": "媒體專區",
"coc": "社群守則",
"languageSwitch": "繁"
"languageSwitch": "繁",
"collection": "我的收藏"
},
"offline": "離線模式",
"footer": {
Expand Down
8 changes: 8 additions & 0 deletions locales/zh-TW/session.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,13 @@
"room-status": {
"vacancy": "尚有空位",
"full": "沒有空位"
},
"filter": {
"speakers": "講者",
"room": "會議室",
"type": "類別",
"tags": "標籤",
"all": "全部",
"collection": "我的收藏"
}
}
1 change: 1 addition & 0 deletions src/assets/images/arrow-down-dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/assets/images/arrow-down-light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
8 changes: 8 additions & 0 deletions src/assets/scss/components/session/_schedule-item.scss
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
color: var(--color-text);
background-color: var(--color-session-background);
text-decoration: none;
position: relative;
padding: 5px;

.content-section {
position: sticky;
Expand Down Expand Up @@ -100,5 +102,11 @@
}
}
}

.mark-icon {
position: absolute;
right: 5px;
top :5px;
}
}
}
59 changes: 59 additions & 0 deletions src/assets/scss/components/session/_session-filter.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@



@mixin session-filter {
.session-filter {
width: 100vw;
position: sticky;
left: 0;
display: grid;
-moz-box-pack: center;
justify-content: center;
padding: 10px 0 30px;

@include smAndUp {
grid-template-columns: repeat(4, 160px);
gap: 25px 15px;

}

@include smOnly {
grid-template-columns: repeat(3, 160px);
gap: 25px 50px;

}

@include xsOnly {
grid-template-columns: repeat(2, 160px);
gap: 25px 15px;
padding: 30px 0;
border-bottom: 1px solid var(--color-filter-border);
}

select {
width: 120px;
margin: 5px 0;
display: block;
border-radius: 8px;
border: 1px solid var(--color-filter-border);
box-shadow: none;

background-image: var(--color-filter-icon);
background-size: contain;
background-repeat: no-repeat;
background-position: right;
background-color: var(--color-filter-background);

color: var(--color-filter-font);
appearance: none;
padding: 5px;
font-size: .85rem;

&:focus {
outline: none;
}
}


}
}
43 changes: 43 additions & 0 deletions src/assets/scss/pages/collection.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@


@import "../shared";
@import "../components/session/schedule-item";


@mixin theme-colors {
@include theme-colors-of("light", "#collection") {
--color-primary: #{$coscup-green};
--color-session-background: #{lighten($coscup-green, 56)};
}
@include theme-colors-of("dark", "#collection") {
--color-primary: #{lighten($coscup-green, 8)};
--color-session-background: #{lighten($background-dark, 8)};
}
}

@include theme-colors;

@include page("collection") {
@include schedule-item;


.caption {
display: flex;
justify-content: center;
align-items: center;
font-size: 1.4rem;
margin: 20px auto;
padding: 10px 0;

svg {
cursor: pointer;
}

}


.session-list {
width: 90%;
margin: 10px auto;
}
}
10 changes: 10 additions & 0 deletions src/assets/scss/pages/session.scss
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
@import "../components/session/schedule-navbar";
@import "../components/session/schedule-table";
@import "../components/session/schedule-list";
@import "../components//session//session-filter";

@mixin session-theme-colors {
// @include theme-colors-of("all", "#session") {
Expand All @@ -22,6 +23,10 @@
$background-light,
$alpha: -0.1
)};
--color-filter-background: #{lighten($coscup-green, 56)};
--color-filter-font: #{$text-light};
--color-filter-border: #{$coscup-secondary};
--color-filter-icon: url('@/assets/images/arrow-down-light.svg');
}

@include theme-colors-of("dark", "#session") {
Expand All @@ -30,6 +35,10 @@
--color-list-time-background: #{$background-dark};
--color-nav-background: #{$background-dark};
--color-room-cell-background: #{adjust-color($background-dark, $alpha: -0.1)};
--color-filter-background: #{$background-dark};
--color-filter-font: #{$text-dark};
--color-filter-border: #{$background-light};
--color-filter-icon: url('@/assets/images/arrow-down-dark.svg');
}
}

Expand All @@ -39,4 +48,5 @@
@include schedule-navbar;
@include schedule-table;
@include schedule-list;
@include session-filter;
}
15 changes: 14 additions & 1 deletion src/components/Session/ScheduleItem.vue
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@
</span>
</div>
</section>
<span class="mark-icon" @click="handleMarkIconOnClick">
<icon-mdi-bookmark v-if="isMark"></icon-mdi-bookmark>
<icon-mdi-bookmark-outline v-else></icon-mdi-bookmark-outline>
</span>
</router-link>
</template>

Expand All @@ -57,6 +61,7 @@ import { useI18n } from 'vue-i18n'
import { Locale } from '@/modules/i18n'
import { formatTimeString } from '@/modules/session/utils'
import { useSession } from '@/modules/session'
import { switchSessionMarkData } from '@/modules/session/logic'

export default defineComponent({
name: 'ScheduleItem',
Expand Down Expand Up @@ -91,6 +96,12 @@ export default defineComponent({
// const isFull = computed(() => !!(roomsStatus.value[session.value.room.id]))
const isFull = ref(false)
const statusText = computed(() => t(`session['room-status'].${isFull.value ? 'full' : 'vacancy'}`))
const isMark = computed(() => session.value.isMark)

const handleMarkIconOnClick = (e: Event) => {
switchSessionMarkData(session.value)
return e.preventDefault()
}

return {
isLoaded,
Expand All @@ -104,7 +115,9 @@ export default defineComponent({
language,
room,
isFull,
statusText
statusText,
isMark,
handleMarkIconOnClick
}
}
})
Expand Down
44 changes: 44 additions & 0 deletions src/components/Session/SessionFilter.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
<template>
<article class="session-filter">
<section v-for="filter in filterOptions" :key="filter.label">
<label>{{ t(`session.filter.${filter.label}`) }}: </label>
<select v-model="filterValue[filter.label]">
<option value="*">{{ t("session.filter.all") }}</option>
<option v-for="option in filter.options" :key="option.id" :value="option.id">
{{ option.name[locale] }}
</option>
</select>
</section>
</article>
</template>
<script lang="ts">
import { defineComponent, watch } from 'vue'
import { useSession } from '@/modules/session'
import { useRoute, useRouter } from 'vue-router'
import { useI18n } from 'vue-i18n'

export default defineComponent({
name: 'SessionFilter',
setup () {
const { filterOptions, filterValue } = useSession()
const { t, locale } = useI18n()
const { query } = useRoute()
const router = useRouter()

filterValue.value = { ...filterValue.value, ...query }

watch(filterValue.value, (value) => {
yoyo930021 marked this conversation as resolved.
Show resolved Hide resolved
const newFilterValue = Object.entries(value).filter(([_, value]) => value !== '*')
router.push({ query: Object.fromEntries(newFilterValue), replace: true })
})

return {
filterOptions,
filterValue,
locale,
t
}
}
})

</script>
45 changes: 41 additions & 4 deletions src/modules/session/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
// https://opensource.org/licenses/MIT
import { computed, InjectionKey, Ref, ref } from 'vue'
import { createModuleHook, useSetupCtx } from '../utils'
import { TIMEZONE_OFFSET, ROOM_ORDER, generateScheduleList, generateScheduleTable, getScheduleDays, transformRawData } from './logic'
import { ScheduleElement, SessionsMap, RoomId, ScheduleTable, ScheduleList, Session, SessionId, RoomsMap, Room, RoomsStatusMap, RoomStatus } from './types'
import { TIMEZONE_OFFSET, ROOM_ORDER, generateScheduleList, generateScheduleTable, getScheduleDays, transformRawData, generateFilterOption } from './logic'
import { ScheduleElement, SessionsMap, RoomId, ScheduleTable, ScheduleList, Session, SessionId, RoomsMap, Room, RoomsStatusMap, RoomStatus, FilterOptions, FilterValue } from './types'
import { fixedTimeZoneDate } from './utils'
import { useProgress } from '../progress'
import io, { Socket } from 'socket.io-client'
Expand All @@ -18,7 +18,10 @@ interface UseSession {
table: ScheduleTable;
list: ScheduleList;
}[]>;
filterOptions: Ref<FilterOptions>;
filterValue: Ref<FilterValue>;
roomsStatusMap: Ref<RoomsStatusMap | null>;
sessionsMap: Ref<SessionsMap | null>;
getSessionById: (id: SessionId) => Session;
getRoomById: (id: RoomId) => Room;
getRoomStatusById: (id: RoomId) => RoomStatus;
Expand All @@ -36,6 +39,7 @@ const _useSession = (): UseSession => {
const sessionsMap = ref<SessionsMap | null>(null)
const roomsMap = ref<RoomsMap | null>(null)
const isLoaded = ref<boolean>(false)
const filterOptions = ref<FilterOptions>([])

const load = async () => {
if (isLoaded.value) return
Expand All @@ -48,19 +52,49 @@ const _useSession = (): UseSession => {
roomsMap.value = _roomsMap
isClient && await prepareRoomStatus()
isLoaded.value = true
filterOptions.value = generateFilterOption(_rawData)
done()

const markSessions: SessionId[] = JSON.parse(window.localStorage.getItem('MARK_SESSIONS') ?? '[]')
for (const id in sessionsMap.value) {
const session: Session = sessionsMap.value?.[id]
session.isMark = markSessions.includes(id)
}
}

isClient && load()

const currentDayIndex = ref(0)
const filterValue = ref<FilterValue>({ room: '*', tags: '*', type: '*', collection: '*' })
const daysSchedule = computed(() => {
if (scheduleElements.value === null) return []
return getScheduleDays(scheduleElements.value)
.map((scheduleDay) => {
const day = scheduleDay.day
const table = generateScheduleTable(scheduleDay.elements)
const list = generateScheduleList(scheduleDay.elements)
const elements = scheduleDay.elements.filter(s => {
const session = getSessionById(s.session)

for (const filter of Object.entries(filterValue.value)) {
yoyo930021 marked this conversation as resolved.
Show resolved Hide resolved
if (filter[1] === '*') continue

switch (filter[0]) {
case 'tags':
if (!session[filter[0]].find(x => x.id === filter[1])) return false
else continue
case 'room':
case 'type':
if (session[filter[0]].id !== filter[1]) return false
else continue
case 'collection':
if (!session.isMark) return false
else continue
}
}

return true
})
const table = generateScheduleTable(elements)
const list = generateScheduleList(elements)
return { day, table, list }
})
})
Expand Down Expand Up @@ -127,6 +161,9 @@ const _useSession = (): UseSession => {
currentDayIndex,
daysSchedule,
roomsStatusMap,
filterOptions,
filterValue,
sessionsMap,
getSessionById,
getRoomById,
getRoomStatusById,
Expand Down
Loading