chore: migrate to new flowbite-react

This commit is contained in:
Kentai Radiquum 2025-04-04 00:29:19 +05:00
parent 8daab3b3c1
commit 329448c9fc
Signed by: Radiquum
GPG key ID: 858E8EE696525EED
32 changed files with 650 additions and 344 deletions

View file

@ -1,6 +1,14 @@
"use client";
import { Modal, Accordion } from "flowbite-react";
import {
Accordion,
AccordionContent,
AccordionPanel,
AccordionTitle,
Modal,
ModalBody,
ModalHeader,
} from "flowbite-react";
import Markdown from "markdown-to-jsx";
import { useEffect, useState } from "react";
import Styles from "./ChangelogModal.module.css";
@ -37,8 +45,8 @@ export const ChangelogModal = (props: {
return (
<Modal show={props.isOpen} onClose={() => props.setIsOpen(false)}>
<Modal.Header>Список изменений v{props.version}</Modal.Header>
<Modal.Body>
<ModalHeader>Список изменений v{props.version}</ModalHeader>
<ModalBody>
<Markdown className={Styles.markdown}>
{currentVersionChangelog}
</Markdown>
@ -46,8 +54,8 @@ export const ChangelogModal = (props: {
{props.previousVersions.length > 0 &&
props.previousVersions.map((version) => {
return (
<Accordion.Panel key={version}>
<Accordion.Title
<AccordionPanel key={version}>
<AccordionTitle
onClickCapture={(e) => {
if (!previousVersionsChangelog.hasOwnProperty(version)) {
_fetchVersionChangelog(version).then((data) => {
@ -62,19 +70,19 @@ export const ChangelogModal = (props: {
}}
>
Список изменений v{version}
</Accordion.Title>
<Accordion.Content>
</AccordionTitle>
<AccordionContent>
{previousVersionsChangelog.hasOwnProperty(version) ?
<Markdown className={Styles.markdown}>
{previousVersionsChangelog[version]}
</Markdown>
: <div>Загрузка ...</div>}
</Accordion.Content>
</Accordion.Panel>
</AccordionContent>
</AccordionPanel>
);
})}
</Accordion>
</Modal.Body>
</ModalBody>
</Modal>
);
};

View file

@ -1,4 +1,4 @@
import { Button, Modal, ToggleSwitch, Label, Textarea } from "flowbite-react";
import { Button, Label, Modal, ModalBody, ModalHeader, Textarea, ToggleSwitch } from "flowbite-react";
import { CommentsComment } from "./Comments.Comment";
import { useState } from "react";
import { ENDPOINTS } from "#/api/config";
@ -68,12 +68,12 @@ export const CommentsAddModal = (props: {
show={props.isOpen}
onClose={() => props.setIsOpen(false)}
>
<Modal.Header>
<ModalHeader>
<p className="text-lg font-bold text-gray-900 lg:text-2xl dark:text-white">
{props.isReply ? "Ответ на комментарий" : "Оставить комментарий"}
</p>
</Modal.Header>
<Modal.Body>
</ModalHeader>
<ModalBody>
{props.isReply && (
<div className="mb-4">
<CommentsComment
@ -98,7 +98,7 @@ export const CommentsAddModal = (props: {
<form className="flex flex-col gap-4" onSubmit={(e) => _sendComment(e)}>
<div>
<div className="block mb-2 sr-only">
<Label htmlFor="comment" value="Ваш комментарий." />
<Label htmlFor="comment">Ваш комментарий.</Label>
</div>
<Textarea
id="comment"
@ -132,7 +132,7 @@ export const CommentsAddModal = (props: {
</Button>
</div>
</form>
</Modal.Body>
</ModalBody>
</Modal>
);
};

View file

@ -1,7 +1,7 @@
import { unixToDate, sinceUnixDate } from "#/api/utils";
import { useEffect, useState } from "react";
import { ENDPOINTS } from "#/api/config";
import { Button, Dropdown } from "flowbite-react";
import { Button, Dropdown, DropdownItem } from "flowbite-react";
import Link from "next/link";
import { CommentsAddModal } from "./Comments.Add";
import { CommentsEditModal } from "./Comments.Edit";
@ -183,12 +183,12 @@ export const CommentsComment = (props: {
<span className="w-6 h-6 bg-gray-400 iconify mdi--more-horiz hover:bg-gray-800 active:bg-gray-800"></span>
)}
>
<Dropdown.Item onClick={() => setIsEditCommentsOpen(true)}>
<DropdownItem onClick={() => setIsEditCommentsOpen(true)}>
Редактировать
</Dropdown.Item>
<Dropdown.Item onClick={() => _deleteComment()}>
</DropdownItem>
<DropdownItem onClick={() => _deleteComment()}>
Удалить
</Dropdown.Item>
</DropdownItem>
</Dropdown>
)}
</footer>

View file

@ -1,4 +1,4 @@
import { Button, Modal, ToggleSwitch, Label, Textarea } from "flowbite-react";
import { Button, Label, Modal, ModalBody, ModalHeader, Textarea, ToggleSwitch } from "flowbite-react";
import { useState } from "react";
import { ENDPOINTS } from "#/api/config";
@ -56,16 +56,16 @@ export const CommentsEditModal = (props: {
show={props.isOpen}
onClose={() => props.setIsOpen(false)}
>
<Modal.Header>
<ModalHeader>
<p className="text-lg font-bold text-gray-900 lg:text-2xl dark:text-white">
Редактировать комментарий
</p>
</Modal.Header>
<Modal.Body>
</ModalHeader>
<ModalBody>
<form className="flex flex-col gap-4" onSubmit={(e) => _sendComment(e)}>
<div>
<div className="block mb-2 sr-only">
<Label htmlFor="comment" value="Редактировать ваш комментарий." />
<Label htmlFor="comment" >Редактировать ваш комментарий.</Label>
</div>
<Textarea
id="comment"
@ -99,7 +99,7 @@ export const CommentsEditModal = (props: {
</Button>
</div>
</form>
</Modal.Body>
</ModalBody>
</Modal>
);
};

View file

@ -1,4 +1,4 @@
import { Card, Button, Modal, Spinner } from "flowbite-react";
import { Button, Card, Modal, ModalHeader, Spinner } from "flowbite-react";
import { CommentsComment } from "./Comments.Comment";
import { useState, useEffect, useCallback } from "react";
import { ENDPOINTS } from "#/api/config";
@ -149,7 +149,7 @@ const CommentsAllModal = (props: {
show={props.isOpen}
onClose={() => props.setIsOpen(false)}
>
<Modal.Header>
<ModalHeader>
<div className="flex flex-col gap-1">
<h2 className="text-lg font-bold text-gray-900 lg:text-2xl dark:text-white">
Все комментарии
@ -158,7 +158,7 @@ const CommentsAllModal = (props: {
всего: {isLoading ? "загрузка..." : data[0].total_count}
</p>
</div>
</Modal.Header>
</ModalHeader>
<div
className="flex flex-col gap-2 p-4 overflow-y-auto"
onScroll={handleScroll}

View file

@ -1,7 +1,7 @@
import React, { useRef } from "react";
import Cropper, { ReactCropperElement } from "react-cropper";
import "cropperjs/dist/cropper.css";
import { Button, Modal } from "flowbite-react";
import { Button, Modal, ModalBody, ModalFooter, ModalHeader } from "flowbite-react";
type CropModalProps = {
isOpen: boolean;
@ -71,8 +71,8 @@ export const CropModal: React.FC<CropModalProps> = ({
}}
size={"7xl"}
>
<Modal.Header>Обрезать изображение</Modal.Header>
<Modal.Body>
<ModalHeader>Обрезать изображение</ModalHeader>
<ModalBody>
<Cropper
src={selectedImage}
style={{ height: 400, width: "100%" }}
@ -95,8 +95,8 @@ export const CropModal: React.FC<CropModalProps> = ({
</p>
<p>Используйте колёсико мыши что-бы изменить масштаб</p>
</div>
</Modal.Body>
<Modal.Footer>
</ModalBody>
<ModalFooter>
<Button
color={"blue"}
disabled={isActionsDisabled}
@ -120,7 +120,7 @@ export const CropModal: React.FC<CropModalProps> = ({
>
Отменить
</Button>
</Modal.Footer>
</ModalFooter>
</Modal>
);
};

View file

@ -1,6 +1,6 @@
import { ENDPOINTS } from "#/api/config";
import { tryCatchAPI, unixToDate, useSWRfetcher } from "#/api/utils";
import { Avatar, Button, Modal, useThemeMode } from "flowbite-react";
import { Avatar, Button, Modal, ModalHeader, useThemeMode } from "flowbite-react";
import { useCallback, useEffect, useState } from "react";
import useSWRInfinite from "swr/infinite";
import { Spinner } from "../Spinner/Spinner";
@ -130,7 +130,7 @@ export const ProfileBlockedUsersModal = (props: {
onClose={() => props.setIsOpen(false)}
size={"7xl"}
>
<Modal.Header>Заблокированные пользователи</Modal.Header>
<ModalHeader>Заблокированные пользователи</ModalHeader>
<div
className="flex flex-col gap-2 p-4 overflow-y-auto"
onScroll={handleScroll}

View file

@ -1,6 +1,6 @@
"use client";
import { Button, Modal, Textarea, useThemeMode } from "flowbite-react";
import { Button, Modal, ModalBody, ModalFooter, ModalHeader, Textarea, useThemeMode } from "flowbite-react";
import { ENDPOINTS } from "#/api/config";
import { useEffect, useState } from "react";
import { useSWRConfig } from "swr";
@ -138,8 +138,8 @@ export const ProfileEditLoginModal = (props: {
onClose={() => props.setIsOpen(false)}
size={"4xl"}
>
<Modal.Header>Изменить никнейм</Modal.Header>
<Modal.Body>
<ModalHeader>Изменить никнейм</ModalHeader>
<ModalBody>
{loading ?
<div className="flex items-center justify-center py-8">
<Spinner />
@ -173,8 +173,8 @@ export const ProfileEditLoginModal = (props: {
}
</>
}
</Modal.Body>
<Modal.Footer>
</ModalBody>
<ModalFooter>
{_loginData.is_change_available && (
<Button
color="blue"
@ -191,7 +191,7 @@ export const ProfileEditLoginModal = (props: {
>
Отмена
</Button>
</Modal.Footer>
</ModalFooter>
</Modal>
);
};

View file

@ -1,6 +1,6 @@
"use client";
import { FileInput, Label, Modal, useThemeMode } from "flowbite-react";
import { FileInput, Label, Modal, ModalBody, ModalHeader, useThemeMode } from "flowbite-react";
import { Spinner } from "../Spinner/Spinner";
import useSWR from "swr";
import { ENDPOINTS } from "#/api/config";
@ -201,8 +201,8 @@ export const ProfileEditModal = (props: {
onClose={() => props.setIsOpen(false)}
size={"7xl"}
>
<Modal.Header>Редактирование профиля</Modal.Header>
<Modal.Body>
<ModalHeader>Редактирование профиля</ModalHeader>
<ModalBody>
{prefLoading ?
<Spinner />
: <div className="flex flex-col gap-4">
@ -394,7 +394,7 @@ export const ProfileEditModal = (props: {
</div>
</div>
}
</Modal.Body>
</ModalBody>
</Modal>
{props.token ?
<>

View file

@ -1,6 +1,6 @@
"use client";
import { Modal, useThemeMode } from "flowbite-react";
import { Modal, ModalBody, ModalHeader, useThemeMode } from "flowbite-react";
import { ENDPOINTS } from "#/api/config";
import { useState } from "react";
import { toast } from "react-toastify";
@ -98,8 +98,8 @@ export const ProfileEditPrivacyModal = (props: {
onClose={() => props.setIsOpen(false)}
size={"4xl"}
>
<Modal.Header>{setting_text[props.setting]}</Modal.Header>
<Modal.Body>
<ModalHeader>{setting_text[props.setting]}</ModalHeader>
<ModalBody>
{props.setting != "none" ?
<>
<div className="flex flex-col gap-2">
@ -202,7 +202,7 @@ export const ProfileEditPrivacyModal = (props: {
</div>
</>
: ""}
</Modal.Body>
</ModalBody>
</Modal>
);
};

View file

@ -1,6 +1,15 @@
"use client";
import { Button, Modal, Label, TextInput, useThemeMode } from "flowbite-react";
import {
Button,
Label,
Modal,
ModalBody,
ModalFooter,
ModalHeader,
TextInput,
useThemeMode,
} from "flowbite-react";
import { Spinner } from "../Spinner/Spinner";
import { ENDPOINTS } from "#/api/config";
import { useEffect, useState } from "react";
@ -164,8 +173,8 @@ export const ProfileEditSocialModal = (props: {
onClose={() => props.setIsOpen(false)}
size={"4xl"}
>
<Modal.Header>Соц. сети</Modal.Header>
<Modal.Body>
<ModalHeader>Соц. сети</ModalHeader>
<ModalBody>
<p className="p-2 text-gray-400 border-2 border-gray-200 rounded-md dark:border-gray-500 dark:text-gray-300">
Укажите ссылки на свои социальные сети, чтобы другие пользователи
могли с вами связаться
@ -177,7 +186,7 @@ export const ProfileEditSocialModal = (props: {
: <div className="flex flex-col gap-4 py-4">
<div>
<div className="block mb-2">
<Label htmlFor="vk-page" value="ВКонтакте" />
<Label htmlFor="vk-page">ВКонтакте</Label>
</div>
<TextInput
id="vk-page"
@ -189,7 +198,7 @@ export const ProfileEditSocialModal = (props: {
</div>
<div>
<div className="block mb-2">
<Label htmlFor="tg-page" value="Telegram" />
<Label htmlFor="tg-page">Telegram</Label>
</div>
<TextInput
id="tg-page"
@ -201,7 +210,7 @@ export const ProfileEditSocialModal = (props: {
</div>
<div>
<div className="block mb-2">
<Label htmlFor="discord-page" value="Discord" />
<Label htmlFor="discord-page">Discord</Label>
</div>
<TextInput
id="discord-page"
@ -213,7 +222,7 @@ export const ProfileEditSocialModal = (props: {
</div>
<div>
<div className="block mb-2">
<Label htmlFor="inst-page" value="Instagram" />
<Label htmlFor="inst-page">Instagram</Label>
</div>
<TextInput
id="inst-page"
@ -225,7 +234,7 @@ export const ProfileEditSocialModal = (props: {
</div>
<div>
<div className="block mb-2">
<Label htmlFor="tt-page" value="TikTok" />
<Label htmlFor="tt-page">TikTok</Label>
</div>
<TextInput
id="tt-page"
@ -237,8 +246,8 @@ export const ProfileEditSocialModal = (props: {
</div>
</div>
}
</Modal.Body>
<Modal.Footer>
</ModalBody>
<ModalFooter>
<Button
color="blue"
onClick={() => _setSocialSetting()}
@ -253,7 +262,7 @@ export const ProfileEditSocialModal = (props: {
>
Отмена
</Button>
</Modal.Footer>
</ModalFooter>
</Modal>
);
};

View file

@ -1,6 +1,6 @@
"use client";
import { Button, Modal, Textarea, useThemeMode } from "flowbite-react";
import { Button, Modal, ModalBody, ModalFooter, ModalHeader, Textarea, useThemeMode } from "flowbite-react";
import { ENDPOINTS } from "#/api/config";
import { useEffect, useState } from "react";
import { useSWRConfig } from "swr";
@ -96,8 +96,8 @@ export const ProfileEditStatusModal = (props: {
onClose={() => props.setIsOpen(false)}
size={"4xl"}
>
<Modal.Header>Изменить статус</Modal.Header>
<Modal.Body>
<ModalHeader>Изменить статус</ModalHeader>
<ModalBody>
<Textarea
disabled={loading}
rows={3}
@ -111,8 +111,8 @@ export const ProfileEditStatusModal = (props: {
<p className="text-sm text-right text-gray-500 dark:text-gray-300">
{_stringLength}/80
</p>
</Modal.Body>
<Modal.Footer>
</ModalBody>
<ModalFooter>
<Button
color="blue"
onClick={() => _setStatusSetting()}
@ -123,7 +123,7 @@ export const ProfileEditStatusModal = (props: {
<Button color="red" onClick={() => props.setIsOpen(false)}>
Отмена
</Button>
</Modal.Footer>
</ModalFooter>
</Modal>
);
};

View file

@ -1,10 +1,4 @@
import {
Card,
RatingStar,
Rating,
Modal,
Button,
} from "flowbite-react";
import { Button, Card, Modal, ModalHeader, Rating, RatingStar } from "flowbite-react";
import { unixToDate, useSWRfetcher } from "#/api/utils";
import Link from "next/link";
@ -119,7 +113,7 @@ const ProfileReleaseRatingsModal = (props: {
onClose={() => props.setIsOpen(false)}
size={"4xl"}
>
<Modal.Header>Оценки</Modal.Header>
<ModalHeader>Оценки</ModalHeader>
<div
className="flex flex-col gap-2 p-4 overflow-y-auto"
onScroll={handleScroll}

View file

@ -1,4 +1,4 @@
import { Card, Table } from "flowbite-react";
import { Card, Table, TableBody, TableCell, TableRow } from "flowbite-react";
import { ReleaseInfoSearchLink } from "#/components/ReleaseInfo/ReleaseInfo.SearchLink";
import { unixToDate, minutesToTime } from "#/api/utils";
const weekDay = [
@ -30,9 +30,9 @@ export const ReleaseInfoInfo = (props: {
return (
<Card>
<Table>
<Table.Body>
<Table.Row>
<Table.Cell className="py-0">
<TableBody>
<TableRow>
<TableCell className="py-0">
{props.country ?
props.country.toLowerCase() == "япония" ?
<span className="w-8 h-8 iconify-color twemoji--flag-for-japan"></span>
@ -40,45 +40,45 @@ export const ReleaseInfoInfo = (props: {
: <span className="w-8 h-8 iconify-color twemoji--flag-for-united-nations "></span>
}
</Table.Cell>
<Table.Cell className="font-medium text-gray-900 whitespace-nowrap dark:text-white">
</TableCell>
<TableCell className="font-medium text-gray-900 whitespace-nowrap dark:text-white">
{props.country && props.country}
{(props.aired_on_date != 0 || props.year) && ", "}
{props.season && props.season != 0 ?
`${YearSeason[props.season]} `
: ""}
{props.year && `${props.year} г.`}
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell className="py-0">
</TableCell>
</TableRow>
<TableRow>
<TableCell className="py-0">
<span className="w-8 h-8 iconify-color mdi--animation-play-outline dark:invert"></span>
</Table.Cell>
<Table.Cell className="font-medium text-gray-900 whitespace-nowrap dark:text-white">
</TableCell>
<TableCell className="font-medium text-gray-900 whitespace-nowrap dark:text-white">
{props.episodes.released ? props.episodes.released : "?"}
{"/"}
{props.episodes.total ? props.episodes.total + " эп. " : "? эп. "}
{props.duration != 0 &&
`по ${minutesToTime(props.duration, "daysHours")}`}
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell className="py-0">
</TableCell>
</TableRow>
<TableRow>
<TableCell className="py-0">
<span className="w-8 h-8 iconify-color mdi--calendar-outline dark:invert"></span>
</Table.Cell>
<Table.Cell className="font-medium text-gray-900 dark:text-white">
</TableCell>
<TableCell className="font-medium text-gray-900 dark:text-white">
{props.category}
{", "}
{props.broadcast == 0 ?
props.status.toLowerCase()
: `выходит ${weekDay[props.broadcast]}`}
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell className="py-0">
</TableCell>
</TableRow>
<TableRow>
<TableCell className="py-0">
<span className="w-8 h-8 iconify-color mdi--people-group-outline dark:invert"></span>
</Table.Cell>
<Table.Cell className="font-medium text-gray-900 dark:text-white">
</TableCell>
<TableCell className="font-medium text-gray-900 dark:text-white">
{props.studio && (
<>
{"Студия: "}
@ -117,13 +117,13 @@ export const ReleaseInfoInfo = (props: {
/>
</>
)}
</Table.Cell>
</Table.Row>
<Table.Row>
<Table.Cell className="py-0">
</TableCell>
</TableRow>
<TableRow>
<TableCell className="py-0">
<span className="w-8 h-8 iconify-color mdi--tag-outline dark:invert"></span>
</Table.Cell>
<Table.Cell className="font-medium text-gray-900 dark:text-white">
</TableCell>
<TableCell className="font-medium text-gray-900 dark:text-white">
{props.genres &&
props.genres.split(", ").map((genre: string, index: number) => {
return (
@ -133,14 +133,14 @@ export const ReleaseInfoInfo = (props: {
</div>
);
})}
</Table.Cell>
</Table.Row>
</TableCell>
</TableRow>
{props.status.toLowerCase() == "анонс" && (
<Table.Row>
<Table.Cell className="py-0">
<TableRow>
<TableCell className="py-0">
<span className="w-8 h-8 iconify-color mdi--clock-outline dark:invert"></span>
</Table.Cell>
<Table.Cell className="font-medium text-gray-900 whitespace-nowrap dark:text-white">
</TableCell>
<TableCell className="font-medium text-gray-900 whitespace-nowrap dark:text-white">
{props.aired_on_date != 0 ?
unixToDate(props.aired_on_date, "full")
: props.year ?
@ -151,10 +151,10 @@ export const ReleaseInfoInfo = (props: {
{props.year && `${props.year} г.`}
</>
: "Скоро"}
</Table.Cell>
</Table.Row>
</TableCell>
</TableRow>
)}
</Table.Body>
</TableBody>
</Table>
</Card>
);

View file

@ -1,20 +1,26 @@
import {
Card,
Rating,
Flowbite,
Button,
CustomFlowbiteTheme,
Card,
Modal,
ModalBody,
ModalFooter,
ModalHeader,
Rating,
RatingAdvanced,
RatingStar,
RatingAdvancedTheme,
} from "flowbite-react";
import { numberDeclension } from "#/api/utils";
import { useState } from "react";
import { ENDPOINTS } from "#/api/config";
const RatingTheme: CustomFlowbiteTheme = {
ratingAdvanced: {
progress: {
base: "mx-4 h-5 w-3/4 rounded bg-gray-200 dark:bg-gray-700",
},
const CustomRatingTheme: RatingAdvancedTheme = {
base: "flex items-center",
label: "text-sm font-medium text-cyan-600 dark:text-cyan-500",
progress: {
base: "mx-4 h-5 w-3/4 rounded bg-gray-200 dark:bg-gray-700",
fill: "h-5 rounded bg-yellow-400",
label: "text-sm font-medium text-cyan-600 dark:text-cyan-500",
},
};
export const ReleaseInfoRating = (props: {
@ -39,7 +45,7 @@ export const ReleaseInfoRating = (props: {
<Card>
<div className="flex flex-col gap-2 sm:items-center sm:flex-row">
<Rating>
<Rating.Star />
<RatingStar />
<p className="ml-2 text-sm font-bold dark:text-white">
{props.grade.toFixed(2)} из 5
</p>
@ -48,7 +54,7 @@ export const ReleaseInfoRating = (props: {
<>
<span className="mx-1.5 h-1 w-1 rounded-full bg-gray-500 dark:bg-gray-400 hidden lg:block" />
<div className="flex items-center gap-2">
{vote ? (
{vote ?
<>
<p className="text-sm font-medium text-gray-500 dark:text-gray-400">
ваша оценка: {vote}
@ -62,8 +68,7 @@ export const ReleaseInfoRating = (props: {
изменить
</Button>
</>
) : (
<Button
: <Button
size={"xs"}
className="text-gray-500 border border-gray-600 rounded-full hover:bg-black hover:text-white hover:border-black dark:text-gray-400 dark:border-gray-500"
color="inline"
@ -71,7 +76,7 @@ export const ReleaseInfoRating = (props: {
>
оценить
</Button>
)}
}
</div>
</>
)}
@ -80,47 +85,50 @@ export const ReleaseInfoRating = (props: {
{props.votes.total}{" "}
{numberDeclension(props.votes.total, "голос", "голоса", "голосов")}
</p>
<Flowbite theme={{ theme: RatingTheme }}>
<Rating.Advanced
percentFilled={Math.floor(
(props.votes["5"] / props.votes.total) * 100
)}
className="mb-2"
>
5
</Rating.Advanced>
<Rating.Advanced
percentFilled={Math.floor(
(props.votes["4"] / props.votes.total) * 100
)}
className="mb-2"
>
4
</Rating.Advanced>
<Rating.Advanced
percentFilled={Math.floor(
(props.votes["3"] / props.votes.total) * 100
)}
className="mb-2"
>
3
</Rating.Advanced>
<Rating.Advanced
percentFilled={Math.floor(
(props.votes["2"] / props.votes.total) * 100
)}
className="mb-2"
>
2
</Rating.Advanced>
<Rating.Advanced
percentFilled={Math.floor(
(props.votes["1"] / props.votes.total) * 100
)}
>
1
</Rating.Advanced>
</Flowbite>
<RatingAdvanced
theme={CustomRatingTheme}
percentFilled={Math.floor(
(props.votes["5"] / props.votes.total) * 100
)}
className="mb-2"
>
5
</RatingAdvanced>
<RatingAdvanced
theme={CustomRatingTheme}
percentFilled={Math.floor(
(props.votes["4"] / props.votes.total) * 100
)}
className="mb-2"
>
4
</RatingAdvanced>
<RatingAdvanced
theme={CustomRatingTheme}
percentFilled={Math.floor(
(props.votes["3"] / props.votes.total) * 100
)}
className="mb-2"
>
3
</RatingAdvanced>
<RatingAdvanced
theme={CustomRatingTheme}
percentFilled={Math.floor(
(props.votes["2"] / props.votes.total) * 100
)}
className="mb-2"
>
2
</RatingAdvanced>
<RatingAdvanced
theme={CustomRatingTheme}
percentFilled={Math.floor(
(props.votes["1"] / props.votes.total) * 100
)}
>
1
</RatingAdvanced>
</Card>
<ReleaseInfoRatingModal
isOpen={isRatingModalOpen}
@ -178,8 +186,8 @@ const ReleaseInfoRatingModal = (props: {
show={props.isOpen}
onClose={() => props.setIsOpen(false)}
>
<Modal.Header>Оценка</Modal.Header>
<Modal.Body>
<ModalHeader>Оценка</ModalHeader>
<ModalBody>
<div>
<div className="block sm:hidden">
<Rating size="md" className="justify-center">
@ -191,7 +199,7 @@ const ReleaseInfoRatingModal = (props: {
onMouseOut={() => setCurElement(0)}
onClick={() => setVote(element)}
>
<Rating.Star
<RatingStar
filled={index + 1 <= curElement || index + 1 <= vote}
/>
</Button>
@ -208,7 +216,7 @@ const ReleaseInfoRatingModal = (props: {
onMouseOut={() => setCurElement(0)}
onClick={() => setVote(element)}
>
<Rating.Star
<RatingStar
filled={index + 1 <= curElement || index + 1 <= vote}
/>
</Button>
@ -216,8 +224,8 @@ const ReleaseInfoRatingModal = (props: {
</Rating>
</div>
</div>
</Modal.Body>
<Modal.Footer>
</ModalBody>
<ModalFooter>
<div className="flex gap-1 ml-auto">
<Button
disabled={isSending}
@ -241,7 +249,7 @@ const ReleaseInfoRatingModal = (props: {
Оценить
</Button>
</div>
</Modal.Footer>
</ModalFooter>
</Modal>
);
};

View file

@ -5,7 +5,7 @@ import useSWRInfinite from "swr/infinite";
import { useCallback, useEffect, useState } from "react";
import { tryCatchAPI, useSWRfetcher } from "#/api/utils";
import { toast } from "react-toastify";
import { useThemeMode } from "flowbite-react";
import { DropdownItem, ModalHeader, useThemeMode } from "flowbite-react";
const lists = [
{ list: 0, name: "Не смотрю" },
@ -174,12 +174,12 @@ export const ReleaseInfoUserList = (props: {
disabled={listEventDisabled}
>
{lists.map((list) => (
<Dropdown.Item
<DropdownItem
key={list.list}
onClick={() => _addToList(list.list)}
>
{list.name}
</Dropdown.Item>
</DropdownItem>
))}
</Dropdown>
<Button
@ -321,7 +321,7 @@ const AddReleaseToCollectionModal = (props: {
show={props.isOpen}
onClose={() => props.setIsOpen(false)}
>
<Modal.Header>Выбор коллекции</Modal.Header>
<ModalHeader>Выбор коллекции</ModalHeader>
<div
className="flex flex-col gap-2 p-4 overflow-y-auto"
onScroll={handleScroll}

View file

@ -3,7 +3,7 @@
import { Spinner } from "#/components/Spinner/Spinner";
import { useUserStore } from "#/store/auth";
import { useUserPlayerPreferencesStore } from "#/store/player";
import { Card, Dropdown, Button } from "flowbite-react";
import { Button, Card, Dropdown, DropdownItem } from "flowbite-react";
import { ENDPOINTS } from "#/api/config";
import { useState, useEffect } from "react";
import { Swiper, SwiperSlide } from "swiper/react";
@ -270,14 +270,14 @@ export const ReleasePlayer = (props: { id: number }) => {
theme={DropdownTheme}
>
{voiceoverInfo.map((voiceover: any) => (
<Dropdown.Item
<DropdownItem
key={`voiceover_${voiceover.id}`}
onClick={() =>
setSelectedVoiceoverAndSaveAsPreferred(voiceover)
}
>
{voiceover.name}
</Dropdown.Item>
</DropdownItem>
))}
</Dropdown>
<Dropdown
@ -286,12 +286,12 @@ export const ReleasePlayer = (props: { id: number }) => {
theme={DropdownTheme}
>
{sourcesInfo.map((source: any) => (
<Dropdown.Item
<DropdownItem
key={`source_${source.id}`}
onClick={() => setSelectedPlayerAndSaveAsPreferred(source)}
>
{source.name}
</Dropdown.Item>
</DropdownItem>
))}
</Dropdown>
</div>

View file

@ -1,6 +1,6 @@
"use client";
import { Dropdown } from "flowbite-react";
import { Dropdown, DropdownItem } from "flowbite-react";
import { numberDeclension } from "#/api/utils";
import { useUserPlayerPreferencesStore } from "#/store/player";
@ -55,7 +55,7 @@ export const SourceSelector = (props: {
)}
>
{props.availableSource.map((source: Source) => (
<Dropdown.Item
<DropdownItem
key={`source_${source.id}`}
onClick={() => {
playerPreferenceStore.setPreferredPlayer(
@ -69,7 +69,7 @@ export const SourceSelector = (props: {
}}
>
<DropdownItem {...source} />
</Dropdown.Item>
</DropdownItem>
))}
</Dropdown>
);

View file

@ -1,6 +1,6 @@
"use client";
import { Dropdown } from "flowbite-react";
import { Dropdown, DropdownItem } from "flowbite-react";
import { numberDeclension } from "#/api/utils";
import { useUserPlayerPreferencesStore } from "#/store/player";
@ -26,7 +26,7 @@ const DropdownTrigger = ({ icon, name, pinned }: Voiceover) => {
);
};
const DropdownItem = ({
const DropdownItemInternal = ({
icon,
name,
pinned,
@ -80,7 +80,7 @@ export const VoiceoverSelector = (props: {
)}
>
{props.availableVoiceover.map((voiceover: Voiceover) => (
<Dropdown.Item
<DropdownItem
className="w-fit"
key={`voiceover_${voiceover.id}`}
onClick={() => {
@ -94,8 +94,8 @@ export const VoiceoverSelector = (props: {
});
}}
>
<DropdownItem {...voiceover} />
</Dropdown.Item>
<DropdownItemInternal {...voiceover} />
</DropdownItem>
))}
</Dropdown>
);

View file

@ -4,12 +4,16 @@ import { CURRENT_APP_VERSION } from "#/api/config";
import { useUserStore } from "#/store/auth";
import { usePreferencesStore } from "#/store/preferences";
import {
Modal,
Button,
useThemeMode,
ToggleSwitch,
HR,
ButtonGroup,
Dropdown,
DropdownItem,
HR,
Modal,
ModalBody,
ModalHeader,
ToggleSwitch,
useThemeMode,
} from "flowbite-react";
import Link from "next/link";
@ -54,8 +58,8 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {
show={props.isOpen}
onClose={() => props.setIsOpen(false)}
>
<Modal.Header>Настройки</Modal.Header>
<Modal.Body>
<ModalHeader>Настройки</ModalHeader>
<ModalBody>
<div className="space-y-6">
<div className="flex items-center gap-2">
<span className="w-6 h-6 iconify material-symbols--palette-outline"></span>
@ -63,7 +67,7 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {
</div>
<div className="flex items-center justify-between">
<p className=" dark:text-white">Тема</p>
<Button.Group>
<ButtonGroup>
<Button
color={computedMode == "light" ? "blue" : "gray"}
onClick={() => setMode("light")}
@ -76,7 +80,7 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {
>
Темная
</Button>
</Button.Group>
</ButtonGroup>
</div>
<div className="flex items-center justify-between">
<p className=" dark:text-white max-w-96">
@ -121,7 +125,7 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {
>
{Object.keys(HomeCategory).map((key) => {
return (
<Dropdown.Item
<DropdownItem
key={key}
onClick={() =>
preferenceStore.setParams({
@ -133,7 +137,7 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {
}
>
{HomeCategory[key]}
</Dropdown.Item>
</DropdownItem>
);
})}
</Dropdown>
@ -152,7 +156,7 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {
>
{Object.keys(BookmarksCategory).map((key) => {
return (
<Dropdown.Item
<DropdownItem
key={key}
onClick={() =>
preferenceStore.setParams({
@ -164,7 +168,7 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {
}
>
{BookmarksCategory[key]}
</Dropdown.Item>
</DropdownItem>
);
})}
</Dropdown>
@ -182,7 +186,7 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {
{Object.keys(NavbarTitles).map(
(key: "always" | "links" | "selected" | "never") => {
return (
<Dropdown.Item
<DropdownItem
className={`${key == "links" ? "hidden lg:flex" : ""}`}
key={`navbar-titles-${key}`}
onClick={() =>
@ -192,7 +196,7 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {
}
>
{NavbarTitles[key]}
</Dropdown.Item>
</DropdownItem>
);
}
)}
@ -211,7 +215,7 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {
: "Нет"
}
>
<Dropdown.Item
<DropdownItem
onClick={() =>
preferenceStore.setFlags({
showFifthButton: null,
@ -219,10 +223,10 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {
}
>
Не показывать
</Dropdown.Item>
</DropdownItem>
{Object.keys(FifthButton).map((key) => {
return (
<Dropdown.Item
<DropdownItem
key={`navbar-fifthbutton-${key}`}
onClick={() =>
preferenceStore.setFlags({
@ -231,7 +235,7 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {
}
>
{FifthButton[key]}
</Dropdown.Item>
</DropdownItem>
);
})}
</Dropdown>
@ -340,7 +344,7 @@ export const SettingsModal = (props: { isOpen: boolean; setIsOpen: any }) => {
</div>
</Link>
</div>
</Modal.Body>
</ModalBody>
</Modal>
);
};