Even more code styling things

This commit is contained in:
Dmitriy Shishkov 2023-07-31 12:41:19 +03:00
parent 9eb30d2066
commit 9b35a54ae9
Signed by: dm1sh
GPG Key ID: 027994B0AA357688
51 changed files with 127 additions and 113 deletions

View File

@ -32,5 +32,16 @@ module.exports = {
} }
], ],
'jsx-quotes': [2, 'prefer-single'], 'jsx-quotes': [2, 'prefer-single'],
'comma-dangle': 'off',
'@typescript-eslint/comma-dangle': ['warn', {
'arrays': 'always-multiline',
'objects': 'always-multiline',
'imports': 'always-multiline',
'exports': 'always-multiline',
'functions': 'only-multiline',
'enums': 'always-multiline',
'generics': 'always-multiline',
'tuples': 'always-multiline',
}],
}, },
} }

View File

@ -6,7 +6,7 @@ const processAnnouncement = (data: AnnouncementResponse): Announcement => ({
lng: data.longtitude, lng: data.longtitude,
bestBy: data.best_by, bestBy: data.best_by,
bookedBy: data.booked_by, bookedBy: data.booked_by,
userId: data.user_id userId: data.user_id,
}) })
export { processAnnouncement } export { processAnnouncement }

View File

@ -14,7 +14,7 @@ type AnnouncementResponse = {
src: string | null, src: string | null,
metro: string, metro: string,
trashId: number | null, trashId: number | null,
booked_by: number booked_by: number,
} }
const isAnnouncementResponse = (obj: unknown): obj is AnnouncementResponse => ( const isAnnouncementResponse = (obj: unknown): obj is AnnouncementResponse => (
@ -31,7 +31,7 @@ const isAnnouncementResponse = (obj: unknown): obj is AnnouncementResponse => (
'src': 'string?', 'src': 'string?',
'metro': 'string', 'metro': 'string',
'trashId': 'number?', 'trashId': 'number?',
'booked_by': 'number' 'booked_by': 'number',
}) })
) )
@ -48,7 +48,7 @@ type Announcement = {
src: string | null, src: string | null,
metro: string, metro: string,
trashId: number | null, trashId: number | null,
bookedBy: number bookedBy: number,
} }
export type { export type {

View File

@ -3,13 +3,13 @@ import { AnnouncementResponse, isAnnouncementResponse } from '../announcement/ty
type AnnouncementsResponse = { type AnnouncementsResponse = {
list_of_announcements: AnnouncementResponse[], list_of_announcements: AnnouncementResponse[],
Success: boolean Success: boolean,
} }
const isAnnouncementsResponse = (obj: unknown): obj is AnnouncementsResponse => ( const isAnnouncementsResponse = (obj: unknown): obj is AnnouncementsResponse => (
isObject(obj, { isObject(obj, {
'list_of_announcements': obj => isArrayOf<AnnouncementResponse>(obj, isAnnouncementResponse), 'list_of_announcements': obj => isArrayOf<AnnouncementResponse>(obj, isAnnouncementResponse),
'Success': 'boolean' 'Success': 'boolean',
}) })
) )

View File

@ -1,12 +1,12 @@
import { isObject } from '../../utils/types' import { isObject } from '../../utils/types'
type BookResponse = { type BookResponse = {
Success: boolean Success: boolean,
} }
const isBookResponse = (obj: unknown): obj is BookResponse => ( const isBookResponse = (obj: unknown): obj is BookResponse => (
isObject(obj, { isObject(obj, {
'Success': 'boolean' 'Success': 'boolean',
}) })
) )

View File

@ -1,7 +1,7 @@
import { isObject } from '../../utils/types' import { isObject } from '../../utils/types'
type OsmAddressResponse = { type OsmAddressResponse = {
display_name: string display_name: string,
} }
const isOsmAddressResponse = (obj: unknown): obj is OsmAddressResponse => ( const isOsmAddressResponse = (obj: unknown): obj is OsmAddressResponse => (

View File

@ -1,12 +1,12 @@
import { isObject } from '../../utils/types' import { isObject } from '../../utils/types'
type PutAnnouncementResponse = { type PutAnnouncementResponse = {
Answer: boolean Answer: boolean,
} }
const isPutAnnouncementResponse = (obj: unknown): obj is PutAnnouncementResponse => ( const isPutAnnouncementResponse = (obj: unknown): obj is PutAnnouncementResponse => (
isObject(obj, { isObject(obj, {
'Answer': 'boolean' 'Answer': 'boolean',
}) })
) )

View File

@ -1,12 +1,12 @@
import { isObject } from '../../utils/types' import { isObject } from '../../utils/types'
type RemoveAnnouncementResponse = { type RemoveAnnouncementResponse = {
Answer: boolean Answer: boolean,
} }
const isRemoveAnnouncementResponse = (obj: unknown): obj is RemoveAnnouncementResponse => ( const isRemoveAnnouncementResponse = (obj: unknown): obj is RemoveAnnouncementResponse => (
isObject(obj, { isObject(obj, {
'Answer': 'boolean' 'Answer': 'boolean',
}) })
) )

View File

@ -11,7 +11,7 @@ type SignUpResponse = {
Success: true, Success: true,
} | { } | {
Success: false, Success: false,
Message: string Message: string,
} }
const isSignUpResponse = (obj: unknown): obj is SignUpResponse => ( const isSignUpResponse = (obj: unknown): obj is SignUpResponse => (

View File

@ -1,12 +1,12 @@
import { isObject } from '../../utils/types' import { isObject } from '../../utils/types'
type TokenResponse = { type TokenResponse = {
access_token: string access_token: string,
} }
const isTokenResponse = (obj: unknown): obj is TokenResponse => ( const isTokenResponse = (obj: unknown): obj is TokenResponse => (
isObject(obj, { isObject(obj, {
'access_token': 'string' 'access_token': 'string',
}) })
) )

View File

@ -6,11 +6,12 @@ import { Trashbox, TrashboxResponse } from './types'
const composeTrashboxURL = (position: LatLng) => ( const composeTrashboxURL = (position: LatLng) => (
API_URL + '/trashbox?' + new URLSearchParams({ API_URL + '/trashbox?' + new URLSearchParams({
lat: position.lat.toString(), lat: position.lat.toString(),
lng: position.lng.toString() lng: position.lng.toString(),
}).toString() }).toString()
) )
const processTrashbox = (data: TrashboxResponse): Trashbox[] => const processTrashbox = (data: TrashboxResponse): Trashbox[] => (
data data
)
export { composeTrashboxURL, processTrashbox } export { composeTrashboxURL, processTrashbox }

View File

@ -4,7 +4,7 @@ type Trashbox = {
Lat: number, Lat: number,
Lng: number, Lng: number,
Address: string, Address: string,
Categories: string[] Categories: string[],
} }
const isTrashbox = (obj: unknown): obj is Trashbox => ( const isTrashbox = (obj: unknown): obj is Trashbox => (
@ -12,7 +12,7 @@ const isTrashbox = (obj: unknown): obj is Trashbox => (
'Lat': 'number', 'Lat': 'number',
'Lng': 'number', 'Lng': 'number',
'Address': 'string', 'Address': 'string',
'Categories': obj => isArrayOf<string>(obj, isString) 'Categories': obj => isArrayOf<string>(obj, isString),
}) })
) )

View File

@ -10,10 +10,10 @@ const initialUser: User = import.meta.env.DEV ? { // Temporary, until api is rea
regDate: faker.date.anytime().getTime(), regDate: faker.date.anytime().getTime(),
points: Math.round(Math.random() * 1000), points: Math.round(Math.random() * 1000),
} : { } : {
id: -1, id: 1,
name: '', name: 'Вася пупкин',
regDate: 0, regDate: 0,
points: 0, points: 100,
} }
const composeUserURL = () => ( const composeUserURL = () => (

View File

@ -4,7 +4,7 @@ type User = {
id: number, id: number,
name: string, name: string,
regDate: number, regDate: number,
points: number points: number,
} }
const isUser = (obj: unknown): obj is User => ( const isUser = (obj: unknown): obj is User => (

View File

@ -1 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" style="fill: rgb(17, 17, 17); --darkreader-inline-fill: #e8e6e3;" data-darkreader-inline-fill=""><path d="M20 2H4c-1.103 0-2 .897-2 2v18l4-4h14c1.103 0 2-.897 2-2V4c0-1.103-.897-2-2-2zm-3 9h-4v4h-2v-4H7V9h4V5h2v4h4v2z"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" style="fill: rgb(17, 17, 17); --darkreader-inline-fill: #e8e6e3;" data-darkreader-inline-fill="">
<path d="M20 2H4c-1.103 0-2 .897-2 2v18l4-4h14c1.103 0 2-.897 2-2V4c0-1.103-.897-2-2-2zm-3 9h-4v4h-2v-4H7V9h4V5h2v4h4v2z" />
</svg>

Before

Width:  |  Height:  |  Size: 315 B

After

Width:  |  Height:  |  Size: 317 B

View File

@ -1 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" style="fill: rgb(17, 17, 17); --darkreader-inline-fill: #e8e6e3;" data-darkreader-inline-fill=""><path d="M13 20v-4.586L20.414 8c.375-.375.586-.884.586-1.415V4a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v2.585c0 .531.211 1.04.586 1.415L11 15.414V22l2-2z"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" style="fill: rgb(17, 17, 17); --darkreader-inline-fill: #e8e6e3;" data-darkreader-inline-fill="">
<path d="M13 20v-4.586L20.414 8c.375-.375.586-.884.586-1.415V4a1 1 0 0 0-1-1H4a1 1 0 0 0-1 1v2.585c0 .531.211 1.04.586 1.415L11 15.414V22l2-2z" />
</svg>

Before

Width:  |  Height:  |  Size: 337 B

After

Width:  |  Height:  |  Size: 338 B

View File

@ -1 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" style="fill: rgb(17, 17, 17); --darkreader-inline-fill: #e8e6e3;" data-darkreader-inline-fill=""><path d="M20.5 5A1.5 1.5 0 0 0 19 6.5V11h-1V4.5a1.5 1.5 0 0 0-3 0V11h-1V3.5a1.5 1.5 0 0 0-3 0V11h-1V5.5a1.5 1.5 0 0 0-3 0v10.81l-2.22-3.6a1.5 1.5 0 0 0-2.56 1.58l3.31 5.34A5 5 0 0 0 9.78 22H17a5 5 0 0 0 5-5V6.5A1.5 1.5 0 0 0 20.5 5z"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" style="fill: rgb(17, 17, 17); --darkreader-inline-fill: #e8e6e3;" data-darkreader-inline-fill="">
<path d="M20.5 5A1.5 1.5 0 0 0 19 6.5V11h-1V4.5a1.5 1.5 0 0 0-3 0V11h-1V3.5a1.5 1.5 0 0 0-3 0V11h-1V5.5a1.5 1.5 0 0 0-3 0v10.81l-2.22-3.6a1.5 1.5 0 0 0-2.56 1.58l3.31 5.34A5 5 0 0 0 9.78 22H17a5 5 0 0 0 5-5V6.5A1.5 1.5 0 0 0 20.5 5z" />
</svg>

Before

Width:  |  Height:  |  Size: 427 B

After

Width:  |  Height:  |  Size: 429 B

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools --> <?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="24" height="24" viewBox="0 0 24 24" fill="rgb(185, 179, 170)" xmlns="http://www.w3.org/2000/svg"> <svg width="24" height="24" viewBox="0 0 24 24" fill="rgb(185, 179, 170)" xmlns="http://www.w3.org/2000/svg">
<path d="M6.25993 21.3884H6C5.05719 21.3884 4.58579 21.3884 4.29289 21.0955C4 20.8026 4 20.3312 4 19.3884V18.2764C4 17.7579 4 17.4987 4.13318 17.2672C4.26636 17.0356 4.46727 16.9188 4.8691 16.6851C7.51457 15.1464 11.2715 14.2803 13.7791 15.7759C13.9475 15.8764 14.0991 15.9977 14.2285 16.1431C14.7866 16.77 14.746 17.7161 14.1028 18.2775C13.9669 18.396 13.8222 18.486 13.6764 18.5172C13.7962 18.5033 13.911 18.4874 14.0206 18.4699C14.932 18.3245 15.697 17.8375 16.3974 17.3084L18.2046 15.9433C18.8417 15.462 19.7873 15.4619 20.4245 15.943C20.9982 16.3762 21.1736 17.0894 20.8109 17.6707C20.388 18.3487 19.7921 19.216 19.2199 19.7459C18.6469 20.2766 17.7939 20.7504 17.0975 21.0865C16.326 21.4589 15.4738 21.6734 14.6069 21.8138C12.8488 22.0983 11.0166 22.0549 9.27633 21.6964C8.29253 21.4937 7.27079 21.3884 6.25993 21.3884Z"/> <path d="M6.25993 21.3884H6C5.05719 21.3884 4.58579 21.3884 4.29289 21.0955C4 20.8026 4 20.3312 4 19.3884V18.2764C4 17.7579 4 17.4987 4.13318 17.2672C4.26636 17.0356 4.46727 16.9188 4.8691 16.6851C7.51457 15.1464 11.2715 14.2803 13.7791 15.7759C13.9475 15.8764 14.0991 15.9977 14.2285 16.1431C14.7866 16.77 14.746 17.7161 14.1028 18.2775C13.9669 18.396 13.8222 18.486 13.6764 18.5172C13.7962 18.5033 13.911 18.4874 14.0206 18.4699C14.932 18.3245 15.697 17.8375 16.3974 17.3084L18.2046 15.9433C18.8417 15.462 19.7873 15.4619 20.4245 15.943C20.9982 16.3762 21.1736 17.0894 20.8109 17.6707C20.388 18.3487 19.7921 19.216 19.2199 19.7459C18.6469 20.2766 17.7939 20.7504 17.0975 21.0865C16.326 21.4589 15.4738 21.6734 14.6069 21.8138C12.8488 22.0983 11.0166 22.0549 9.27633 21.6964C8.29253 21.4937 7.27079 21.3884 6.25993 21.3884Z"/>
<path d="M10.8613 3.36335C11.3679 2.45445 11.6213 2 12 2C12.3787 2 12.6321 2.45445 13.1387 3.36335L13.2698 3.59849C13.4138 3.85677 13.4858 3.98591 13.598 4.07112C13.7103 4.15633 13.8501 4.18796 14.1296 4.25122L14.3842 4.30881C15.3681 4.53142 15.86 4.64273 15.977 5.01909C16.0941 5.39546 15.7587 5.78763 15.088 6.57197L14.9144 6.77489C14.7238 6.99777 14.6285 7.10922 14.5857 7.24709C14.5428 7.38496 14.5572 7.53365 14.586 7.83102L14.6122 8.10176C14.7136 9.14824 14.7644 9.67148 14.4579 9.90409C14.1515 10.1367 13.6909 9.92462 12.7697 9.50047L12.5314 9.39074C12.2696 9.27021 12.1387 9.20994 12 9.20994C11.8613 9.20994 11.7304 9.27021 11.4686 9.39074L11.2303 9.50047C10.3091 9.92462 9.84847 10.1367 9.54206 9.90409C9.23565 9.67148 9.28635 9.14824 9.38776 8.10176L9.41399 7.83102C9.44281 7.53364 9.45722 7.38496 9.41435 7.24709C9.37147 7.10922 9.27617 6.99777 9.08557 6.77489L8.91204 6.57197C8.2413 5.78763 7.90593 5.39546 8.02297 5.01909C8.14001 4.64273 8.63194 4.53142 9.61581 4.30881L9.87035 4.25122C10.1499 4.18796 10.2897 4.15633 10.402 4.07112C10.5142 3.98591 10.5862 3.85677 10.7302 3.59849L10.8613 3.36335Z"/> <path d="M10.8613 3.36335C11.3679 2.45445 11.6213 2 12 2C12.3787 2 12.6321 2.45445 13.1387 3.36335L13.2698 3.59849C13.4138 3.85677 13.4858 3.98591 13.598 4.07112C13.7103 4.15633 13.8501 4.18796 14.1296 4.25122L14.3842 4.30881C15.3681 4.53142 15.86 4.64273 15.977 5.01909C16.0941 5.39546 15.7587 5.78763 15.088 6.57197L14.9144 6.77489C14.7238 6.99777 14.6285 7.10922 14.5857 7.24709C14.5428 7.38496 14.5572 7.53365 14.586 7.83102L14.6122 8.10176C14.7136 9.14824 14.7644 9.67148 14.4579 9.90409C14.1515 10.1367 13.6909 9.92462 12.7697 9.50047L12.5314 9.39074C12.2696 9.27021 12.1387 9.20994 12 9.20994C11.8613 9.20994 11.7304 9.27021 11.4686 9.39074L11.2303 9.50047C10.3091 9.92462 9.84847 10.1367 9.54206 9.90409C9.23565 9.67148 9.28635 9.14824 9.38776 8.10176L9.41399 7.83102C9.44281 7.53364 9.45722 7.38496 9.41435 7.24709C9.37147 7.10922 9.27617 6.99777 9.08557 6.77489L8.91204 6.57197C8.2413 5.78763 7.90593 5.39546 8.02297 5.01909C8.14001 4.64273 8.63194 4.53142 9.61581 4.30881L9.87035 4.25122C10.1499 4.18796 10.2897 4.15633 10.402 4.07112C10.5142 3.98591 10.5862 3.85677 10.7302 3.59849L10.8613 3.36335Z"/>
<path d="M19.4306 7.68167C19.684 7.22722 19.8106 7 20 7C20.1894 7 20.316 7.22723 20.5694 7.68167L20.6349 7.79925C20.7069 7.92839 20.7429 7.99296 20.799 8.03556C20.8551 8.07817 20.925 8.09398 21.0648 8.12561L21.1921 8.15441C21.684 8.26571 21.93 8.32136 21.9885 8.50955C22.047 8.69773 21.8794 8.89381 21.544 9.28598L21.4572 9.38744C21.3619 9.49889 21.3143 9.55461 21.2928 9.62354C21.2714 9.69248 21.2786 9.76682 21.293 9.91551L21.3061 10.0509C21.3568 10.5741 21.3822 10.8357 21.229 10.952C21.0758 11.0683 20.8455 10.9623 20.3849 10.7502L20.2657 10.6954C20.1348 10.6351 20.0694 10.605 20 10.605C19.9306 10.605 19.8652 10.6351 19.7343 10.6954L19.6151 10.7502C19.1545 10.9623 18.9242 11.0683 18.771 10.952C18.6178 10.8357 18.6432 10.5741 18.6939 10.0509L18.707 9.91551C18.7214 9.76682 18.7286 9.69248 18.7072 9.62354C18.6857 9.55461 18.6381 9.49889 18.5428 9.38744L18.456 9.28598C18.1207 8.89381 17.953 8.69773 18.0115 8.50955C18.07 8.32136 18.316 8.26571 18.8079 8.15441L18.9352 8.12561C19.075 8.09398 19.1449 8.07817 19.201 8.03556C19.2571 7.99296 19.2931 7.92839 19.3651 7.79925L19.4306 7.68167Z"/> <path d="M19.4306 7.68167C19.684 7.22722 19.8106 7 20 7C20.1894 7 20.316 7.22723 20.5694 7.68167L20.6349 7.79925C20.7069 7.92839 20.7429 7.99296 20.799 8.03556C20.8551 8.07817 20.925 8.09398 21.0648 8.12561L21.1921 8.15441C21.684 8.26571 21.93 8.32136 21.9885 8.50955C22.047 8.69773 21.8794 8.89381 21.544 9.28598L21.4572 9.38744C21.3619 9.49889 21.3143 9.55461 21.2928 9.62354C21.2714 9.69248 21.2786 9.76682 21.293 9.91551L21.3061 10.0509C21.3568 10.5741 21.3822 10.8357 21.229 10.952C21.0758 11.0683 20.8455 10.9623 20.3849 10.7502L20.2657 10.6954C20.1348 10.6351 20.0694 10.605 20 10.605C19.9306 10.605 19.8652 10.6351 19.7343 10.6954L19.6151 10.7502C19.1545 10.9623 18.9242 11.0683 18.771 10.952C18.6178 10.8357 18.6432 10.5741 18.6939 10.0509L18.707 9.91551C18.7214 9.76682 18.7286 9.69248 18.7072 9.62354C18.6857 9.55461 18.6381 9.49889 18.5428 9.38744L18.456 9.28598C18.1207 8.89381 17.953 8.69773 18.0115 8.50955C18.07 8.32136 18.316 8.26571 18.8079 8.15441L18.9352 8.12561C19.075 8.09398 19.1449 8.07817 19.201 8.03556C19.2571 7.99296 19.2931 7.92839 19.3651 7.79925L19.4306 7.68167Z"/>
<path d="M3.43063 7.68167C3.68396 7.22722 3.81063 7 4 7C4.18937 7 4.31604 7.22723 4.56937 7.68167L4.63491 7.79925C4.7069 7.92839 4.74289 7.99296 4.79901 8.03556C4.85513 8.07817 4.92503 8.09398 5.06482 8.12561L5.19209 8.15441C5.68403 8.26571 5.93 8.32136 5.98852 8.50955C6.04704 8.69773 5.87935 8.89381 5.54398 9.28598L5.45722 9.38744C5.36191 9.49889 5.31426 9.55461 5.29283 9.62354C5.27139 9.69248 5.27859 9.76682 5.293 9.91551L5.30612 10.0509C5.35682 10.5741 5.38218 10.8357 5.22897 10.952C5.07576 11.0683 4.84547 10.9623 4.38487 10.7502L4.2657 10.6954C4.13481 10.6351 4.06937 10.605 4 10.605C3.93063 10.605 3.86519 10.6351 3.7343 10.6954L3.61513 10.7502C3.15454 10.9623 2.92424 11.0683 2.77103 10.952C2.61782 10.8357 2.64318 10.5741 2.69388 10.0509L2.707 9.91551C2.72141 9.76682 2.72861 9.69248 2.70717 9.62354C2.68574 9.55461 2.63809 9.49889 2.54278 9.38744L2.45602 9.28598C2.12065 8.89381 1.95296 8.69773 2.01148 8.50955C2.07 8.32136 2.31597 8.26571 2.80791 8.15441L2.93518 8.12561C3.07497 8.09398 3.14487 8.07817 3.20099 8.03556C3.25711 7.99296 3.29311 7.92839 3.36509 7.79925L3.43063 7.68167Z"/> <path d="M3.43063 7.68167C3.68396 7.22722 3.81063 7 4 7C4.18937 7 4.31604 7.22723 4.56937 7.68167L4.63491 7.79925C4.7069 7.92839 4.74289 7.99296 4.79901 8.03556C4.85513 8.07817 4.92503 8.09398 5.06482 8.12561L5.19209 8.15441C5.68403 8.26571 5.93 8.32136 5.98852 8.50955C6.04704 8.69773 5.87935 8.89381 5.54398 9.28598L5.45722 9.38744C5.36191 9.49889 5.31426 9.55461 5.29283 9.62354C5.27139 9.69248 5.27859 9.76682 5.293 9.91551L5.30612 10.0509C5.35682 10.5741 5.38218 10.8357 5.22897 10.952C5.07576 11.0683 4.84547 10.9623 4.38487 10.7502L4.2657 10.6954C4.13481 10.6351 4.06937 10.605 4 10.605C3.93063 10.605 3.86519 10.6351 3.7343 10.6954L3.61513 10.7502C3.15454 10.9623 2.92424 11.0683 2.77103 10.952C2.61782 10.8357 2.64318 10.5741 2.69388 10.0509L2.707 9.91551C2.72141 9.76682 2.72861 9.69248 2.70717 9.62354C2.68574 9.55461 2.63809 9.49889 2.54278 9.38744L2.45602 9.28598C2.12065 8.89381 1.95296 8.69773 2.01148 8.50955C2.07 8.32136 2.31597 8.26571 2.80791 8.15441L2.93518 8.12561C3.07497 8.09398 3.14487 8.07817 3.20099 8.03556C3.25711 7.99296 3.29311 7.92839 3.36509 7.79925L3.43063 7.68167Z"/>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -21,7 +21,7 @@ const stations: Record<Lines, Set<string>> = {
'Кировский завод', 'Кировский завод',
'Автово', 'Автово',
'Ленинский проспект', 'Ленинский проспект',
'Проспект Ветеранов' 'Проспект Ветеранов',
]), ]),
blue: new Set([ blue: new Set([
'Парнас', 'Парнас',
@ -41,7 +41,7 @@ const stations: Record<Lines, Set<string>> = {
'Парк Победы', 'Парк Победы',
'Московская', 'Московская',
'Звёздная', 'Звёздная',
'Купчино' 'Купчино',
]), ]),
green: new Set([ green: new Set([
'Приморская', 'Приморская',
@ -54,7 +54,7 @@ const stations: Record<Lines, Set<string>> = {
'Ломоносовская', 'Ломоносовская',
'Пролетарская', 'Пролетарская',
'Обухово', 'Обухово',
'Рыбацкое' 'Рыбацкое',
]), ]),
orange: new Set([ orange: new Set([
'Спасская', 'Спасская',
@ -64,7 +64,7 @@ const stations: Record<Lines, Set<string>> = {
'Новочеркасская', 'Новочеркасская',
'Ладожская', 'Ладожская',
'Проспект Большевиков', 'Проспект Большевиков',
'Улица Дыбенко' 'Улица Дыбенко',
]), ]),
violet: new Set([ violet: new Set([
'Комендантский проспект', 'Комендантский проспект',
@ -81,7 +81,7 @@ const stations: Record<Lines, Set<string>> = {
'Международная', 'Международная',
'Проспект славы', 'Проспект славы',
'Дунайскай', 'Дунайскай',
'Шушары' 'Шушары',
]), ]),
} }

View File

@ -10,4 +10,4 @@
<animate attributeName="stroke-opacity" begin="-0.9s" dur="1.8s" values="1; 0" calcMode="spline" keyTimes="0; 1" keySplines="0.3, 0.61, 0.355, 1" repeatCount="indefinite"/> <animate attributeName="stroke-opacity" begin="-0.9s" dur="1.8s" values="1; 0" calcMode="spline" keyTimes="0; 1" keySplines="0.3, 0.61, 0.355, 1" repeatCount="indefinite"/>
</circle> </circle>
</g> </g>
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools --> <?xml version="1.0" encoding="utf-8"?><!-- Uploaded to: SVG Repo, www.svgrepo.com, Generator: SVG Repo Mixer Tools -->
<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M14 20H6C4.89543 20 4 19.1046 4 18L4 6C4 4.89543 4.89543 4 6 4H14M10 12H21M21 12L18 15M21 12L18 9" stroke="rgb(185, 179, 170)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"/> <path d="M14 20H6C4.89543 20 4 19.1046 4 18L4 6C4 4.89543 4.89543 4 6 4H14M10 12H21M21 12L18 15M21 12L18 9" stroke="rgb(185, 179, 170)" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" />
</svg> </svg>

Before

Width:  |  Height:  |  Size: 426 B

After

Width:  |  Height:  |  Size: 433 B

View File

@ -1 +1,3 @@
<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" style="fill: rgb(17, 17, 17); --darkreader-inline-fill: #e8e6e3;" data-darkreader-inline-fill=""><path d="M7.5 6.5C7.5 8.981 9.519 11 12 11s4.5-2.019 4.5-4.5S14.481 2 12 2 7.5 4.019 7.5 6.5zM20 21h1v-1c0-3.859-3.141-7-7-7h-4c-3.86 0-7 3.141-7 7v1h17z"></path></svg> <svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" style="fill: rgb(17, 17, 17); --darkreader-inline-fill: #e8e6e3;" data-darkreader-inline-fill="">
<path d="M7.5 6.5C7.5 8.981 9.519 11 12 11s4.5-2.019 4.5-4.5S14.481 2 12 2 7.5 4.019 7.5 6.5zM20 21h1v-1c0-3.859-3.141-7-7-7h-4c-3.86 0-7 3.141-7 7v1h17z" />
</svg>

Before

Width:  |  Height:  |  Size: 348 B

After

Width:  |  Height:  |  Size: 350 B

View File

@ -28,7 +28,7 @@ const styles = {
} }
function AnnouncementDetails({ close, refresh, announcement: { function AnnouncementDetails({ close, refresh, announcement: {
id, name, category, bestBy, description, lat, lng, address, metro, bookedBy, userId id, name, category, bestBy, description, lat, lng, address, metro, bookedBy, userId,
} }: AnnouncementDetailsProps) { } }: AnnouncementDetailsProps) {
const { handleBook, bookButton } = useBook() const { handleBook, bookButton } = useBook()

View File

@ -6,7 +6,7 @@ import { composeSignUpBody } from '../api/signup'
import { composeSignInBody } from '../api/token' import { composeSignInBody } from '../api/token'
type AuthFormProps = { type AuthFormProps = {
register: boolean register: boolean,
goBack: () => void, goBack: () => void,
} }

View File

@ -5,7 +5,7 @@ import { PropsWithChildren } from 'react'
import BackButton from '../assets/backArrow.svg' import BackButton from '../assets/backArrow.svg'
type BackHeaderProps = { type BackHeaderProps = {
text: string text: string,
} }
function BackHeader({ text, children }: PropsWithChildren<BackHeaderProps>) { function BackHeader({ text, children }: PropsWithChildren<BackHeaderProps>) {

View File

@ -15,22 +15,20 @@ const styles = {
display: 'flex', display: 'flex',
flexDirection: 'row', flexDirection: 'row',
height: '100%', height: '100%',
margin: 'auto' margin: 'auto',
} as CSSProperties, } as CSSProperties,
navBarElement: { navBarElement: {
width: '100%', width: '100%',
height: '100%', height: '100%',
display: 'flex', display: 'flex',
alignItems: 'center', alignItems: 'center',
justifyContent: 'center' justifyContent: 'center',
} as CSSProperties, } as CSSProperties,
} }
type BottomNavBarProps = { type BottomNavBarProps = {
width: number, width: number,
toggleFilters: (p: boolean) => void toggleFilters: (state: boolean) => void,
} }
function BottomNavBar({ width, toggleFilters }: BottomNavBarProps) { function BottomNavBar({ width, toggleFilters }: BottomNavBarProps) {
@ -38,7 +36,7 @@ function BottomNavBar({ width, toggleFilters }: BottomNavBarProps) {
<div style={styles.navBar}> <div style={styles.navBar}>
<div style={{ ...styles.navBarGroup, width: width }}> <div style={{ ...styles.navBarGroup, width: width }}>
<a style={styles.navBarElement} onClick={() => toggleFilters(true)}> <a href='#' style={styles.navBarElement} onClick={() => toggleFilters(true)}>
<img src={filterIcon} alt='Фильтровать объявления' title='Фильтровать объявления' /> <img src={filterIcon} alt='Фильтровать объявления' title='Фильтровать объявления' />
</a> </a>
@ -46,7 +44,7 @@ function BottomNavBar({ width, toggleFilters }: BottomNavBarProps) {
<img src={addIcon} alt='Опубликовать объявление' title='Опубликовать объявление' /> <img src={addIcon} alt='Опубликовать объявление' title='Опубликовать объявление' />
</Link> </Link>
<Link style={styles.navBarElement} to={'/user'} > <Link style={styles.navBarElement} to='/user' >
<img src={userIcon} alt='Личный кабинет' title='Личный кабинет' /> <img src={userIcon} alt='Личный кабинет' title='Личный кабинет' />
</Link> </Link>

View File

@ -4,7 +4,7 @@ import { Card } from 'react-bootstrap'
import { BackHeader } from '.' import { BackHeader } from '.'
type CardLayoutProps = { type CardLayoutProps = {
text: string text: string,
} }
const CardLayout = ({ text, children }: PropsWithChildren<CardLayoutProps>) => ( const CardLayout = ({ text, children }: PropsWithChildren<CardLayoutProps>) => (

View File

@ -4,7 +4,7 @@ import { useAnnouncements } from '../hooks/api'
import { gotError } from '../hooks/useFetch' import { gotError } from '../hooks/useFetch'
type CategoryPreviewProps = { type CategoryPreviewProps = {
category: UserCategory category: UserCategory,
} }
function CategoryPreview({ category }: CategoryPreviewProps) { function CategoryPreview({ category }: CategoryPreviewProps) {

View File

@ -10,21 +10,21 @@ type FiltersProps = {
filter: FiltersType, filter: FiltersType,
setFilter: SetState<FiltersType>, setFilter: SetState<FiltersType>,
filterShown: boolean, filterShown: boolean,
setFilterShown: SetState<boolean> setFilterShown: SetState<boolean>,
} }
function Filters({ filter, setFilter, filterShown, setFilterShown }: FiltersProps) { function Filters({ filter, setFilter, filterShown, setFilterShown }: FiltersProps) {
const handleSubmit: FormEventHandler<HTMLFormElement> = (event) => { const handleSubmit: FormEventHandler<HTMLFormElement> = (event) => {
event.preventDefault(); event.preventDefault()
event.stopPropagation(); event.stopPropagation()
const formData = new FormData(event.currentTarget) const formData = new FormData(event.currentTarget)
setFilter(prev => ({ setFilter(prev => ({
...prev, ...prev,
category: (formData.get('category') as (FiltersType['category'] | null)) || undefined, category: (formData.get('category') as (FiltersType['category'] | null)) || undefined,
metro: (formData.get('metro') as (FiltersType['metro'] | null)) || undefined metro: (formData.get('metro') as (FiltersType['metro'] | null)) || undefined,
})) }))
setFilterShown(false) setFilterShown(false)

View File

@ -3,8 +3,9 @@ import { colors, lineNames, lineByName } from '../assets/metro'
function LineDot({ station }: { station: string }) { function LineDot({ station }: { station: string }) {
const line = lineByName(station) const line = lineByName(station)
if (line == undefined) if (line == undefined) {
return <></> return <></>
}
const lineTitle = lineNames[line] const lineTitle = lineNames[line]
const color = colors[line] const color = colors[line]

View File

@ -7,7 +7,7 @@ import { iconItem } from '../utils/markerIcons'
type LocationMarkerProps = { type LocationMarkerProps = {
address: string, address: string,
position: LatLng, position: LatLng,
setPosition: SetState<LatLng> setPosition: SetState<LatLng>,
} }
function LocationMarker({ address, position, setPosition }: LocationMarkerProps) { function LocationMarker({ address, position, setPosition }: LocationMarkerProps) {
@ -21,7 +21,7 @@ function LocationMarker({ address, position, setPosition }: LocationMarkerProps)
}, },
resize: () => { resize: () => {
setPosition(map.getCenter()) setPosition(map.getCenter())
} },
}) })
return ( return (

View File

@ -3,7 +3,7 @@ import { CSSProperties } from 'react'
import handStarsIcon from '../assets/handStars.svg' import handStarsIcon from '../assets/handStars.svg'
type PointsProps = { type PointsProps = {
points: number points: number,
} }
const styles = { const styles = {

View File

@ -9,7 +9,7 @@ import signOutIcon from '../assets/signOut.svg'
const styles = { const styles = {
rightIcon: { rightIcon: {
marginLeft: '1rem', marginLeft: '1rem',
marginRight: 0 marginRight: 0,
} as CSSProperties, } as CSSProperties,
} }

View File

@ -58,7 +58,7 @@ const styles = {
} as CSSProperties, } as CSSProperties,
leftScrollButton: { leftScrollButton: {
left: 0, left: 0,
transform: 'scaleX(-1)' transform: 'scaleX(-1)',
} as CSSProperties, } as CSSProperties,
rightScrollButton: { rightScrollButton: {
right: 0, right: 0,
@ -116,7 +116,7 @@ function StoriesPreview({ announcements, category }: StoriesPreviewProps) {
<li key={`${category}${i}`}> <li key={`${category}${i}`}>
<Link to={'/?' + new URLSearchParams({ <Link to={'/?' + new URLSearchParams({
...URLEncodeFilters(composeUserCategoriesFilters[category]()), ...URLEncodeFilters(composeUserCategoriesFilters[category]()),
storyIndex: i.toString() storyIndex: i.toString(),
}).toString()} style={styles.link}> }).toString()} style={styles.link}>
{ann.src?.endsWith('mp4') ? ( {ann.src?.endsWith('mp4') ? (
<video src={ann.src} style={styles.image} /> <video src={ann.src} style={styles.image} />

View File

@ -5,7 +5,10 @@ import { iconTrash } from '../utils/markerIcons'
type TrashboxMarkersProps = { type TrashboxMarkersProps = {
trashboxes: Trashbox[], trashboxes: Trashbox[],
selectTrashbox: ({ index, category }: { index: number, category: string }) => void selectTrashbox: ({ index, category }: {
index: number,
category: string,
}) => void,
} }
function TrashboxMarkers({ trashboxes, selectTrashbox }: TrashboxMarkersProps) { function TrashboxMarkers({ trashboxes, selectTrashbox }: TrashboxMarkersProps) {

View File

@ -16,7 +16,7 @@ function useAddAnnouncement() {
function handleAdd(formData: FormData) { function handleAdd(formData: FormData) {
void doSend({}, { void doSend({}, {
body: formData body: formData,
}) })
} }

View File

@ -1,18 +1,8 @@
import { useCallback } from 'react' import { useCallback } from 'react'
import { isObject } from '../../utils/types'
import { useSendWithButton } from '..' import { useSendWithButton } from '..'
import { composeBookURL, processBook } from '../../api/book' import { composeBookURL, processBook } from '../../api/book'
import { isBookResponse } from '../../api/book/types'
type BookResponse = {
Success: boolean
}
const isBookResponse = (obj: unknown): obj is BookResponse => (
isObject(obj, {
'Success': 'boolean'
})
)
function useBook() { function useBook() {
const { doSend, button } = useSendWithButton('Забронировать', const { doSend, button } = useSendWithButton('Забронировать',
@ -22,17 +12,17 @@ function useBook() {
'POST', 'POST',
true, true,
isBookResponse, isBookResponse,
processBook processBook,
) )
const handleBook = useCallback((id: number) => { const handleBook = useCallback((id: number) => {
void doSend({}, { void doSend({}, {
body: JSON.stringify({ body: JSON.stringify({
id id,
}), }),
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json',
} },
}) })
}, [doSend]) }, [doSend])

View File

@ -11,7 +11,7 @@ const useOsmAddresses = (addressPosition: LatLng) => (
false, false,
isOsmAddressResponse, isOsmAddressResponse,
processOsmAddress, processOsmAddress,
'' '',
) )
) )

View File

@ -13,17 +13,17 @@ const useRemoveAnnouncement = (resolve: () => void) => {
'DELETE', 'DELETE',
true, true,
isRemoveAnnouncementResponse, isRemoveAnnouncementResponse,
processRemoveAnnouncement processRemoveAnnouncement,
) )
const doSendWithClose = useCallback(async (id: number) => { const doSendWithClose = useCallback(async (id: number) => {
const res = await doSend({}, { const res = await doSend({}, {
body: JSON.stringify({ body: JSON.stringify({
id id,
}), }),
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json',
} },
}) })
if (res) { if (res) {

View File

@ -17,7 +17,7 @@ function useSignIn() {
async function handleSignIn(formData: FormData) { async function handleSignIn(formData: FormData) {
const token = await doSend({}, { const token = await doSend({}, {
body: formData body: formData,
}) })
if (token !== undefined) { if (token !== undefined) {

View File

@ -18,8 +18,8 @@ function useSignUp() {
const res = await doSend({}, { const res = await doSend({}, {
body: JSON.stringify(data), body: JSON.stringify(data),
headers: { headers: {
'Content-Type': 'application/json' 'Content-Type': 'application/json',
} },
}) })
return res ?? false return res ?? false

View File

@ -11,7 +11,7 @@ const useTrashboxes = (position: LatLng) => (
true, true,
isTrashboxResponse, isTrashboxResponse,
processTrashbox, processTrashbox,
[] [],
) )
) )

View File

@ -16,8 +16,8 @@ const useUser = (): UseFetchReturn<User> => (
data: initialUser, data: initialUser,
loading: false, loading: false,
error: null, error: null,
refetch: () => { return } refetch: () => { return },
} }
) )
export default useUser export default useUser

View File

@ -15,7 +15,7 @@ type UseFetchSucced<T> = {
type UseFetchErrored = { type UseFetchErrored = {
error: string, error: string,
data: undefined data: undefined,
} & UseFetchShared } & UseFetchShared
type UseFetchReturn<T> = UseFetchSucced<T> | UseFetchErrored type UseFetchReturn<T> = UseFetchSucced<T> | UseFetchErrored
@ -35,7 +35,7 @@ function useFetch<R, T extends NonNullable<unknown>>(
guardResponse: (data: unknown) => data is R, guardResponse: (data: unknown) => data is R,
processResponse: (data: R) => T, processResponse: (data: R) => T,
initialData?: T, initialData?: T,
params?: Omit<RequestInit, 'method'> params?: Omit<RequestInit, 'method'>,
): UseFetchReturn<T> { ): UseFetchReturn<T> {
const [data, setData] = useState(initialData) const [data, setData] = useState(initialData)
@ -46,7 +46,7 @@ function useFetch<R, T extends NonNullable<unknown>>(
guardResponse, guardResponse,
processResponse, processResponse,
true, true,
params params,
) )
function refetch() { function refetch() {
@ -62,11 +62,11 @@ function useFetch<R, T extends NonNullable<unknown>>(
return { return {
...( ...(
error === null ? ({ error === null ? ({
data: data!, error: null data: data!, error: null,
}) : ({ data: undefined, error }) }) : ({ data: undefined, error })
), ),
loading, loading,
refetch refetch,
} }
} }

View File

@ -12,7 +12,7 @@ function useFilters(initialFilters: FiltersType = defaultFilters): [FiltersType,
const appendFiltersSearchParams = (filters: FiltersType, replace = false) => ( const appendFiltersSearchParams = (filters: FiltersType, replace = false) => (
setSearchParams(params => ({ setSearchParams(params => ({
...Object.fromEntries(params), ...Object.fromEntries(params),
...URLEncodeFilters(filters) ...URLEncodeFilters(filters),
}), { replace }) }), { replace })
) )

View File

@ -11,7 +11,7 @@ function useSend<R, T extends NonNullable<unknown>>(
guardResponse: (data: unknown) => data is R, guardResponse: (data: unknown) => data is R,
processResponse: (data: R) => T, processResponse: (data: R) => T,
startWithLoading = false, startWithLoading = false,
defaultParams?: Omit<RequestInit, 'method'> defaultParams?: Omit<RequestInit, 'method'>,
) { ) {
const [loading, setLoading] = useState(startWithLoading) const [loading, setLoading] = useState(startWithLoading)
const [error, setError] = useState<string | null>(null) const [error, setError] = useState<string | null>(null)
@ -36,7 +36,7 @@ function useSend<R, T extends NonNullable<unknown>>(
const headers = new Headers({ const headers = new Headers({
...defaultParams?.headers, ...defaultParams?.headers,
...params?.headers ...params?.headers,
}) })
if (needAuth) { if (needAuth) {
@ -93,7 +93,7 @@ function useSend<R, T extends NonNullable<unknown>>(
return { return {
doSend, loading, error, doSend, loading, error,
abort: abortControllerRef.current?.abort.bind(abortControllerRef.current) abort: abortControllerRef.current?.abort.bind(abortControllerRef.current),
} }
} }

View File

@ -5,7 +5,7 @@ function useSendButtonCaption(
loading: boolean, loading: boolean,
error: string | null, error: string | null,
result = initial, result = initial,
singular = true singular = true,
) { ) {
const [caption, setCaption] = useState(initial) const [caption, setCaption] = useState(initial)
const [disabled, setDisabled] = useState(false) const [disabled, setDisabled] = useState(false)

View File

@ -3,7 +3,7 @@ import { useState, useEffect } from 'react';
const getWindowDimensions = () => ( const getWindowDimensions = () => (
{ {
width: window.innerWidth, width: window.innerWidth,
height: window.innerHeight height: window.innerHeight,
} }
) )
@ -12,11 +12,11 @@ function useStoryDimensions(maxRatio = 16 / 9) {
useEffect(() => { useEffect(() => {
function handleResize() { function handleResize() {
setWindowDimensions(getWindowDimensions()); setWindowDimensions(getWindowDimensions())
} }
window.addEventListener('resize', handleResize); window.addEventListener('resize', handleResize);
return () => window.removeEventListener('resize', handleResize); return () => window.removeEventListener('resize', handleResize)
}, []); }, []);
const bottomBarHeight = 56 const bottomBarHeight = 56
@ -27,7 +27,7 @@ function useStoryDimensions(maxRatio = 16 / 9) {
return { return {
height: height, height: height,
width: Math.round(height / ratio) width: Math.round(height / ratio),
} }
} }

View File

@ -12,7 +12,7 @@ function useStoryIndex(annLength: number | undefined) {
setIndex(0) setIndex(0)
setSearchParams(prev => ({ setSearchParams(prev => ({
...Object.fromEntries(prev), ...Object.fromEntries(prev),
storyIndex: '0' storyIndex: '0',
}), { replace: true }) }), { replace: true })
f(...args) f(...args)
} }
@ -29,7 +29,7 @@ function useStoryIndex(annLength: number | undefined) {
const newIndex = (prev + 1) % (annLength || 1) const newIndex = (prev + 1) % (annLength || 1)
setSearchParams(prev => ({ setSearchParams(prev => ({
...Object.fromEntries(prev), ...Object.fromEntries(prev),
storyIndex: newIndex.toString() storyIndex: newIndex.toString(),
}), { replace: true }) }), { replace: true })
return newIndex return newIndex
@ -39,7 +39,7 @@ function useStoryIndex(annLength: number | undefined) {
const newIndex = prev > 0 ? (prev - 1) : 0 const newIndex = prev > 0 ? (prev - 1) : 0
setSearchParams(prev => ({ setSearchParams(prev => ({
...Object.fromEntries(prev), ...Object.fromEntries(prev),
storyIndex: newIndex.toString() storyIndex: newIndex.toString(),
}), { replace: true }) }), { replace: true })
return newIndex return newIndex
@ -49,7 +49,7 @@ function useStoryIndex(annLength: number | undefined) {
n: index, n: index,
withReset, withReset,
increment, increment,
decrement decrement,
} }
} }

View File

@ -18,7 +18,9 @@ function generateStories(announcements: Announcement[], refresh: () => void): St
id: announcement.id, id: announcement.id,
url: announcement.src || categoryGraphics[announcement.category], url: announcement.src || categoryGraphics[announcement.category],
type: announcement.src?.endsWith('mp4') ? 'video' : undefined, type: announcement.src?.endsWith('mp4') ? 'video' : undefined,
seeMore: ({ close }: { close: () => void }) => <AnnouncementDetails close={close} refresh={refresh} announcement={announcement} /> seeMore: ({ close }: { close: () => void }) => (
<AnnouncementDetails close={close} refresh={refresh} announcement={announcement} />
),
}) })
}) })
} }
@ -58,7 +60,7 @@ const styles = {
backgroundColor: 'rgb(17, 17, 17)', backgroundColor: 'rgb(17, 17, 17)',
} as CSSProperties, } as CSSProperties,
center: { center: {
margin: 'auto' margin: 'auto',
} as CSSProperties, } as CSSProperties,
} }

View File

@ -33,11 +33,11 @@ function clearToken() {
} }
type TokenPayload = { type TokenPayload = {
user_id: number user_id: number,
} }
const isTokenPayload = (data: unknown): data is TokenPayload => isObject(data, { const isTokenPayload = (data: unknown): data is TokenPayload => isObject(data, {
'user_id': 'number' 'user_id': 'number',
}) })
function getId() { function getId() {