Merge branch 'main' of https://github.com/dm1sh/porridger_tmp
This commit is contained in:
commit
73eaf00b96
2
back/unimportant.env
Normal file
2
back/unimportant.env
Normal file
@ -0,0 +1,2 @@
|
||||
TOKEN = "eyJhbGciOiJSUzI1NiIsInR5cCIgOiAiSldUIiwia2lkIiA6ICJhU1RaZm42bHpTdURYcUttRkg1SzN5UDFhT0FxUkhTNm9OendMUExaTXhFIn0.eyJleHAiOjE3ODYyMjUzMzMsImlhdCI6MTY5MTUzMDkzMywianRpIjoiYjU0MmU3MTQtYzJkMS00NTY2LWJkY2MtYmQ5NzA0ODY1ZjgzIiwiaXNzIjoiaHR0cHM6Ly9rYy5wZXRlcnNidXJnLnJ1L3JlYWxtcy9lZ3MtYXBpIiwiYXVkIjoiYWNjb3VudCIsInN1YiI6ImJjYjQ2NzljLTU3ZGItNDU5ZC1iNWUxLWRlOGI4Yzg5MTMwMyIsInR5cCI6IkJlYXJlciIsImF6cCI6ImFkbWluLXJlc3QtY2xpZW50Iiwic2Vzc2lvbl9zdGF0ZSI6IjJhOTgwMzUyLTY1M2QtNGZlZC1iMDI1LWQ1N2U0NDRjZmM3NiIsImFjciI6IjEiLCJhbGxvd2VkLW9yaWdpbnMiOlsiLyoiXSwicmVhbG1fYWNjZXNzIjp7InJvbGVzIjpbImRlZmF1bHQtcm9sZXMtZWdzLWFwaSIsIm9mZmxpbmVfYWNjZXNzIiwidW1hX2F1dGhvcml6YXRpb24iXX0sInJlc291cmNlX2FjY2VzcyI6eyJhY2NvdW50Ijp7InJvbGVzIjpbIm1hbmFnZS1hY2NvdW50IiwibWFuYWdlLWFjY291bnQtbGlua3MiLCJ2aWV3LXByb2ZpbGUiXX19LCJzY29wZSI6ImVtYWlsIHByb2ZpbGUiLCJzaWQiOiIyYTk4MDM1Mi02NTNkLTRmZWQtYjAyNS1kNTdlNDQ0Y2ZjNzYiLCJlbWFpbF92ZXJpZmllZCI6ZmFsc2UsIm5hbWUiOiLQktC70LDQtNC40LzQuNGAINCv0LrQvtCy0LvQtdCyIiwicHJlZmVycmVkX3VzZXJuYW1lIjoiZTBmYzc2OGRhOTA4MjNiODgwZGQzOGVhMDJjMmQ5NTciLCJnaXZlbl9uYW1lIjoi0JLQu9Cw0LTQuNC80LjRgCIsImZhbWlseV9uYW1lIjoi0K_QutC-0LLQu9C10LIifQ.FTKiC1hpWcOkmSW9QZpC-RY7Ko50jw1mDMfXIWYxlQ-zehLm2CLmOnHvYoOoI39k2OzeCIAB9ZdRrrGZc6G9Z1eFELUjNGEqKxSC1Phj9ATemKgbOKEttk-OGc-rFr9VPA8_SnfvLts6wTI2YK33YBIxCF5nCbnr4Qj3LeEQ0d6Hy8PO4ATrBF5EOeuAZRprvIEjXe_f8N9ONKckCPB-xFB4P2pZlVXGoCNoewGEcY3zXH4khezN6zcVr6tpc6G8dBv9EqT_v92IDSg-aXQk6ysA0cO0-6x5w1-_qU0iHGIAPsLNV9IKBoFbjc0JH6cWabldPRH12NP1trvYfqKDGQ"
|
||||
DOMAIN = "https://geointelect2.gate.petersburg.ru"
|
@ -25,10 +25,12 @@ const styles = {
|
||||
}
|
||||
|
||||
type ViewProps = {
|
||||
myId: number,
|
||||
announcement: Announcement,
|
||||
}
|
||||
|
||||
const View = ({
|
||||
myId,
|
||||
announcement: { name, category, bestBy, description, lat, lng, address, metro, userId },
|
||||
}: ViewProps) => (
|
||||
<>
|
||||
@ -41,7 +43,7 @@ const View = ({
|
||||
<p className='mb-0'>{description}</p>
|
||||
|
||||
<p className='mb-3'>
|
||||
Рейтинг пользователя: <StarRating dynamic userId={userId} />
|
||||
Рейтинг пользователя: <StarRating dynamic={myId !== userId} userId={userId} />
|
||||
</p>
|
||||
|
||||
<MapContainer style={styles.map} center={[lat, lng]} zoom={16} >
|
||||
@ -62,12 +64,14 @@ const View = ({
|
||||
)
|
||||
|
||||
type ControlProps = {
|
||||
myId: number,
|
||||
closeRefresh: () => void,
|
||||
announcement: Announcement,
|
||||
showDispose: () => void
|
||||
}
|
||||
|
||||
function Control({
|
||||
myId,
|
||||
closeRefresh,
|
||||
announcement: { bookedBy, id, userId },
|
||||
showDispose,
|
||||
@ -76,8 +80,6 @@ function Control({
|
||||
|
||||
const { handleRemove, removeButton } = useRemoveAnnouncement(closeRefresh)
|
||||
|
||||
const myId = useId()
|
||||
|
||||
return (
|
||||
<>
|
||||
<p>Забронировали {bookedBy + (bookButton.disabled ? 1 : 0)} чел.</p>
|
||||
@ -111,6 +113,8 @@ function AnnouncementDetails({
|
||||
|
||||
const [disposeShow, setDisposeShow] = useState(false)
|
||||
|
||||
const myId = useId()
|
||||
|
||||
return (
|
||||
<div
|
||||
className='modal'
|
||||
@ -124,11 +128,16 @@ function AnnouncementDetails({
|
||||
</Modal.Header>
|
||||
|
||||
<Modal.Body>
|
||||
<View announcement={announcement} />
|
||||
<View myId={myId} announcement={announcement} />
|
||||
</Modal.Body>
|
||||
|
||||
<Modal.Footer>
|
||||
<Control closeRefresh={closeRefresh} showDispose={() => setDisposeShow(true)} announcement={announcement} />
|
||||
<Control
|
||||
myId={myId}
|
||||
closeRefresh={closeRefresh}
|
||||
showDispose={() => setDisposeShow(true)}
|
||||
announcement={announcement}
|
||||
/>
|
||||
</Modal.Footer>
|
||||
</Modal.Dialog>
|
||||
<Modal centered show={disposeShow} onHide={() => setDisposeShow(false)} style={{ zIndex: 100000 }}>
|
||||
|
@ -7,7 +7,7 @@ function Poetry() {
|
||||
const poetry = usePoetry()
|
||||
|
||||
return (
|
||||
<div className={styles.container}>
|
||||
<section>
|
||||
<h4 className='fw-bold'>Поэзия</h4> {
|
||||
gotResponse(poetry) ? (
|
||||
gotError(poetry) ? (
|
||||
@ -26,6 +26,7 @@ function Poetry() {
|
||||
}}
|
||||
/>
|
||||
<p><em>{poetry.data.author}</em></p>
|
||||
<img src={`/poem_pic/${poetry.data.id}`} alt='Иллюстрация' />
|
||||
</>
|
||||
)
|
||||
) : (
|
||||
@ -33,7 +34,7 @@ function Poetry() {
|
||||
)
|
||||
}
|
||||
|
||||
</div>
|
||||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -7,9 +7,6 @@ type PointsProps = {
|
||||
}
|
||||
|
||||
const styles = {
|
||||
container: {
|
||||
paddingBottom: 8,
|
||||
} as CSSProperties,
|
||||
points: {
|
||||
float: 'right',
|
||||
} as CSSProperties,
|
||||
@ -22,7 +19,6 @@ const styles = {
|
||||
|
||||
function Points({ points }: PointsProps) {
|
||||
return (
|
||||
<div style={styles.container}>
|
||||
<h5>
|
||||
Набрано очков:
|
||||
<span style={styles.points}>
|
||||
@ -33,7 +29,6 @@ function Points({ points }: PointsProps) {
|
||||
{points}
|
||||
</span>
|
||||
</h5>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -8,18 +8,17 @@ import styles from '../styles/StarRating.module.css'
|
||||
type StarProps = {
|
||||
filled: boolean,
|
||||
selected: boolean,
|
||||
setMyRate?: () => void,
|
||||
selectRate?: () => void,
|
||||
sendMyRate?: () => void,
|
||||
disabled: boolean
|
||||
}
|
||||
|
||||
function Star({ filled, selected, setMyRate, sendMyRate, disabled }: StarProps) {
|
||||
function Star({ filled, selected, selectRate, disabled }: StarProps) {
|
||||
return (
|
||||
<button
|
||||
className={`${styles.star} ${filled ? styles.starFilled : ''} ${selected ? styles.starSelected : ''}`}
|
||||
onMouseEnter={setMyRate}
|
||||
onFocus={setMyRate}
|
||||
onClick={sendMyRate}
|
||||
onMouseEnter={selectRate}
|
||||
onFocus={selectRate}
|
||||
disabled={disabled}
|
||||
>★</button> // star
|
||||
)
|
||||
@ -28,21 +27,23 @@ function Star({ filled, selected, setMyRate, sendMyRate, disabled }: StarProps)
|
||||
type StarRatingProps = {
|
||||
userId: number,
|
||||
dynamic?: boolean,
|
||||
style?: React.CSSProperties,
|
||||
}
|
||||
|
||||
function StarRating({ userId, dynamic = false }: StarRatingProps) {
|
||||
const rating = useUserRating(userId)
|
||||
|
||||
const [selectedRate, setSelectedRate] = useState(0)
|
||||
const [myRate, setMyRate] = useState(0)
|
||||
const rated = myRate > 0
|
||||
|
||||
const { doSendRate } = useSendRate()
|
||||
|
||||
async function sendMyRate() {
|
||||
const res = await doSendRate(myRate, userId)
|
||||
const res = await doSendRate(selectedRate, userId)
|
||||
|
||||
if (res) {
|
||||
rating.refetch()
|
||||
setMyRate(selectedRate)
|
||||
}
|
||||
}
|
||||
|
||||
@ -59,15 +60,30 @@ function StarRating({ userId, dynamic = false }: StarRatingProps) {
|
||||
}
|
||||
|
||||
return (
|
||||
<span className={styles.starContainer} onMouseLeave={() => setMyRate(0)}>
|
||||
<span
|
||||
className={styles.starContainer}
|
||||
|
||||
onClick={() => dynamic && !rated && void sendMyRate()}
|
||||
|
||||
onMouseEnter={() => rated && setSelectedRate(myRate)}
|
||||
onMouseLeave={() => setSelectedRate(0)}
|
||||
|
||||
onFocus={() => rated && setSelectedRate(myRate)}
|
||||
onBlur={() => setSelectedRate(0)}
|
||||
|
||||
onTouchStart={() => rated && setSelectedRate(myRate)}
|
||||
onTouchEnd={() => setSelectedRate(0)}
|
||||
|
||||
title={`Пользователи: ${Math.round(rating.data)}\nВы: ${myRate}`}
|
||||
tabIndex={0}
|
||||
>
|
||||
{...Array(5).fill(5).map((_, i) => (
|
||||
<Star
|
||||
key={i}
|
||||
filled={i < Math.round(rating.data)}
|
||||
selected={i < myRate}
|
||||
setMyRate={() => dynamic && setMyRate(i + 1)}
|
||||
sendMyRate={() => dynamic && void sendMyRate()}
|
||||
disabled={!dynamic}
|
||||
selected={i < selectedRate}
|
||||
selectRate={() => dynamic && !rated && setSelectedRate(i + 1)}
|
||||
disabled={!dynamic || rated}
|
||||
/>
|
||||
))}
|
||||
</span >
|
||||
|
@ -37,6 +37,7 @@ const styles = {
|
||||
objectFit: 'contain',
|
||||
borderRadius: 12,
|
||||
marginBottom: 5,
|
||||
maxWidth: 'inherit',
|
||||
} as CSSProperties,
|
||||
title: {
|
||||
overflow: 'hidden',
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useCallback, useEffect, useState } from 'react'
|
||||
|
||||
import useSend from './useSend'
|
||||
|
||||
@ -54,7 +54,9 @@ function useFetch<R, T extends NonNullable<unknown>>(
|
||||
): UseFetchReturn<T> {
|
||||
const [data, setData] = useState(initialData)
|
||||
|
||||
const { doSend, loading, error } = useSend(
|
||||
const [fetchLoading, setFetchLoading] = useState(true)
|
||||
|
||||
const { doSend, error } = useSend(
|
||||
url,
|
||||
method,
|
||||
needAuth,
|
||||
@ -64,20 +66,26 @@ function useFetch<R, T extends NonNullable<unknown>>(
|
||||
params,
|
||||
)
|
||||
|
||||
function refetch() {
|
||||
const refetch = useCallback(() => {
|
||||
setFetchLoading(true)
|
||||
doSend().then(
|
||||
data => { if (data !== undefined) setData(data) }
|
||||
data => {
|
||||
if (data !== undefined) {
|
||||
setData(data)
|
||||
}
|
||||
setFetchLoading(false)
|
||||
}
|
||||
).catch( // must never occur
|
||||
err => import.meta.env.DEV && console.error('Failed to do fetch request', err)
|
||||
)
|
||||
}
|
||||
}, [doSend])
|
||||
|
||||
useEffect(refetch, [doSend])
|
||||
useEffect(refetch, [refetch])
|
||||
|
||||
if (loading === true) {
|
||||
if (fetchLoading === true) {
|
||||
return {
|
||||
data: undefined,
|
||||
loading,
|
||||
loading: fetchLoading,
|
||||
error: null,
|
||||
refetch,
|
||||
}
|
||||
@ -86,7 +94,7 @@ function useFetch<R, T extends NonNullable<unknown>>(
|
||||
if (error !== null) {
|
||||
return {
|
||||
data: undefined,
|
||||
loading,
|
||||
loading: fetchLoading,
|
||||
error,
|
||||
refetch,
|
||||
}
|
||||
@ -94,7 +102,7 @@ function useFetch<R, T extends NonNullable<unknown>>(
|
||||
|
||||
return {
|
||||
data: data!,
|
||||
loading,
|
||||
loading: fetchLoading,
|
||||
error,
|
||||
refetch,
|
||||
}
|
||||
|
@ -26,6 +26,7 @@ function UserPage() {
|
||||
<SignOut />
|
||||
</BackHeader>
|
||||
|
||||
<div className='mb-4'>
|
||||
<Points points={
|
||||
gotResponse(user) ? (
|
||||
gotError(user) ? -1 : user.data?.points
|
||||
@ -34,7 +35,6 @@ function UserPage() {
|
||||
)
|
||||
} />
|
||||
|
||||
<div>
|
||||
<h5 className={styles.userRating}>
|
||||
Ваша оценка:
|
||||
<StarRating userId={user.data?.id || 1} />
|
||||
@ -45,7 +45,9 @@ function UserPage() {
|
||||
<CategoryPreview key={cat} category={cat} />
|
||||
))}
|
||||
|
||||
<div className='mb-3'>
|
||||
<Poetry />
|
||||
</div>
|
||||
</Container>
|
||||
)
|
||||
}
|
||||
|
@ -3,5 +3,5 @@
|
||||
}
|
||||
|
||||
.text {
|
||||
white-space: 'pre-wrap';
|
||||
white-space: pre-wrap;
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user