Skip to content

Commit

Permalink
Add Select Device page basic filters
Browse files Browse the repository at this point in the history
Add Select Device page basic filters
  • Loading branch information
pkong-ds authored May 25, 2024
2 parents 4e0e57b + 0959d4e commit ac8454f
Show file tree
Hide file tree
Showing 26 changed files with 1,226 additions and 807 deletions.
6 changes: 6 additions & 0 deletions public/Images/types/all-white.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
6 changes: 6 additions & 0 deletions public/Images/types/all.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
4 changes: 4 additions & 0 deletions public/Images/types/computer-white.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/Images/types/phone-white.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/Images/types/phone.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/Images/types/tablet-white.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions public/Images/types/tablet.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
5 changes: 5 additions & 0 deletions public/Images/types/tv-white.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions public/Images/types/wearables-white.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
253 changes: 57 additions & 196 deletions public/scripts/device.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,28 +13,19 @@ class RootViewModel {
searchText = "";
shouldShowSearchSuggestionList = false;
shouldShowFullscreenSearchOnBelowLg = false;
selectedBrand = "all";
_deviceList;
_brandDeviceList;

constructor(deviceList) {
constructor(deviceList, brandDeviceList) {
mobx.makeObservable(this, {
searchText: mobx.observable,
shouldShowSearchSuggestionList: mobx.observable,
shouldShowFullscreenSearchOnBelowLg: mobx.observable,
suggestedDeviceList: mobx.computed,
shouldShowSearchClear: mobx.computed,
selectedBrand: mobx.observable,
});
this._deviceList = deviceList;
}

get suggestedDeviceList() {
const targetText = this.searchText.toLowerCase().replace(/\s/g, "");
return this._deviceList.filter(({ name }) => {
return name.toLowerCase().replace(/\s/g, "").includes(targetText);
});
}

get shouldShowSearchClear() {
return this.searchText.trim().length > 0;
this._brandDeviceList = brandDeviceList;
}
}

Expand Down Expand Up @@ -92,200 +83,70 @@ function handleMouseLeaveDeviceGrid(e) {
cycleDeviceImages.uncycle(e.target);
}

function handleClickBrandLabelBtn(e, viewModel) {
const brand = e.target.dataset.brandName;
viewModel.selectedBrand = brand;
}

function main() {
const searchInput = document.querySelector(".select-device__search-input");
const searchClearBtn = document.querySelector(
".select-device__search-clear-btn",
);
const searchSuggestionList = document.querySelector(".suggestion-list");
const fullscreenSearch = document.querySelector(".fullscreen-search");
const fullscreenSearchInput = document.querySelector(
".fullscreen-search__search-input",
);
const fullscreenSearchCancelBtn = document.querySelector(
".fullscreen-search__search-cancel-btn",
);
const fullscreenSearchSuggestionList = document.querySelector(
".fullscreen-suggestion-list",
);
const deviceTagList = document.querySelector(".device-tag-list");
const deviceSectionList = document.querySelector(".device-section-list");
const deviceGrids = document.querySelectorAll(".device-grid");
const brands = document.querySelectorAll(".device-brand-list__item-button");

const { deviceList } = (function () {
var deviceType = window.location.href.split("/").at(-2);
if (deviceType == "type") {
deviceType = window.location.href.split("/").at(-1).split("#").at(0);
}
const deviceJson = window.deviceData;
const deviceList = deviceJson.device_cat[deviceType];
return {
deviceList,
};
})();

window.deviceList = deviceList;

const viewModel = new RootViewModel(deviceList);
const viewModel = new RootViewModel(
window.deviceList,
window.brandDeviceList,
);
if (isDebug) {
window.viewModel = viewModel;
}

mobx.reaction(
() => viewModel.selectedBrand,
(selectedBrand) => {
// Show non-selected styles for all brand tags
const allBrandListItems = document.querySelectorAll(
".device-brand-list__item-button",
);
allBrandListItems.forEach((n) =>
n.classList.remove("device-brand-list__item-button--selected"),
);

// Show selected styles for target brand tags
const targetBrandListItem = document.querySelector(
`#device-brand-list__item-button__${selectedBrand}`,
);

targetBrandListItem.classList.add(
"device-brand-list__item-button--selected",
);

// Hide all brand sections
const allBrandSections = document.querySelectorAll(
".device-section-list__item",
);
allBrandSections.forEach((n) => n.classList.add("d-none"));

// Show target brand sections
const targetBrandSections =
selectedBrand === "all"
? allBrandSections
: [
document.querySelector(
`#device-section-list__item-${selectedBrand}`,
),
];
targetBrandSections.forEach((n) => n.classList.remove("d-none"));
},
);

deviceGrids.forEach((deviceGrid) => {
deviceGrid.addEventListener("mouseenter", handleMouseEnterDeviceGrid);
deviceGrid.addEventListener("mouseleave", handleMouseLeaveDeviceGrid);
});

searchInput.addEventListener("input", (e) => {
viewModel.searchText = e.target.value;
});

searchInput.addEventListener("click", (e) => {
viewModel.shouldShowFullscreenSearchOnBelowLg = true;
});

searchInput.addEventListener("focus", (e) => {
viewModel.shouldShowSearchSuggestionList = true;
});

searchInput.addEventListener("blur", (e) => {
// allow click suggestion list before dismissing the list
setTimeout(() => {
viewModel.shouldShowSearchSuggestionList = false;
}, 200);
});

// finish input
searchInput.addEventListener("change", (e) => {
viewModel.shouldShowSearchSuggestionList = false;
viewModel.shouldShowFullscreenSearchOnBelowLg = false;
});

searchClearBtn.addEventListener("click", () => {
viewModel.searchText = "";
});

searchSuggestionList.addEventListener("click", (e) => {
viewModel.searchText = e.target.innerText;
});

fullscreenSearchInput.addEventListener("input", (e) => {
viewModel.searchText = e.target.value;
});

fullscreenSearchInput.addEventListener("keyup", (e) => {
if (e.key === "Enter") {
viewModel.shouldShowFullscreenSearchOnBelowLg = false;
viewModel.shouldShowSearchSuggestionList = false;
e.target.blur();
}
});

fullscreenSearchCancelBtn.addEventListener("click", () => {
viewModel.shouldShowFullscreenSearchOnBelowLg = false;
viewModel.shouldShowSearchSuggestionList = false;
viewModel.searchText = "";
});

fullscreenSearchSuggestionList.addEventListener("click", (e) => {
viewModel.shouldShowFullscreenSearchOnBelowLg = false;
viewModel.shouldShowSearchSuggestionList = false;
viewModel.searchText = e.target.innerText;
});

// observe viewModel: searchText, suggestedDeviceList
mobx.autorun(() => {
const searchText = viewModel.searchText;
const suggestedDeviceList = viewModel.suggestedDeviceList;
const suggestedDeviceIds = suggestedDeviceList.map((device) => device.id);

// update search input
searchInput.value = searchText;
fullscreenSearchInput.value = searchText;

// update device tag list
const deviceTagNodes = Array.from(deviceTagList.children);
deviceTagNodes.forEach((deviceTagNode) => {
const deviceId = deviceTagNode.dataset.deviceId;
if (suggestedDeviceIds.includes(deviceId)) {
deviceTagNode.classList.remove("d-none");
} else {
deviceTagNode.classList.add("d-none");
}
});

// update device section list
const deviceSectionListItemNodes = Array.from(deviceSectionList.children);
deviceSectionListItemNodes.forEach((deviceSectionListItemNode) => {
if (
deviceSectionListItemNode.classList.contains(
"device-section-list__request-device",
)
) {
return;
}
const deviceId = deviceSectionListItemNode.dataset.deviceId;
if (suggestedDeviceIds.includes(deviceId)) {
deviceSectionListItemNode.classList.remove("d-none");
} else {
deviceSectionListItemNode.classList.add("d-none");
}
});

// update search suggestion list
const suggestionNodes = Array.from(searchSuggestionList.children);
suggestionNodes.forEach((suggestionNode) => {
const deviceId = suggestionNode.dataset.deviceId;
if (suggestedDeviceIds.includes(deviceId)) {
suggestionNode.classList.remove("d-none");
} else {
suggestionNode.classList.add("d-none");
}
});

// update fullscreen search suggestion list
const fullscreenSuggestionNodes = Array.from(
fullscreenSearchSuggestionList.children,
brands.forEach((brand) => {
brand.addEventListener("click", (e) =>
handleClickBrandLabelBtn(e, viewModel),
);
fullscreenSuggestionNodes.forEach((suggestionNode) => {
const deviceId = suggestionNode.dataset.deviceId;
if (suggestedDeviceIds.includes(deviceId)) {
suggestionNode.classList.remove("d-none");
} else {
suggestionNode.classList.add("d-none");
}
});
});

// observer viewModel: shouldShowSearchClear
mobx.autorun(() => {
if (viewModel.shouldShowSearchClear) {
searchClearBtn.classList.remove("d-none");
} else {
searchClearBtn.classList.add("d-none");
}
});

// observer viewModel: shouldShowSearchSuggestionList
mobx.autorun(() => {
if (viewModel.shouldShowSearchSuggestionList) {
searchSuggestionList.classList.remove("d-none");
} else {
searchSuggestionList.classList.add("d-none");
}
});

// observer viewModel: shouldShowFullscreenSearchOnBelowLg
mobx.autorun(() => {
if (viewModel.shouldShowFullscreenSearchOnBelowLg && screen.width < 992) {
fullscreenSearch.classList.remove("d-none");
setTimeout(() => {
fullscreenSearchInput.focus();
}, 100);
document.body.classList.add("body--modal-open");
} else {
fullscreenSearch.classList.add("d-none");
document.body.classList.remove("body--modal-open");
}
});
}
4 changes: 2 additions & 2 deletions src/components/ListItem.astro
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import { DEVICE_MANAGER } from "../scripts/deviceManager";
import type { Device } from "../scripts/model";
const { type } = Astro.props;
const deviceArray: Device[] = DEVICE_MANAGER.getDevicesBytype(type);
const deviceArray: Device[] = DEVICE_MANAGER.getDeviceListByModel(type);
---

<h2>{type}</h2>
Expand All @@ -22,7 +22,7 @@ const deviceArray: Device[] = DEVICE_MANAGER.getDevicesBytype(type);
</thead>
<tbody>
{
deviceArray.map((device) => {
deviceArray.map((device: Device) => {
return (
<tr>
<td>
Expand Down
Loading

0 comments on commit ac8454f

Please sign in to comment.