Implement footer, redesign other sections

This commit is contained in:
2026-03-15 14:42:00 +03:00
Unverified
parent 0b81f7b947
commit 40968e9368
5 changed files with 302 additions and 171 deletions
+105 -35
View File
@@ -1,21 +1,27 @@
import { useNavigate } from "react-router-dom";
import { Link, useNavigate } from "react-router-dom";
import { useUserStore } from "@/state/user";
import styles from "./home.module.scss";
import useDownloadAppScreen from "@/core/hooks/useDownloadAppScreen";
import { MaterialButton, MaterialIcon } from "@/utils/material";
import generalChatScreenshot from "../../images/screenshots/general-chat.png";
import dmScreenshot from "../../images/screenshots/dm.png";
import telegramIcon from "../../images/telegram.svg";
import maxIcon from "../../images/max.svg";
import type { ReactNode } from "react";
function GitHubLink({ children }: { children: React.ReactNode }) {
const GITHUB_WEB = "https://github.com/fromchat-messenger/web";
const GITHUB_APP = "https://github.com/fromchat-messenger/app";
const GITHUB_LICENSE = `${GITHUB_WEB}/blob/main/LICENSE`;
function GitHubLink({ children, className }: { children: React.ReactNode; className?: string }) {
return (
<a href="https://github.com/denis0001-dev/FromChat" target="_blank">{children}</a>
<a href={`${GITHUB_WEB}/tree/main`} target="_blank" rel="noopener noreferrer" className={className}>{children}</a>
);
}
function SupportLink({ children }: { children: React.ReactNode }) {
function SupportLink({ children, className }: { children: React.ReactNode; className?: string }) {
return (
<a href="https://t.me/denis0001-dev" target="_blank">{children}</a>
<a href="https://t.me/denis0001-dev" target="_blank" rel="noopener noreferrer" className={className}>{children}</a>
);
}
@@ -99,7 +105,9 @@ export default function HomePage() {
<section className={styles.title}>
<div className={styles.titleLogo} />
<div className={styles.titleContent}>FromChat</div>
<div className={styles.titleDesc}>100% бесплатный и открытый мессенджер. Поддерживает self-hosted установку на своем сервере.</div>
<div className={styles.titleDesc}>
100% бесплатный и открытый мессенджер. Поддерживает self-hosted установку на своём сервере.
</div>
<div className={styles.titleButtons}>
<MaterialButton variant="filled" onClick={() => navigate("/auth?mode=login")} icon="devices">Открыть веб-версию</MaterialButton>
<MaterialButton variant="outlined" onClick={() => navigate("/download-app")} icon="download">Скачать приложение</MaterialButton>
@@ -112,12 +120,12 @@ export default function HomePage() {
screenshot={generalChatScreenshot}
right
>
Общайтесь со всеми пользователями этого сервера FromChat.
Открытый форум для всех пользователей сервера. Пишите сообщения, делитесь файлами и общайтесь в реальном времени.
</FeatureSection>
<FeatureSection
title={<>Личные сообщения</>}
screenshot={dmScreenshot}>
Общайтесь с одним человеком.
Общайтесь с одним человеком в личной переписке.
</FeatureSection>
</section>
@@ -126,31 +134,65 @@ export default function HomePage() {
<div className={styles.downloadContent}>
<h3>Скачайте приложение</h3>
<p>
Для лучшего опыта используйте настольное приложение с поддержкой
уведомлений и автономной работы.
Для лучшего опыта используйте настольное приложение с уведомлениями
и автономной работой или мобильное приложение для Android.
</p>
<div className={styles.downloadButtons}>
<div className={styles.downloadPlatforms}>
{!isMobile ? (
<>
<a
href="https://github.com/Toolbox-io/FromChat/actions/workflows/build.yml"
href={`${GITHUB_WEB}/actions/workflows/build.yml`}
target="_blank"
rel="noopener noreferrer"
className={styles.downloadCard}
>
<MaterialButton variant="filled">
<MaterialIcon name="computer" className={styles.downloadCardIcon} />
<span className={styles.downloadCardTitle}>Для ПК</span>
<span className={styles.downloadCardDesc}>Windows, macOS, Linux</span>
<MaterialButton variant="filled" className={styles.downloadCardBtn}>
<MaterialIcon name="download" slot="icon" />
Скачать для ПК
Скачать
</MaterialButton>
</a>
<MaterialButton variant="outlined" onClick={() => navigate("/login")}>
<MaterialIcon name="language" slot="icon" />
Веб-версия
</MaterialButton>
<a
href={`${GITHUB_APP}/releases/latest`}
target="_blank"
rel="noopener noreferrer"
className={styles.downloadCard}
>
<MaterialIcon name="android" className={styles.downloadCardIcon} />
<span className={styles.downloadCardTitle}>Android</span>
<span className={styles.downloadCardDesc}>APK на GitHub</span>
<MaterialButton variant="outlined" className={styles.downloadCardBtn}>
<MaterialIcon name="download" slot="icon" />
Скачать
</MaterialButton>
</a>
<div className={styles.downloadCard}>
<MaterialIcon name="language" className={styles.downloadCardIcon} />
<span className={styles.downloadCardTitle}>Веб-версия</span>
<span className={styles.downloadCardDesc}>Без установки</span>
<MaterialButton variant="outlined" className={styles.downloadCardBtn} onClick={() => navigate("/login")}>
<MaterialIcon name="open_in_new" slot="icon" />
Открыть
</MaterialButton>
</div>
</>
) : (
<MaterialButton variant="filled" onClick={() => navigate("/download-app")}>
Скачать приложение
</MaterialButton>
<a
href={`${GITHUB_APP}/releases/latest`}
target="_blank"
rel="noopener noreferrer"
className={styles.downloadCard}
>
<MaterialIcon name="android" className={styles.downloadCardIcon} />
<span className={styles.downloadCardTitle}>Android</span>
<span className={styles.downloadCardDesc}>Скачайте APK на GitHub</span>
<MaterialButton variant="filled" className={styles.downloadCardBtn}>
<MaterialIcon name="download" slot="icon" />
Скачать приложение
</MaterialButton>
</a>
)}
</div>
</div>
@@ -162,7 +204,8 @@ export default function HomePage() {
<div className={styles.ctaContent}>
<h3>Готовы начать общение?</h3>
<p>
Присоединяйтесь к FromChat и общайтесь безопасно с друзьями и коллегами.
Создайте аккаунт за минуту. Общайтесь в общем чате, ведите личную переписку
или звоните всё бесплатно и с открытым кодом.
</p>
<div className={styles.ctaActions}>
{isMobile ? (
@@ -190,20 +233,47 @@ export default function HomePage() {
</main>
<footer className={styles.homepageFooter}>
<div className={styles.container}>
<div className={styles.footerContent}>
<div className={styles.footerSection}>
<h4>Ссылки</h4>
<GitHubLink>GitHub</GitHubLink>
<SupportLink>Поддержка</SupportLink>
</div>
<div className={styles.footerSection}>
<h4>Лицензия</h4>
<p>GPL-3.0</p>
</div>
<div className={styles.footerBrand}>
<div className={styles.footerLogoRow}>
<div className={styles.footerLogo} />
<span className={styles.footerBrandName}>FromChat</span>
</div>
<div className={styles.footerBottom}>
<p>&copy; 2025 FromChat. Сделано программистом denis0001-dev с для свободы общения.</p>
<p className={styles.footerCopyright}>FromChat © 2025</p>
</div>
<div className={styles.footerLinks}>
<div className={styles.footerSection}>
<Link to="/download-app" className={styles.footerLink}>
<MaterialIcon name="download" className={styles.footerLinkIcon} />
Скачать приложение
</Link>
<Link to="/login" className={styles.footerLink}>
<MaterialIcon name="language" className={styles.footerLinkIcon} />
Веб-версия
</Link>
</div>
<div className={styles.footerSection}>
<a href={`${GITHUB_APP}/tree/main`} target="_blank" rel="noopener noreferrer" className={styles.footerLink}>
<MaterialIcon name="android" className={styles.footerLinkIcon} />
Исходный код приложения
</a>
<GitHubLink className={styles.footerLink}>
<MaterialIcon name="code" className={styles.footerLinkIcon} />
Исходный код веб-версии
</GitHubLink>
<a href={GITHUB_LICENSE} target="_blank" rel="noopener noreferrer" className={styles.footerLink}>
<MaterialIcon name="description" className={styles.footerLinkIcon} />
Лицензия
</a>
</div>
<div className={styles.footerSection}>
<a href="https://t.me/fromchat_ch" target="_blank" rel="noopener noreferrer" className={styles.footerLink}>
<span className={`${styles.footerLinkIcon} ${styles.footerLinkIconSvg}`} style={{ maskImage: `url(${telegramIcon})`, WebkitMaskImage: `url(${telegramIcon})` }} />
Telegram
</a>
<a href="https://max.ru/join/c5t6LfnCCPetQSAOshmouEvq9vsjHZT_Lt63kw8YCg0" target="_blank" rel="noopener noreferrer" className={styles.footerLink}>
<span className={`${styles.footerLinkIcon} ${styles.footerLinkIconSvg}`} style={{ maskImage: `url(${maxIcon})`, WebkitMaskImage: `url(${maxIcon})` }} />
MAX
</a>
</div>
</div>
</footer>