diff --git a/astro.config.mjs b/astro.config.mjs index 4a936da..b369cb6 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -17,6 +17,7 @@ const createAnchorLabel = (heading) => { export default defineConfig({ site: "https://yarkov.tech", integrations: [solid(), image(), mdx()], + trailingSlash: "always", markdown: { syntaxHighlight: "prism", remarkPlugins: ["remark-gfm", "remark-smartypants"], diff --git a/src/components/ArticleItem/ArticleItem.tsx b/src/components/ArticleItem/ArticleItem.tsx index f0617c5..9fd136d 100644 --- a/src/components/ArticleItem/ArticleItem.tsx +++ b/src/components/ArticleItem/ArticleItem.tsx @@ -1,15 +1,18 @@ import type { Component } from "solid-js"; -import { DateFormatter } from "@utils/date"; +import { createDateFormatter } from "@utils/date"; import "./ArticleItem.scss"; export type ArticleItemProps = { data: ArticleType; + lang: string; }; export const ArticleItem: Component = (props) => { + // eslint-disable-next-line solid/reactivity + const DateFormatter = createDateFormatter(props.lang); return (
- +

{props.data.title}

diff --git a/src/components/ArticlePost/ArticlePost.astro b/src/components/ArticlePost/ArticlePost.astro index cd9bb73..6e5d083 100644 --- a/src/components/ArticlePost/ArticlePost.astro +++ b/src/components/ArticlePost/ArticlePost.astro @@ -1,5 +1,5 @@ --- -import { DateFormatter } from "@root/utils"; +import { createDateFormatter, getLanguageFromURL } from "@root/utils"; import { Image } from "@astrojs/image/components"; import "./ArticlePost.scss"; @@ -9,6 +9,10 @@ export type Props = { const { data } = Astro.props as Props; const { title, tags, author, published_at } = data; +// const lang = getLanguageFromURL(Astro.url.pathname); +// console.log(lang); + +const DateFormatter = createDateFormatter("ru"); ---

@@ -18,7 +22,7 @@ const { title, tags, author, published_at } = data; { tags.map((tag) => (
  • - {`${tag}${tags.at(-1) === tag ? "" : ","}`} + {`${tag}${tags.at(-1) === tag ? "" : ","}`}
  • )) } diff --git a/src/components/ArticlesList/ArticlesList.tsx b/src/components/ArticlesList/ArticlesList.tsx index 44b79f9..5c9a255 100644 --- a/src/components/ArticlesList/ArticlesList.tsx +++ b/src/components/ArticlesList/ArticlesList.tsx @@ -8,12 +8,18 @@ import SearchInput from "@components/SearchInput"; import TagsList from "@components/TagsList"; import "./ArticlesList.scss"; +type UiStringsType = { + "input.search": string; + "articles.empty": string; +}; + type ArticlesListProps = { data: { articles: ArticleBlockType; tags: string[]; }; - emptyPlaceholder?: string | undefined; + lang: string; + i18n: UiStringsType; }; const ArticlesList: Component = (props) => { @@ -64,12 +70,12 @@ const ArticlesList: Component = (props) => { return ( <> - +
    {isEmpty() ? (
    -

    {props.emptyPlaceholder || "No articles found..."}

    +

    {props.i18n["articles.empty"]}

    ) : ( = (props) => { return (

    {year}

    - } /> + } />
    ); }} diff --git a/src/components/BaseHead.astro b/src/components/BaseHead.astro index 8a0ec9b..a60d777 100644 --- a/src/components/BaseHead.astro +++ b/src/components/BaseHead.astro @@ -1,11 +1,13 @@ --- import { SITE_METADATA } from "@root/config"; +import { useTranslation } from "@i18n/utils"; export interface Props { title?: string | undefined; description?: string | undefined; } +const t = useTranslation(Astro); const { title = SITE_METADATA.title, description } = Astro.props as Props; --- @@ -18,7 +20,7 @@ const { title = SITE_METADATA.title, description } = Astro.props as Props; {title} - + diff --git a/src/components/ContactForm/ContactForm.tsx b/src/components/ContactForm/ContactForm.tsx index 0fb9cca..478a6ab 100644 --- a/src/components/ContactForm/ContactForm.tsx +++ b/src/components/ContactForm/ContactForm.tsx @@ -3,22 +3,35 @@ import type { Component, JSX } from "solid-js"; import { createSignal } from "solid-js"; import { createStore } from "solid-js/store"; import { useForm } from "@hooks/index"; -import { encode } from "@root/utils/url"; +import { encode } from "@utils/url"; import Button from "@components/Button"; -import { validateEmail } from "./validations"; +import validations from "./validations"; import Submitted from "./Submitted"; import Error from "./Error"; import "./ContactForm.scss"; +type UiStringsType = { + "form.contactSuccess": string; + "form.contactError": string; + "input.nameField": string; + "input.subjectField": string; + "input.messageField": string; + "btn.send": string; + "btn.sending": string; + "error.invalidEmail": string; +}; + const ErrorMessage: Component<{ message: string }> = (props) => {props.message}; -const ContactForm: Component = () => { +const ContactForm: Component<{ i18n: UiStringsType }> = (props) => { const { formSubmit, validate, errors } = useForm({ errorClass: "error-input" }); const [isSubmitted, setIsSubmitted] = createSignal(false); const [isLoading, setIsLoading] = createSignal(false); const [isError, setIsError] = createSignal(false); const [state, setState] = createStore({ name: "", email: "", subject: "", message: "", "bot-field": "" }); + const { validateEmail } = validations; + const reset = (form: HTMLFormElement) => { for (const key in state) { form.elements[key].value = ""; @@ -63,13 +76,22 @@ const ContactForm: Component = () => {
    - + {errors.name && }
    { onInput={onChange} use:validate name="subject" - placeholder="Тема сообщения" + placeholder={props.i18n["input.subjectField"]} type="text" autocomplete="off" required @@ -94,7 +116,7 @@ const ContactForm: Component = () => { onInput={onChange} use:validate name="message" - placeholder="Ваше сообщение..." + placeholder={props.i18n["input.messageField"]} id="message" autocomplete="off" cols={30} @@ -104,12 +126,12 @@ const ContactForm: Component = () => { {errors.message && } ); diff --git a/src/components/ContactForm/Error.tsx b/src/components/ContactForm/Error.tsx index 0836ef3..a8976aa 100644 --- a/src/components/ContactForm/Error.tsx +++ b/src/components/ContactForm/Error.tsx @@ -1,7 +1,7 @@ import type { Component } from "solid-js"; -const Submitted: Component = () => { - return
    ❌ При отправке произошла ошибка. Повторите запрос позже.
    ; +const Submitted: Component<{ text: string }> = (props) => { + return
    ❌ {props.text}
    ; }; export default Submitted; diff --git a/src/components/ContactForm/Submitted.tsx b/src/components/ContactForm/Submitted.tsx index e06d187..980f305 100644 --- a/src/components/ContactForm/Submitted.tsx +++ b/src/components/ContactForm/Submitted.tsx @@ -1,7 +1,7 @@ import type { Component } from "solid-js"; -const Submitted: Component = () => { - return
    ✔️ Сообщение было успешно отправлено!
    ; +const Submitted: Component<{ text: string }> = (props) => { + return
    ✔️ {props.text}
    ; }; export default Submitted; diff --git a/src/components/ContactForm/validations.ts b/src/components/ContactForm/validations.ts index 5493763..9e9e195 100644 --- a/src/components/ContactForm/validations.ts +++ b/src/components/ContactForm/validations.ts @@ -1,3 +1,7 @@ import { isEmail } from "@utils/string"; -export const validateEmail = (field: HTMLInputElement) => (isEmail(field.value) ? false : "Заполните поле в формате e-mail."); +export default { + validateEmail: (error: string) => { + return (field: HTMLInputElement) => (isEmail(field.value) ? false : error); + }, +}; diff --git a/src/components/Header/Header.astro b/src/components/Header/Header.astro index e3ec58b..d11d738 100644 --- a/src/components/Header/Header.astro +++ b/src/components/Header/Header.astro @@ -2,9 +2,10 @@ import { Icon } from "astro-icon"; import { SITE_METADATA } from "@root/config"; import ThemeSwitcher from "@components/ThemeSwticher"; -import { removeSlashes } from "@utils/string"; +import UIString from "@components/UIString"; import NavToggle from "./NavToggle"; import "./Header.scss"; +import TranslatedLink from "@components/TranslatedLink"; const { name, nav, contacts } = SITE_METADATA; const { pathname } = Astro.url; @@ -13,23 +14,25 @@ const { pathname } = Astro.url;
    diff --git a/src/components/Header/Header.scss b/src/components/Header/Header.scss index 03221ea..ee890a0 100644 --- a/src/components/Header/Header.scss +++ b/src/components/Header/Header.scss @@ -3,8 +3,8 @@ top: 0; border-bottom: 1px solid var(--border-color); background-color: var(--background-header-color); - padding-top: 15px; - padding-bottom: 15px; + padding-top: 13.5px; + padding-bottom: 13.5px; user-select: none; z-index: 9999; & .container { @@ -53,7 +53,7 @@ display: flex; align-items: center; column-gap: 10px; - margin-right: 40px; + margin-right: 30px; & a { text-decoration: none; font-size: 0; @@ -62,6 +62,9 @@ } } } + &-settings { + column-gap: 13.5px; + } } } diff --git a/src/components/ProjectItem/ProjectItem.astro b/src/components/ProjectItem/ProjectItem.astro index 415ac81..02773e0 100644 --- a/src/components/ProjectItem/ProjectItem.astro +++ b/src/components/ProjectItem/ProjectItem.astro @@ -1,12 +1,16 @@ --- -import { Icon } from 'astro-icon'; -import './ProjectItem.scss'; +import { FALLBACK_LANGUAGE } from "@root/config"; +import { getLanguageFromURL } from "@root/utils"; +import { Icon } from "astro-icon"; +import UIString from "../UIString"; +import "./ProjectItem.scss"; export interface Props { data: ProjectType; } const { data } = Astro.props as Props; +const lang = getLanguageFromURL(Astro.url.pathname); const { icon, name, year, description, articleUrl, sourceUrl, demoUrl } = data; --- @@ -19,25 +23,31 @@ const { icon, name, year, description, articleUrl, sourceUrl, demoUrl } = data; {year}
    -

    {description}

    +

    {description[lang] || description[FALLBACK_LANGUAGE]}

    diff --git a/src/components/RecentArticles/EmptyList.astro b/src/components/RecentArticles/EmptyList.astro index fa3f0c1..dc4459e 100644 --- a/src/components/RecentArticles/EmptyList.astro +++ b/src/components/RecentArticles/EmptyList.astro @@ -1,5 +1,9 @@ +--- +import UIString from "@components/UIString"; +--- +
    -

    Пока что здесь ничего нет...

    +