-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #21 from Furiiku/reviews-and-store_fix-feature
Find reviews and clear missing stores features
- Loading branch information
Showing
11 changed files
with
618 additions
and
61 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,39 @@ | ||
/* eslint-disable no-multi-spaces */ | ||
/* eslint-disable @typescript-eslint/key-spacing */ | ||
|
||
import { type Avatar } from './me' | ||
import { type Product } from './order' | ||
|
||
export interface ReviewResponse { | ||
reviews: Review[] | ||
hypes: unknown[] | ||
totalReviewCount: number | ||
totalHypeCount: number | ||
reviewsPerPage: number | ||
ratingReviewCount: number | ||
currentReviewCount: number | ||
} | ||
|
||
export interface Review { | ||
id: number | ||
text: string | ||
rating: number | ||
upvotes: number | ||
downvotes: number | ||
verifiedPurchase: boolean | ||
createdAt: number | ||
isAnonymous: boolean | ||
isEmployee: boolean | ||
product: Product | ||
isHype: boolean | ||
user: ReviewUser | ||
} | ||
|
||
export interface ReviewUser { | ||
id: number | ||
username: string | ||
isPublicProfile: boolean | ||
knighthood: number[] | ||
rankLevel: number | ||
avatar: Avatar | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export interface DeleteStoreResponse { | ||
status: string | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
export function findInjectPath (paths: string[]): HTMLElement | null { | ||
let dom = null | ||
paths.forEach(path => { | ||
const d = document.querySelector(path) | ||
if (d) { | ||
dom = d | ||
} | ||
}) | ||
|
||
return dom | ||
} | ||
|
||
export function addDataToDiv (headerText: string, domObject: Element): HTMLDivElement { | ||
const div = document.createElement('div') | ||
div.className = 'order my-4' | ||
|
||
const table = document.createElement('table') | ||
table.className = 'table table-condensed' | ||
|
||
const tbody = document.createElement('tbody') | ||
|
||
const tr = document.createElement('tr') | ||
tr.className = 'order-id-wrap' | ||
|
||
const td = document.createElement('td') | ||
td.textContent = headerText | ||
|
||
tr.appendChild(td) | ||
tbody.appendChild(tr) | ||
table.appendChild(tbody) | ||
div.appendChild(table) | ||
|
||
const div1 = document.createElement('div') | ||
const div2 = document.createElement('div') | ||
const orderProgression = document.createElement('div') | ||
const innerContainer = document.createElement('div') | ||
const orderStatusEvent = document.createElement('div') | ||
const icon = document.createElement('div') | ||
const header = document.createElement('h3') | ||
const secondary = document.createElement('div') | ||
|
||
div1.appendChild(div2) | ||
div2.appendChild(orderProgression) | ||
orderProgression.appendChild(innerContainer) | ||
innerContainer.appendChild(orderStatusEvent) | ||
orderStatusEvent.appendChild(icon) | ||
orderStatusEvent.appendChild(header) | ||
orderStatusEvent.appendChild(secondary) | ||
secondary.appendChild(domObject) | ||
|
||
header.className = 'level-two-heading' | ||
icon.className = 'icon' | ||
|
||
header.textContent = '' | ||
|
||
div.appendChild(div1) | ||
|
||
return div | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,38 @@ | ||
export function timeAgo (unixTimestamp: number): string { | ||
const now = Math.floor(Date.now() / 1000) | ||
const secondsAgo = now - unixTimestamp | ||
|
||
const timeUnits = [ | ||
{ singular: 'år', plural: 'år', seconds: 365 * 24 * 60 * 60 }, | ||
{ singular: 'månad', plural: 'månader', seconds: 30 * 24 * 60 * 60 }, | ||
{ singular: 'dag', plural: 'dagar', seconds: 24 * 60 * 60 }, | ||
{ singular: 'timma', plural: 'timmar', seconds: 60 * 60 }, | ||
{ singular: 'minut', plural: 'minuter', seconds: 60 }, | ||
] | ||
|
||
for (const { singular, plural, seconds } of timeUnits) { | ||
const count = Math.floor(secondsAgo / seconds) | ||
if (count >= 1) { | ||
return count === 1 ? `1 ${singular} sedan` : `${count} ${plural} sedan` | ||
} | ||
} | ||
|
||
return 'Just nu' | ||
} | ||
|
||
export function unixTimestampToLocale (unixTimestamp: number): string { | ||
const date = new Date(unixTimestamp * 1000) | ||
const locale = navigator.language || 'sv-SE' | ||
|
||
const options = { | ||
year: 'numeric', | ||
month: 'long', | ||
day: 'numeric', | ||
hour: 'numeric', | ||
minute: 'numeric', | ||
second: 'numeric', | ||
timeZoneName: 'short', | ||
} as Intl.DateTimeFormatOptions | ||
|
||
return new Intl.DateTimeFormat(locale, options).format(date) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
import { type ProductReview } from '../lib/api' | ||
|
||
export function getPostedReviews (reviews: ProductReview[]): ProductReview[] { | ||
return reviews.filter(orderReview => orderReview.review !== undefined) | ||
.sort((a, b) => { | ||
if (a.review && b.review) { | ||
return b.review.createdAt - a.review.createdAt | ||
} | ||
return 0 | ||
}) | ||
} | ||
|
||
export function getProductsWithoutReviews (reviews: ProductReview[]): ProductReview[] { | ||
return reviews.filter(orderReview => orderReview.review === undefined) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
import { deleteFavoriteStores } from '../lib/api' | ||
|
||
async function _clearAllStores (event: MouseEvent): Promise<void> { | ||
event.preventDefault() | ||
await deleteFavoriteStores() | ||
location.reload() | ||
} | ||
|
||
function observeDOM (): void { | ||
const targetNode = document.body | ||
|
||
const config = { childList: true, subtree: true } | ||
|
||
const callback = function (mutationsList: MutationRecord[], observer: MutationObserver): void { | ||
for (const mutation of mutationsList) { | ||
if (mutation.type === 'childList') { | ||
mutation.addedNodes.forEach((node) => { | ||
const addedNode = node as unknown as HTMLElement | ||
if (addedNode.className && addedNode.className === 'stores-map') { | ||
const storelist = addedNode.querySelector('.list-group') as HTMLDivElement | ||
if (storelist) { | ||
console.log('Found store list', storelist) | ||
const li = document.createElement('li') | ||
li.className = 'list-group-item store-list-item' | ||
const label = document.createElement('label') | ||
label.className = 'stock-favorite' | ||
label.title = 'Rensa' | ||
const checkbox = document.createElement('input') | ||
checkbox.type = 'checkbox' | ||
const span1 = document.createElement('span') | ||
span1.textContent = 'Rensa alla butiker' | ||
const link = document.createElement('a') | ||
link.href = '#' | ||
link.className = 'store-info' | ||
link.addEventListener('click', (event) => { _clearAllStores(event).catch(() => { }) }) | ||
const span2 = document.createElement('span') | ||
span2.className = 'store-location' | ||
span2.textContent = 'Löser problem med butiker som inte går att ta bort då de försvunnit' | ||
link.appendChild(span1) | ||
link.appendChild(span2) | ||
li.appendChild(label) | ||
li.appendChild(link) | ||
storelist.prepend(li) | ||
} | ||
} | ||
}) | ||
} | ||
} | ||
} | ||
|
||
const observer = new MutationObserver(callback) | ||
observer.observe(targetNode, config) | ||
} | ||
|
||
let renderedAlready = false | ||
export const renderClearFavoriteStoresUtility = (): void => { | ||
if (renderedAlready) return | ||
observeDOM() | ||
renderedAlready = true | ||
} |
Oops, something went wrong.