upd
This commit is contained in:
@@ -14,7 +14,10 @@ export default async function BlogPage() {
|
||||
|
||||
await queryClient.prefetchQuery({
|
||||
queryKey: ["articles"],
|
||||
queryFn: () => api.get("articles").json<IArticle[]>(),
|
||||
queryFn: () =>
|
||||
api
|
||||
.get("articles", { searchParams: { locale: "ru" } })
|
||||
.json<IArticle[]>(),
|
||||
});
|
||||
|
||||
return (
|
||||
|
||||
@@ -2,6 +2,7 @@ User-agent: *
|
||||
Disallow: /login
|
||||
Disallow: /form
|
||||
Disallow: /policy
|
||||
Disallow: /privacy-policy
|
||||
Disallow: /a1
|
||||
Disallow: /CircularProgressbar-path
|
||||
|
||||
|
||||
@@ -47,7 +47,7 @@ export function Footer() {
|
||||
<RutubeIcon />
|
||||
</div>
|
||||
</ContactLink>
|
||||
<ContactLink href="https://vk.com/graffinteractive?from=groups">
|
||||
<ContactLink href="https://vk.com/graff.estate">
|
||||
<div className="text-white lg:size-[1.389vw] size-[5.556vw] group-hover:text-black">
|
||||
<VkIcon />
|
||||
</div>
|
||||
@@ -88,11 +88,12 @@ export function ContactLink({
|
||||
className = "",
|
||||
}: PropsWithChildren<{ href: string; className?: string }>) {
|
||||
return (
|
||||
<Link
|
||||
<a
|
||||
href={href}
|
||||
target="_blank"
|
||||
className={`lg:rounded-[1.111vw] rounded-2xl bg-[#37393B99] lg:p-[1.25vw] p-[18px] hover:bg-white transition-all hover:text-black flex justify-center w-full group ${className}`}
|
||||
>
|
||||
{children}
|
||||
</Link>
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ export function ArticleContentFormModal({
|
||||
createdAt,
|
||||
drafted,
|
||||
id,
|
||||
locale,
|
||||
}: IArticle) {
|
||||
const { setModal } = useModalStore();
|
||||
|
||||
@@ -40,6 +41,7 @@ export function ArticleContentFormModal({
|
||||
cardImage,
|
||||
createdAt,
|
||||
drafted,
|
||||
locale,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -84,6 +86,7 @@ export function ArticleContentFormModal({
|
||||
drafted,
|
||||
posterImage,
|
||||
id,
|
||||
locale,
|
||||
}}
|
||||
/>
|
||||
)
|
||||
|
||||
@@ -5,6 +5,7 @@ import { useModalStore } from "@/stores/useModalStore";
|
||||
import { IArticle } from "@/types/IArticle";
|
||||
import { CheckboxesGroup } from "@/ui/CheckboxesGroup";
|
||||
import { TextInput } from "@/ui/TextInput";
|
||||
import { LocaleSwitch } from "@/ui/LocaleSwitch";
|
||||
import { FormProvider, useForm, useWatch } from "react-hook-form";
|
||||
import { ImageUploader } from "../ImageUploader";
|
||||
// import { ArticleContentFormModal } from "./ArticleContentFormModal";
|
||||
@@ -39,6 +40,7 @@ export function ArticleFormModal<TAction extends "create" | "edit">({
|
||||
blocks: [],
|
||||
tags: [],
|
||||
drafted: true,
|
||||
locale: "ru",
|
||||
},
|
||||
mode: "onChange",
|
||||
});
|
||||
@@ -51,9 +53,9 @@ export function ArticleFormModal<TAction extends "create" | "edit">({
|
||||
setModal(<ArticleContentFormModal {...article} />);
|
||||
}
|
||||
|
||||
const { handleSubmit, getValues, control } = form;
|
||||
const { handleSubmit, getValues, control, setValue } = form;
|
||||
|
||||
const { title, tags, cardImage, posterImage } = useWatch({ control });
|
||||
const { title, tags, cardImage, posterImage, locale } = useWatch({ control });
|
||||
|
||||
async function handleSave(drafted: boolean) {
|
||||
await mutateAsync({
|
||||
@@ -101,7 +103,7 @@ export function ArticleFormModal<TAction extends "create" | "edit">({
|
||||
name="cardImage"
|
||||
label="Загрузите или перетащите изображение для превью (рекомендованнный размер 1080/1080 px)"
|
||||
/>
|
||||
<div className="gap-y-4 flex flex-col">
|
||||
<div className="flex flex-col gap-y-4">
|
||||
<label htmlFor="devices" className="w-fit btnl font-medium">
|
||||
Выберите категории
|
||||
</label>
|
||||
@@ -116,6 +118,10 @@ export function ArticleFormModal<TAction extends "create" | "edit">({
|
||||
name="posterImage"
|
||||
label="Загрузите или перетащите изображение для превью (рекомендованнный размер 1080/1080 px)"
|
||||
/>
|
||||
<LocaleSwitch
|
||||
value={locale || "ru"}
|
||||
onChange={(newLocale) => setValue("locale", newLocale)}
|
||||
/>
|
||||
</FormProvider>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -16,6 +16,7 @@ export function ArticleCard({
|
||||
posterImage,
|
||||
createdAt,
|
||||
slug,
|
||||
locale,
|
||||
className,
|
||||
}: IArticle & { className?: string }) {
|
||||
const params = useSearchParams();
|
||||
@@ -58,6 +59,7 @@ export function ArticleCard({
|
||||
drafted,
|
||||
posterImage,
|
||||
createdAt,
|
||||
locale,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
+13
-13
@@ -4,7 +4,8 @@ import { queryOptions, useQuery } from '@tanstack/react-query';
|
||||
|
||||
export const queryArticlesOptions = {
|
||||
queryKey: ['articles'],
|
||||
queryFn: () => api.get('articles').json<IArticle[]>(),
|
||||
queryFn: () =>
|
||||
api.get('articles', { searchParams: { locale: "ru" } }).json<IArticle[]>(),
|
||||
};
|
||||
|
||||
export function useGetArticlesQuery(tags?: string | string[]) {
|
||||
@@ -12,18 +13,17 @@ export function useGetArticlesQuery(tags?: string | string[]) {
|
||||
queryOptions(
|
||||
tags && tags.length > 0
|
||||
? {
|
||||
queryKey: ['articles', tags],
|
||||
queryFn: () =>
|
||||
api
|
||||
.get(
|
||||
`articles?${
|
||||
Array.isArray(tags)
|
||||
? tags.map((tag) => `tags=${tag}`).join('&')
|
||||
: 'tags=' + tags
|
||||
}`
|
||||
)
|
||||
.json<IArticle[]>(),
|
||||
}
|
||||
queryKey: ['articles', tags],
|
||||
queryFn: () =>
|
||||
api
|
||||
.get(
|
||||
`articles?${Array.isArray(tags)
|
||||
? tags.map((tag) => `tags=${tag}`).join('&')
|
||||
: 'tags=' + tags
|
||||
}&locale=ru`
|
||||
)
|
||||
.json<IArticle[]>(),
|
||||
}
|
||||
: queryArticlesOptions
|
||||
)
|
||||
);
|
||||
|
||||
@@ -44,4 +44,5 @@ export interface IArticle {
|
||||
drafted: boolean;
|
||||
slug?: string;
|
||||
blocks: Block[];
|
||||
locale: 'ru' | 'en';
|
||||
}
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
import { motion } from "framer-motion";
|
||||
|
||||
interface LocaleSwitchProps {
|
||||
value: "ru" | "en";
|
||||
onChange: (locale: "ru" | "en") => void;
|
||||
}
|
||||
|
||||
export function LocaleSwitch({ value, onChange }: LocaleSwitchProps) {
|
||||
const handleToggle = () => {
|
||||
onChange(value === "ru" ? "en" : "ru");
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex flex-col gap-2">
|
||||
<label className="text1 font-medium text-white">Язык статьи</label>
|
||||
<div
|
||||
className={`
|
||||
bg-[#37393B99] relative lg:rounded-[0.833vw] rounded-xl
|
||||
w-[8.333vw] aspect-[12/5] cursor-pointer select-none
|
||||
transition-opacity duration-200
|
||||
`}
|
||||
onClick={handleToggle}
|
||||
>
|
||||
<motion.div
|
||||
className="absolute bg-gradient lg:rounded-[0.556vw] rounded-lg lg:p-[0.556vw] p-2 lg:w-[calc(50%-0.278vw)] w-[calc(50%-4px)] flex items-center justify-center left-[0.278vw] top-1/2"
|
||||
animate={{
|
||||
x: value === "ru" ? 0 : "100%",
|
||||
y: "-50%",
|
||||
}}
|
||||
transition={{
|
||||
type: "spring",
|
||||
stiffness: 400,
|
||||
damping: 35,
|
||||
}}
|
||||
>
|
||||
<span className="text1 font-medium text-center text-white">
|
||||
{value === "ru" ? "RU" : "EN"}
|
||||
</span>
|
||||
</motion.div>
|
||||
|
||||
<div className="flex absolute inset-0">
|
||||
<div className="flex flex-1 justify-center items-center">
|
||||
<span
|
||||
className={`text1 font-medium transition-colors duration-200 ${
|
||||
value === "ru" ? "text-transparent" : "text-gray-400"
|
||||
}`}
|
||||
>
|
||||
RU
|
||||
</span>
|
||||
</div>
|
||||
<div className="flex flex-1 justify-center items-center">
|
||||
<span
|
||||
className={`text1 font-medium transition-colors duration-200 ${
|
||||
value === "en" ? "text-transparent" : "text-gray-400"
|
||||
}`}
|
||||
>
|
||||
EN
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user