Mise à jour

This commit is contained in:
Rampeur
2025-08-11 01:14:50 +02:00
parent e1e703c2d8
commit 917b90a26d
43 changed files with 1415 additions and 1241 deletions
+2
View File
@@ -0,0 +1,2 @@
APP_ENV="development"
API_BASE_URL=http://localhost:3200
+2
View File
@@ -0,0 +1,2 @@
APP_ENV="production"
API_BASE_URL=http://api.adastra-cbd.com/api
+2 -1
View File
@@ -1 +1,2 @@
API_BASE_URL=http://localhost/api APP_ENV="development"
API_BASE_URL=http://localhost:3200/api
+2 -2
View File
@@ -1,3 +1,3 @@
npm test npm test
prettier $(git diff --cached --name-only --diff-filter=ACMR | sed 's| |\\ |g') --write --ignore-unknown #prettier $(git diff --cached --name-only --diff-filter=ACMR | sed 's| |\\ |g') --write --ignore-unknown
git update-index --again #git update-index --again
+1 -1
View File
@@ -106,7 +106,7 @@ const TimeClock: React.FC = () => {
<> <>
<div className="date d-flex mb-2 pt-2"> <div className="date d-flex mb-2 pt-2">
<div className="flex-grow-1"></div> <div className="flex-grow-1"></div>
<div className="datelib mt-2 pt-1 ps-1 font-monospace opacity-50 fs-5"> <div className="datelib mt-2 pt-1 ps-1 font-monospace fs-5">
<span className="icon-calendar me-2" aria-hidden="true"></span> <span className="icon-calendar me-2" aria-hidden="true"></span>
<span id="datelib"></span> <span id="datelib"></span>
</div> </div>
@@ -1,3 +1,4 @@
import { Container, Col, Row } from "react-bootstrap";
import { Button } from "@/modules/common/components/button"; import { Button } from "@/modules/common/components/button";
import { DeleteArticleButton } from "@/modules/features/article/components/deleteArticleButton"; import { DeleteArticleButton } from "@/modules/features/article/components/deleteArticleButton";
import { FavoriteButton } from "@/modules/features/article/components/favoriteButton"; import { FavoriteButton } from "@/modules/features/article/components/favoriteButton";
@@ -48,33 +49,32 @@ export const ArticleArea = async ({ slug, children }: { slug: string; children:
const currentUser = (await getSession()) ? await fetchCurrentUser() : undefined; const currentUser = (await getSession()) ? await fetchCurrentUser() : undefined;
return ( return (
<div className="article-page"> <section className="article-page">
<div className="banner"> <Container className="banner">
<div className="container">
<h1>{article.title}</h1> <h1>{article.title}</h1>
<Actions article={article} currentUser={currentUser} /> <Actions article={article} currentUser={currentUser} />
</div> </Container>
</div> <Container className="page">
<Row className="article-content">
<div className="container page"> <Col xs={12}>
<div className="row article-content">
<div className="col-md-12">
<div dangerouslySetInnerHTML={{ __html: body }} /> <div dangerouslySetInnerHTML={{ __html: body }} />
<ul className="tag-list"> <ul className="list-unstyled list-inline">
{article.tagList.map((tag, index) => ( {article.tagList.map((tag, index) => (
<Tag component="li" variant="outline" key={index}> <li className="list-inline-item me-2" key={index}>
<Tag component="badge" color="success">
{tag} {tag}
</Tag> </Tag>
</li>
))} ))}
</ul> </ul>
</div> </Col>
</div> </Row>
<hr /> <hr />
<div className="article-actions"> <div className="article-actions">
<Actions article={article} currentUser={currentUser} /> <Actions article={article} currentUser={currentUser} />
</div> </div>
{children} {children}
</div> </Container>
</div> </section>
); );
}; };
@@ -1,3 +1,4 @@
import { Button, Form } from "react-bootstrap";
import Link from "next/link"; import Link from "next/link";
import Image from "next/image"; import Image from "next/image";
import { Comment } from "@/utils/types/models"; import { Comment } from "@/utils/types/models";
@@ -26,11 +27,11 @@ export const CommentCard = ({ comment, showDeleteCommentButton, deleteCommentAct
</Link> </Link>
<span className="date-posted">{comment.createdAt.toDateString()}</span> <span className="date-posted">{comment.createdAt.toDateString()}</span>
{showDeleteCommentButton && ( {showDeleteCommentButton && (
<form action={deleteCommentAction} className={styles["form"]}> <Form action={deleteCommentAction} className={styles["form"]}>
<button className="mod-options" type="submit"> <Button className="mod-options" variant="primary" type="submit">
<i className="ion-trash-a" /> <i className="icon-trash" />
</button> </Button>
</form> </Form>
)} )}
</div> </div>
</div> </div>
@@ -1,5 +1,5 @@
import { Button, Form } from "react-bootstrap";
import Image from "next/image"; import Image from "next/image";
import { Button } from "@/modules/common/components/button";
import { ErrorMessage } from "@/modules/common/components/errorMessage"; import { ErrorMessage } from "@/modules/common/components/errorMessage";
import { SubmissionResult, useForm } from "@conform-to/react"; import { SubmissionResult, useForm } from "@conform-to/react";
import { parseWithZod } from "@conform-to/zod"; import { parseWithZod } from "@conform-to/zod";
@@ -38,8 +38,13 @@ export const CommentForm = ({ slug, authorImage, result, postCommentAction, isPe
return ( return (
<> <>
<form id={form.id} action={postCommentAction} onSubmit={form.onSubmit} className="card comment-form"> <Form className="card comment-form" id={form.id} action={postCommentAction} onSubmit={form.onSubmit} noValidate={true}>
<input type="hidden" key={fields.slug.key} name={fields.slug.name} defaultValue={fields.slug.initialValue} /> <Form.Control
type="hidden"
key={fields.slug.key}
name={fields.slug.name}
defaultValue={fields.slug.initialValue}
/>
<div className="card-block"> <div className="card-block">
<textarea <textarea
key={fields.body.key} key={fields.body.key}
@@ -53,11 +58,11 @@ export const CommentForm = ({ slug, authorImage, result, postCommentAction, isPe
</div> </div>
<div className="card-footer"> <div className="card-footer">
{authorImage && <Image src={authorImage} alt="" className="comment-author-img" />} {authorImage && <Image src={authorImage} alt="" className="comment-author-img" />}
<Button component="button" type="submit" disabled={isPending}> <Button variant="primary" type="submit" disabled={isPending}>
Post Comment Post Comment
</Button> </Button>
</div> </div>
</form> </Form>
</> </>
); );
}; };
+6 -5
View File
@@ -1,6 +1,7 @@
import { Col, Row } from "react-bootstrap";
import { Suspense } from "react";
import { fetchCurrentUser } from "@/modules/features/auth/fetch/fetchCurrentUser"; import { fetchCurrentUser } from "@/modules/features/auth/fetch/fetchCurrentUser";
import { getSession } from "@/utils/auth/session"; import { getSession } from "@/utils/auth/session";
import { Suspense } from "react";
import { ArticleArea } from "./_components/articleArea"; import { ArticleArea } from "./_components/articleArea";
import { CommentForm } from "./_components/commentForm"; import { CommentForm } from "./_components/commentForm";
import { CommentList } from "./_components/commentList"; import { CommentList } from "./_components/commentList";
@@ -15,14 +16,14 @@ const Page = async (props: { params: Params }) => {
return ( return (
<ArticleArea slug={params.slug}> <ArticleArea slug={params.slug}>
<div className="row"> <Row>
<div className="col-xs-12 col-md-8 offset-md-2"> <Col xs={12} md={{ span: 8, offset: 2 }}>
<CommentForm slug={params.slug} currentUserPromise={currentUserPromise} /> <CommentForm slug={params.slug} currentUserPromise={currentUserPromise} />
<Suspense fallback={<p>Loading comments...</p>}> <Suspense fallback={<p>Loading comments...</p>}>
<CommentList slug={params.slug} /> <CommentList slug={params.slug} />
</Suspense> </Suspense>
</div> </Col>
</div> </Row>
</ArticleArea> </ArticleArea>
); );
}; };
+78
View File
@@ -0,0 +1,78 @@
import { Container, Col, Row } from "react-bootstrap";
import { getSession } from "@/utils/auth/session";
import { ExhaustiveError } from "@/utils/errors";
import clsx from "clsx";
import Link from "next/link";
import { Suspense } from "react";
import { FeedArticleList } from "../_components/feedArticleList";
import { GlobalArticleList } from "../_components/globalArticleList";
import { TagArticleList } from "../_components/tagArticleList";
import { TagList } from "../_components/tagList";
import { SearchParams } from "../_types";
//import { ArticlesList } from "./_components/articlesList";
const ArticleList = (searchParams: SearchParams) => {
switch (searchParams.tab) {
case "yours":
return <FeedArticleList currentPage={searchParams.page} />;
case "global":
return <GlobalArticleList currentPage={searchParams.page} />;
case "tag":
return <TagArticleList currentPage={searchParams.page} tag={searchParams.tag ?? ""} />;
default:
throw new ExhaustiveError(searchParams.tab, "all tab cases are not covered");
}
};
const Page = async (props: { searchParams: Promise<{ [key: string]: string | string[] | undefined }> }) => {
const session = await getSession();
const searchParams = SearchParams.parse(await props.searchParams);
return (
<section className="auth-page">
<Container className="page">
<hr className="col-1 my-5 mx-0" />
<Row>
<Col md={9}>
<div className="feed-toggle">
<ul className="nav nav-pills outline-active">
{session && (
<li className="nav-item">
<Link className={clsx("nav-link", searchParams.tab === "yours" && "active")} href="/?tab=yours">
Your Feed
</Link>
</li>
)}
<li className="nav-item">
<Link className={clsx("nav-link", searchParams.tab === "global" && "active")} href="/?tab=global">
Global Feed
</Link>
</li>
{searchParams.tag && (
<li className="nav-item">
<Link
className={clsx("nav-link", searchParams.tab === "tag" && "active")}
href={`/?tab=tag&tag=${searchParams.tag}`}
>
#{searchParams.tag}
</Link>
</li>
)}
</ul>
</div>
<Suspense key={JSON.stringify(searchParams)} fallback={<p>Chargement...</p>}>
<ArticleList {...searchParams} />
</Suspense>
</Col>
<Col md={3}>
<Suspense fallback={<p>Chargement...</p>}>
<TagList />
</Suspense>
</Col>
</Row>
</Container>
</section>
);
};
export default Page;
+8 -7
View File
@@ -1,3 +1,4 @@
import { Container, Col, Row } from "react-bootstrap";
import { UpdateArticleEditor } from "@/modules/features/article/components/articleEditor"; import { UpdateArticleEditor } from "@/modules/features/article/components/articleEditor";
import { fetchArticle } from "@/modules/features/article/fetch/fetchArticle"; import { fetchArticle } from "@/modules/features/article/fetch/fetchArticle";
import { Suspense } from "react"; import { Suspense } from "react";
@@ -13,15 +14,15 @@ const Page = async ({ params }: Props) => {
return ( return (
<div className="editor-page"> <div className="editor-page">
<div className="container page"> <Container className="page">
<div className="row"> <Row>
<div className="col-md-10 offset-md-1 col-xs-12"> <Col xs={12} md={{ span: 10, offset: 1 }}>
<Suspense fallback={<p>Loading...</p>}> <Suspense fallback={<p> Chargement...</p>}>
<UpdateArticleEditor defaultValues={article} /> <UpdateArticleEditor defaultValues={article} />
</Suspense> </Suspense>
</div> </Col>
</div> </Row>
</div> </Container>
</div> </div>
); );
}; };
+9 -8
View File
@@ -1,15 +1,16 @@
import { Container, Col, Row } from "react-bootstrap";
import { CreateArticleEditor } from "@/modules/features/article/components/articleEditor"; import { CreateArticleEditor } from "@/modules/features/article/components/articleEditor";
const Page = () => ( const Page = () => (
<div className="editor-page"> <section className="editor-page">
<div className="container page"> <Container className="page">
<div className="row"> <Row>
<div className="col-md-10 offset-md-1 col-xs-12"> <Col xs={12} md={{ span: 10, offset: 1 }}>
<CreateArticleEditor /> <CreateArticleEditor />
</div> </Col>
</div> </Row>
</div> </Container>
</div> </section>
); );
export default Page; export default Page;
+19 -7
View File
@@ -1,6 +1,8 @@
"use client"; "use client";
import { Button } from "@/modules/common/components/button"; //import { Button } from "@/modules/common/components/button";
import { Container, Button, Col, Row } from "react-bootstrap";
import TimeClock from "./_components/timeClock/timeClock";
const Error = ({ const Error = ({
reset, reset,
@@ -11,14 +13,24 @@ const Error = ({
reset: () => void; reset: () => void;
}) => { }) => {
return ( return (
<div className="error-page"> <section className="error-page">
<div className="container page"> <Container className="banner">
<p className="error-message">Something went wrong!</p> <Row>
<Button component="button" size="lg" onClick={() => reset()}> <Col sm={6} md={7} lg={8}>
<h1 className="mt-4"> Une erreur est survenue!</h1>
<p className="fs-4">La page que vous vouliez consulter n&apos;est pas d&apos;isponible pour le moment.</p>
</Col>
<Col sm={6} md={5} lg={4}>
<TimeClock />
</Col>
</Row>
</Container>
<Container className="page">
<Button type="button" onClick={() => reset()}>
Try again Try again
</Button> </Button>
</div> </Container>
</div> </section>
); );
}; };
+3 -3
View File
@@ -58,11 +58,11 @@ const RootLayout = ({
}>) => { }>) => {
return ( return (
<html className="h-100" lang="en"> <html className="h-100" lang="en">
<body className="d-flex flex-column h-100" data-bs-theme="dark"> <body className="d-flex flex-column h-100" data-bs-theme="light">
<Header /> <Header />
<div className="h-100"> <main className="h-100">
{children} {children}
</div> </main>
<Footer /> <Footer />
</body> </body>
</html> </html>
+9 -8
View File
@@ -1,19 +1,20 @@
import { Container, Col, Row } from "react-bootstrap";
import Link from "next/link"; import Link from "next/link";
import { LoginForm } from "./_components/loginForm"; import { LoginForm } from "./_components/loginForm";
const Page = () => ( const Page = () => (
<div className="auth-page"> <section className="auth-page">
<div className="container page"> <Container className="page">
<div className="row"> <Row>
<div className="col-md-6 offset-md-3 col-xs-12"> <Col xs={12} md={{ span: 6, offset: 3 }}>
<h1 className="text-xs-center">Se connecter</h1> <h1 className="text-xs-center">Se connecter</h1>
<p className="text-xs-center"> <p className="text-xs-center">
<Link href="/register">Pas encore de compte?</Link> <Link href="/register">Pas encore de compte?</Link>
</p> </p>
<LoginForm /> <LoginForm />
</div> </Col>
</div> </Row>
</div> </Container>
</div> </section>
); );
export default Page; export default Page;
+7 -5
View File
@@ -1,10 +1,12 @@
import { Container, Button } from "react-bootstrap";
const NotFound = () => { const NotFound = () => {
return ( return (
<div className="not-found-page"> <section className="not-found-page">
<div className="container page"> <Container className="page">
<p className="error-message">This page could not be found.</p> <p className="error-message"> Cette page n&apos;existe pas.</p>
</div> </Container>
</div> </section>
); );
}; };
+1 -67
View File
@@ -1,35 +1,10 @@
import { getSession } from "@/utils/auth/session";
import { ExhaustiveError } from "@/utils/errors";
import clsx from "clsx";
import Link from "next/link";
import { Suspense } from "react";
import { Container, Col, Row } from "react-bootstrap"; import { Container, Col, Row } from "react-bootstrap";
import { FeedArticleList } from "./_components/feedArticleList";
import { GlobalArticleList } from "./_components/globalArticleList";
import { TagArticleList } from "./_components/tagArticleList";
import { TagList } from "./_components/tagList";
import { SearchParams } from "./_types";
import TimeClock from "./_components/timeClock/timeClock"; import TimeClock from "./_components/timeClock/timeClock";
const ArticleList = (searchParams: SearchParams) => {
switch (searchParams.tab) {
case "yours":
return <FeedArticleList currentPage={searchParams.page} />;
case "global":
return <GlobalArticleList currentPage={searchParams.page} />;
case "tag":
return <TagArticleList currentPage={searchParams.page} tag={searchParams.tag ?? ""} />;
default:
throw new ExhaustiveError(searchParams.tab, "all tab cases are not covered");
}
};
const Page = async (props: { searchParams: Promise<{ [key: string]: string | string[] | undefined }> }) => { const Page = async (props: { searchParams: Promise<{ [key: string]: string | string[] | undefined }> }) => {
const session = await getSession();
const searchParams = SearchParams.parse(await props.searchParams);
return ( return (
<div className="home-page h-100"> <div className="home-page">
<Container className="banner"> <Container className="banner">
<Row> <Row>
<Col sm={6} md={7} lg={8}> <Col sm={6} md={7} lg={8}>
@@ -41,47 +16,6 @@ const Page = async (props: { searchParams: Promise<{ [key: string]: string | str
</Col> </Col>
</Row> </Row>
</Container> </Container>
<Container className="page">
<hr className="col-1 my-5 mx-0" />
<Row>
<Col md={9}>
<div className="feed-toggle">
<ul className="nav nav-pills outline-active">
{session && (
<li className="nav-item">
<Link className={clsx("nav-link", searchParams.tab === "yours" && "active")} href="/?tab=yours">
Your Feed
</Link>
</li>
)}
<li className="nav-item">
<Link className={clsx("nav-link", searchParams.tab === "global" && "active")} href="/?tab=global">
Global Feed
</Link>
</li>
{searchParams.tag && (
<li className="nav-item">
<Link
className={clsx("nav-link", searchParams.tab === "tag" && "active")}
href={`/?tab=tag&tag=${searchParams.tag}`}
>
#{searchParams.tag}
</Link>
</li>
)}
</ul>
</div>
<Suspense key={JSON.stringify(searchParams)} fallback={<p>Chargement...</p>}>
<ArticleList {...searchParams} />
</Suspense>
</Col>
<Col md={3}>
<Suspense fallback={<p>Chargement...</p>}>
<TagList />
</Suspense>
</Col>
</Row>
</Container>
</div> </div>
); );
}; };
@@ -35,24 +35,24 @@ export const RegistrationForm = ({ result, action, isPending }: Props) => {
<ErrorMessage messages={form.errors} /> <ErrorMessage messages={form.errors} />
<Form id={form.id} action={action} onSubmit={form.onSubmit} noValidate={true}> <Form id={form.id} action={action} onSubmit={form.onSubmit} noValidate={true}>
<Form.Group className="mb-3" controlId="formFirstname"> <Form.Group className="mb-3" controlId="formFirstname">
<Form.Label>Nom</Form.Label> <Form.Label>Prénom</Form.Label>
<Form.Control <Form.Control
type="text" type="text"
key={fields.lastname.key} key={fields.lastname.key}
name={fields.lastname.name} name={fields.lastname.name}
defaultValue={fields.lastname.initialValue} defaultValue={fields.lastname.initialValue}
placeholder="Votre nom" placeholder="Votre prénom"
/> />
<ErrorMessage messages={fields.firstname.errors} /> <ErrorMessage messages={fields.firstname.errors} />
</Form.Group> </Form.Group>
<Form.Group className="mb-3" controlId="formLastname"> <Form.Group className="mb-3" controlId="formLastname">
<Form.Label>Prénom</Form.Label> <Form.Label>Nom</Form.Label>
<Form.Control <Form.Control
type="text" type="text"
key={fields.firstname.key} key={fields.firstname.key}
name={fields.firstname.name} name={fields.firstname.name}
defaultValue={fields.firstname.initialValue} defaultValue={fields.firstname.initialValue}
placeholder="Votre prénom" placeholder="Votre nom"
/> />
<ErrorMessage messages={fields.lastname.errors} /> <ErrorMessage messages={fields.lastname.errors} />
</Form.Group> </Form.Group>
+10 -9
View File
@@ -1,20 +1,21 @@
import { Container, Col, Row } from "react-bootstrap";
import Link from "next/link"; import Link from "next/link";
import { RegistrationForm } from "./_components/registrationForm"; import { RegistrationForm } from "./_components/registrationForm";
const Page = () => ( const Page = () => (
<div className="auth-page"> <section className="auth-page">
<div className="container page"> <Container className="page">
<div className="row"> <Row>
<div className="col-md-6 offset-md-3 col-xs-12"> <Col xs={12} md={{ span: 6, offset: 3 }}>
<h1 className="text-xs-center">Se connecter</h1> <h1 className="text-xs-center">Créer un compte</h1>
<p className="text-xs-center"> <p className="text-xs-center">
<Link href="/login">Déjà un compte?</Link> <Link href="/login">Déjà un compte?</Link>
</p> </p>
<RegistrationForm /> <RegistrationForm />
</div> </Col>
</div> </Row>
</div> </Container>
</div> </section>
); );
export default Page; export default Page;
+64 -52
View File
@@ -1,4 +1,4 @@
import { Button } from "@/modules/common/components/button"; import { Button, Form } from "react-bootstrap";
import { ErrorMessage } from "@/modules/common/components/errorMessage"; import { ErrorMessage } from "@/modules/common/components/errorMessage";
import { User } from "@/utils/types/models"; import { User } from "@/utils/types/models";
import { SubmissionResult, useForm } from "@conform-to/react"; import { SubmissionResult, useForm } from "@conform-to/react";
@@ -35,77 +35,89 @@ export const SettingsForm = ({ user, action, isPending, result }: Props) => {
return ( return (
<> <>
<ErrorMessage messages={form.errors} /> <ErrorMessage messages={form.errors} />
<form id={form.id} action={action} onSubmit={form.onSubmit} noValidate={true}> <Form id={form.id} action={action} onSubmit={form.onSubmit} noValidate={true}>
<fieldset> <Form.Group className="mb-3" controlId="formUsername">
<fieldset className="form-group"> <Form.Label>Pseudo</Form.Label>
<input <Form.Control
type="text"
key={fields.image.key}
name={fields.image.name}
defaultValue={fields.image.initialValue}
placeholder="URL of profile picture"
className="form-control"
/>
<ErrorMessage messages={fields.image.errors} />
</fieldset>
<fieldset className="form-group">
<input
type="text" type="text"
key={fields.username.key} key={fields.username.key}
name={fields.username.name} name={fields.username.name}
defaultValue={fields.username.initialValue} defaultValue={fields.username.initialValue}
placeholder="Your Name" placeholder="Votre pseudo"
className="form-control form-control-lg"
/> />
<ErrorMessage messages={fields.username.errors} /> <ErrorMessage messages={fields.username.errors} />
</fieldset> </Form.Group>
<fieldset className="form-group"> <Form.Group className="mb-3" controlId="formEmail">
<textarea <Form.Label>Adresse email</Form.Label>
key={fields.bio.key} <Form.Control
name={fields.bio.name}
defaultValue={fields.bio.initialValue}
placeholder="Short bio about you"
className="form-control form-control-lg"
rows={8}
></textarea>
<ErrorMessage messages={fields.bio.errors} />
</fieldset>
<fieldset className="form-group">
<input
type="email" type="email"
key={fields.email.key} key={fields.email.key}
name={fields.email.name} name={fields.email.name}
defaultValue={fields.email.initialValue} defaultValue={fields.email.initialValue}
placeholder="Email" placeholder="Votre adresse email"
className="form-control form-control-lg"
/> />
<ErrorMessage messages={fields.email.errors} /> <ErrorMessage messages={fields.email.errors} />
</fieldset> </Form.Group>
<fieldset className="form-group"> <Form.Group className="mb-3" controlId="formFirstname">
<input <Form.Label>Prénom</Form.Label>
<Form.Control
type="text"
key={fields.firstname.key}
name={fields.firstname.name}
defaultValue={fields.firstname.initialValue}
placeholder="Votre prénom"
/>
<ErrorMessage messages={fields.firstname.errors} />
</Form.Group>
<Form.Group className="mb-3" controlId="formLastname">
<Form.Label>Nom</Form.Label>
<Form.Control
type="text"
key={fields.lastname.key}
name={fields.lastname.name}
defaultValue={fields.lastname.initialValue}
placeholder="Votre nom"
/>
<ErrorMessage messages={fields.lastname.errors} />
</Form.Group>
<Form.Group className="mb-3" controlId="formPassword">
<Form.Label>Mot de passe</Form.Label>
<Form.Control
type="password" type="password"
key={fields.password.key} key={fields.password.key}
name={fields.password.name} name={fields.password.name}
defaultValue={fields.password.initialValue} defaultValue={fields.password.initialValue}
placeholder="New Password" placeholder="Nouveau mot de passe"
autoComplete="new-password" autoComplete="new-password"
className="form-control form-control-lg"
/> />
<ErrorMessage messages={fields.password.errors} /> <ErrorMessage messages={fields.password.errors} />
</fieldset> </Form.Group>
<Button <Form.Group className="mb-3" controlId="formBio">
component="button" <Form.Label>Bio</Form.Label>
size="lg" <Form.Control as="textarea" rows={8}
color="primary" key={fields.bio.key}
variant="filled" name={fields.bio.name}
type="submit" defaultValue={fields.bio.initialValue}
className="pull-xs-right" placeholder="Courte description"
disabled={isPending} />
> <ErrorMessage messages={fields.bio.errors} />
Update Settings </Form.Group>
<Form.Group className="mb-3" controlId="formImage">
<Form.Label>Image</Form.Label>
<Form.Control
type="text"
key={fields.image.key}
name={fields.image.name}
defaultValue={fields.image.initialValue}
/>
<ErrorMessage messages={fields.image.errors} />
</Form.Group>
<div className="d-flex justify-content-end">
<Button variant="primary" type="submit" disabled={isPending}>
Enregistrer
</Button> </Button>
</fieldset> </div>
</form> </Form>
</> </>
); );
}; };
+4 -2
View File
@@ -1,10 +1,12 @@
import { z } from "zod"; import { z } from "zod";
export const inputsSchema = z.object({ export const inputsSchema = z.object({
image: z.string().max(200).optional(),
username: z.string().max(200), username: z.string().max(200),
bio: z.string().max(200).optional(),
email: z.string().max(200).email(), email: z.string().max(200).email(),
firstname: z.string().max(200),
lastname: z.string().max(200),
bio: z.string().max(200).optional(),
image: z.string().max(200).optional(),
password: z.string().min(4).max(200).optional(), password: z.string().min(4).max(200).optional(),
}); });
+11 -10
View File
@@ -1,3 +1,4 @@
import { Container, Col, Row } from "react-bootstrap";
import { LogoutButton } from "@/modules/features/auth/components/logoutButton"; import { LogoutButton } from "@/modules/features/auth/components/logoutButton";
import { fetchCurrentUser } from "@/modules/features/auth/fetch/fetchCurrentUser"; import { fetchCurrentUser } from "@/modules/features/auth/fetch/fetchCurrentUser";
import { Suspense } from "react"; import { Suspense } from "react";
@@ -7,20 +8,20 @@ const Page = async () => {
const user = fetchCurrentUser(); const user = fetchCurrentUser();
return ( return (
<div className="settings-page"> <section className="settings-page">
<div className="container page"> <Container className="page">
<div className="row"> <Row>
<div className="col-md-6 offset-md-3 col-xs-12"> <Col xs={12} md={{ span: 6, offset: 3 }}>
<h1 className="text-xs-center">Your Settings</h1> <h1 className="text-xs-center">Vos paramètres</h1>
<Suspense fallback={<p>Loading...</p>}> <Suspense fallback={<p> Chargement...</p>}>
<SettingsForm user={user} /> <SettingsForm user={user} />
</Suspense> </Suspense>
<hr /> <hr />
<LogoutButton /> <LogoutButton />
</div> </Col>
</div> </Row>
</div> </Container>
</div> </section>
); );
}; };
@@ -15,24 +15,19 @@ const ExampleOffcanvas: React.FC<ExampleOffcanvasProps> = ({ className }) => {
return ( return (
<> <>
<Button onClick={() => setShow((s) => !s)} className={className}> <Button size="sm" onClick={() => setShow((s) => !s)} className={className}>
<span className="icon-cart me-2"></span>Mon panier <span className="icon-cart me-2"></span>Mon panier
</Button> </Button>
<Offcanvas placement="end" show={show} onHide={() => setShow(false)}> <Offcanvas placement="end" show={show} onHide={() => setShow(false)}>
<Offcanvas.Header closeButton> <Offcanvas.Header closeButton>
<Offcanvas.Title as="h5">Offcanvas</Offcanvas.Title> <Offcanvas.Title as="h5">Mon panier</Offcanvas.Title>
</Offcanvas.Header> </Offcanvas.Header>
<Offcanvas.Body> <Offcanvas.Body>
<div> <div>
Some text as placeholder. In real life you can have the elements you Some text as placeholder. In real life you can have the elements you
have chosen. Like, text, images, lists, etc. have chosen. Like, text, images, lists, etc.
</div> </div>
<DropdownButton variant="secondary" title="Dropdown button" className="mt-3">
<DropdownButton
variant="secondary"
title="Dropdown button"
className="mt-3"
>
<Dropdown.Item href="#">Action</Dropdown.Item> <Dropdown.Item href="#">Action</Dropdown.Item>
<Dropdown.Item href="#">Another action</Dropdown.Item> <Dropdown.Item href="#">Another action</Dropdown.Item>
<Dropdown.Item href="#">Something else here</Dropdown.Item> <Dropdown.Item href="#">Something else here</Dropdown.Item>
+41 -59
View File
@@ -1,14 +1,17 @@
import { Container, Col, Row } from "react-bootstrap";
import Link from "next/link"; import Link from "next/link";
import LogoSmall from "@/app/_components/layoutElements/logoSmall"; import LogoSmall from "@/app/_components/layoutElements/logoSmall";
import { LogoutButton } from "@/modules/features/auth/components/logoutButton";
//import { ComponentPropsWithoutRef } from "react"; //import { ComponentPropsWithoutRef } from "react";
//type Props = ComponentPropsWithoutRef<"footer">; //type Props = ComponentPropsWithoutRef<"footer">;
export const Footer = () => ( export const Footer = async () => {
<footer className="bd-footer pt-3 pb-2 pt-md-4 mt-5 bg-blue-gold"> return (
<div className="container py-4 py-md-5 px-4 px-md-3 text-body-secondary"> <footer className="bd-footer pt-3 pb-2 pt-md-4 mt-5 bg-dark-blue gold">
<div className="row"> <Container className="py-3 py-md-4 px-4 px-md-3">
<div className="col-lg-3 mb-3"> <Row>
<Col xs={12} lg={3}>
<Link <Link
className="d-inline-flex align-items-center mb-2 text-body-emphasis text-decoration-none" className="d-inline-flex align-items-center mb-2 text-body-emphasis text-decoration-none"
href="/" href="/"
@@ -16,115 +19,94 @@ export const Footer = () => (
> >
<LogoSmall /> <LogoSmall />
</Link> </Link>
<ul className="list-unstyled small"> <p className="mt-2 mb-3 small">
<li className="mb-2">
L&apos;équipe Ad Astra est réactive et à l&apos;écoute de vos demandes afin de vous accompagner au mieux L&apos;équipe Ad Astra est réactive et à l&apos;écoute de vos demandes afin de vous accompagner au mieux
et satisfaire vos besoins en fleurs et hashes CBD de qualité. et satisfaire vos besoins en fleurs et hashes CBD de qualité.
</li> </p>
<li className="mb-2">Exigez la qualité Ad Astra, vous la méritez.</li> <LogoutButton variant="outline-danger" />
</ul> </Col>
</div> <Col xs={6} lg={{ span: 2, offset: 1 }} className="mb-3 mt-3">
<div className="col-6 col-lg-2 offset-lg-1 mb-3">
<h5>Nos produits</h5> <h5>Nos produits</h5>
<ul className="list-unstyled"> <ul className="list-unstyled">
<li className="mb-2"> <li className="mb-2">
<i className="icon-home me-2" />
<Link href="/">Accueil</Link> <Link href="/">Accueil</Link>
</li> </li>
<li className="mb-2"> <li className="mb-2">
<Link href="/produits/fleurs">Lien 2</Link> <i className="icon-marijuana me-2" />
<Link href="/produits/les-fleurs">Fleurs</Link>
</li> </li>
<li className="mb-2"> <li className="mb-2">
<Link href="/produits/resines">Lien 3</Link> <i className="icon-hash me-2" />
<Link href="/produits/les-resines">Résines</Link>
</li> </li>
<li className="mb-2"> <li className="mb-2">
<Link href="/produits/molecules">Lien 4</Link> <i className="icon-molecule me-2" />
</li> <Link href="/produits/les-molecules">10OH+</Link>
<li className="mb-2">
<Link href="/produits/concentres">Lien 5</Link>
</li> </li>
</ul> </ul>
</div> </Col>
<div className="col-6 col-lg-2 mb-3"> <Col xs={6} lg={2} className="mb-3 mt-3">
<h5>Documentation</h5> <h5>Documentation</h5>
<ul className="list-unstyled"> <ul className="list-unstyled">
<li className="mb-2"> <li className="mb-2">
<Link href="/fleurs">Les fleurs</Link> <Link href="/article/les-fleurs">Les fleurs</Link>
</li> </li>
<li className="mb-2"> <li className="mb-2">
<Link href="/resines">Les hashes</Link> <Link href="/article/les-resines">Les hashes</Link>
</li> </li>
<li className="mb-2"> <li className="mb-2">
<Link href="/molecules">Les molécules</Link> <Link href="/article/les-molecules">Les molécules</Link>
</li> </li>
<li className="mb-2"> <li className="mb-2">
<Link href="/concentres">Les concentrés</Link> <Link href="/article/les-concentres">Les concentrés</Link>
</li> </li>
</ul> </ul>
</div> </Col>
<div className="col-6 col-lg-2 mb-3"> <Col xs={6} lg={2} className="mb-3 mt-3">
<h5>Professionels</h5> <h5>Professionels</h5>
<ul className="list-unstyled"> <ul className="list-unstyled">
<li className="mb-2"> <li className="mb-2">
<Link href="/catalogue_ad_astra_2025.pdf" target="_blank" rel="noopener"> <Link href="/catalogue_ad_astra_2025.pdf" target="_blank" rel="noopener">
Catalogue B2B Catalogue B2B
</Link>{" "} </Link>
</li> </li>
<li className="mb-2"> <li className="mb-2">
<Link href="/pro/lien2" target="_blank" rel="noopener"> <Link href="/pro/lien2" target="_blank" rel="noopener">
Lien 2 Lien 2
</Link>{" "} </Link>
</li> </li>
<li className="mb-2"> <li className="mb-2">
<Link href="/pro/lien3" target="_blank" rel="noopener"> <Link href="/pro/lien3" target="_blank" rel="noopener">
Lien 3 Lien 3
</Link> </Link>
</li> </li>
<li className="mb-2">
<Link href="/pro/lien4" target="_blank" rel="noopener">
Lien 4
</Link>
</li>
<li className="mb-2">
{" "}
<Link href="/pro/lien5" target="_blank" rel="noopener">
Lien 5
</Link>{" "}
</li>
</ul> </ul>
</div> </Col>
<div className="col-6 col-lg-2 mb-3"> <Col xs={6} lg={2} className="mb-3 mt-3">
<h5>Contact</h5> <h5>Contact</h5>
<ul className="list-unstyled"> <ul className="list-unstyled">
<li className="mb-2"> <li className="mb-2">
<Link href="/contact" target="_blank" rel="noopener"> <Link href="/contact" target="_blank" rel="noopener">
Lien 1 Lien 1
</Link>{" "} </Link>
</li> </li>
<li className="mb-2"> <li className="mb-2">
<Link href="/mentions-legales" target="_blank" rel="noopener"> <Link href="/mentions-legales" target="_blank" rel="noopener">
Lien 2 Lien 2
</Link>{" "}
</li>
<li className="mb-2">
<Link href="/produits" target="_blank" rel="noopener">
Lien 3
</Link>{" "}
</li>
<li className="mb-2">
<Link href="/produits" target="_blank" rel="noopener">
Lien 4
</Link> </Link>
</li> </li>
<li className="mb-2"> <li className="mb-2">
<Link href="/produits" target="_blank" rel="noopener"> <Link href="/produits" target="_blank" rel="noopener">
Lien 5 Lien 3
</Link>{" "} </Link>
</li> </li>
</ul> </ul>
</div> </Col>
</div> </Row>
</div> </Container>
<hr className="my-3" /> <hr className="my-3" />
<p className="text-muted px-4 mb-2 small">Copyright © 2025 Ad Astra</p> <p className="px-4 mb-2 small">Copyright © 2025 Ad Astra</p>
</footer> </footer>
); );
};
@@ -1,4 +1,4 @@
import { Button } from "@/modules/common/components/button"; import { Button, Form } from "react-bootstrap";
import { ErrorMessage } from "@/modules/common/components/errorMessage"; import { ErrorMessage } from "@/modules/common/components/errorMessage";
import { Article } from "@/utils/types/models"; import { Article } from "@/utils/types/models";
import { SubmissionResult, useForm } from "@conform-to/react"; import { SubmissionResult, useForm } from "@conform-to/react";
@@ -59,80 +59,74 @@ export const ArticleEditor = ({ defaultValues, result, action, isPending }: Prop
return ( return (
<> <>
<ErrorMessage messages={form.errors} /> <ErrorMessage messages={form.errors} />
<form id={form.id} action={action} onSubmit={form.onSubmit} noValidate={true}> <Form id={form.id} action={action} onSubmit={form.onSubmit} noValidate={true}>
<input type="hidden" key={fields.slug.key} name={fields.slug.name} defaultValue={fields.slug.initialValue} /> <Form.Control
<fieldset> type="hidden"
<fieldset className="form-group"> key={fields.slug.key}
<input name={fields.slug.name}
defaultValue={fields.slug.initialValue}
/>
<Form.Group className="mb-3" controlId="formLastname">
<Form.Label>Titre</Form.Label>
<Form.Control
type="text" type="text"
key={fields.title.key} key={fields.title.key}
name={fields.title.name} name={fields.title.name}
defaultValue={fields.title.initialValue} defaultValue={fields.title.initialValue}
placeholder="Article Title" placeholder="Titre"
className="form-control form-control-lg"
/> />
<ErrorMessage messages={fields.title.errors} /> <ErrorMessage messages={fields.title.errors} />
</fieldset> </Form.Group>
<fieldset className="form-group"> <Form.Group className="mb-3" controlId="formLastname">
<input <Form.Label>Catégorie</Form.Label>
<Form.Control
type="text" type="text"
key={fields.description.key} key={fields.description.key}
name={fields.description.name} name={fields.description.name}
defaultValue={fields.description.initialValue} defaultValue={fields.description.initialValue}
placeholder="What's this article about?" placeholder="Catégorie"
className="form-control"
/> />
<ErrorMessage messages={fields.description.errors} /> <ErrorMessage messages={fields.description.errors} />
</fieldset> </Form.Group>
<fieldset className="form-group"> <Form.Group className="mb-3" controlId="formBody">
<textarea <Form.Label>Description</Form.Label>
<Form.Control as="textarea" rows={8}
key={fields.body.key} key={fields.body.key}
name={fields.body.name} name={fields.body.name}
defaultValue={fields.body.initialValue} defaultValue={fields.body.initialValue}
rows={8}
placeholder="Write your article (in markdown)" placeholder="Write your article (in markdown)"
className="form-control"
/> />
<ErrorMessage messages={fields.body.errors} /> <ErrorMessage messages={fields.body.errors} />
</fieldset> </Form.Group>
<fieldset className="form-group"> <Form.Group className="mb-3" controlId="formLastname">
<input <Form.Label>Nom</Form.Label>
<Form.Control
type="text" type="text"
key={fields.tag.key} key={fields.tag.key}
name={fields.tag.name} name={fields.tag.name}
defaultValue={fields.tag.initialValue} defaultValue={fields.tag.initialValue}
placeholder="Enter tags" placeholder="Enter tags"
onKeyDown={onTagFormKeyDown} onKeyDown={onTagFormKeyDown}
className="form-control"
/> />
<ul className="tag-list"> <ul className="list-unstyled">
{fields.tagList.getFieldList().map((tagField, index) => ( {fields.tagList.getFieldList().map((tagField, index) => (
<li key={tagField.key}> <li key={tagField.key}>
<Tag component="span" variant="filled" className={styles["tag-form"]}> <Tag component="badge" color="info" className={styles["tag-form"]}>
<input type="hidden" name={tagField.name} value={tagField.value} /> <input type="hidden" name={tagField.name} value={tagField.value} />
<button onClick={() => onClickRemoveTag(index)}> <span onClick={() => onClickRemoveTag(index)} className="me-2">
<i className="ion-close-round" /> <i className="icon-close" />
</button> </span>
{tagField.value} {tagField.value}
</Tag> </Tag>
</li> </li>
))} ))}
</ul> </ul>
<ErrorMessage messages={tagListErrors} /> <ErrorMessage messages={tagListErrors} />
</fieldset> </Form.Group>
<Button <Button variant="primary" type="submit" disabled={isPending}>
component="button" Enregistrer
size="lg"
color="primary"
variant="filled"
type="submit"
className="pull-xs-right"
disabled={isPending}
>
Publish Article
</Button> </Button>
</fieldset> </Form>
</form>
</> </>
); );
}; };
@@ -1,4 +1,4 @@
import { Button } from "@/modules/common/components/button"; import { Button, Form } from "react-bootstrap";
import clsx from "clsx"; import clsx from "clsx";
import { MouseEventHandler } from "react"; import { MouseEventHandler } from "react";
import styles from "./presentation.module.css"; import styles from "./presentation.module.css";
@@ -12,10 +12,10 @@ type Props = {
export const DeleteArticleButton = ({ action, isPending, className }: Props) => { export const DeleteArticleButton = ({ action, isPending, className }: Props) => {
return ( return (
<form action={action} className={clsx(className, styles["form"])}> <Form action={action} className={clsx(className, styles["form"])}>
<Button component="button" color="danger" type="submit" disabled={isPending}> <Button variant="danger" type="submit" disabled={isPending}>
<i className="ion-trash-a"></i> Delete Article Supprimer
</Button> </Button>
</form> </Form>
); );
}; };
@@ -1,3 +1,4 @@
import { Form } from "react-bootstrap";
import { Button } from "@/modules/common/components/button"; import { Button } from "@/modules/common/components/button";
import clsx from "clsx"; import clsx from "clsx";
import styles from "./presentation.module.css"; import styles from "./presentation.module.css";
@@ -24,10 +25,10 @@ export const FavoriteButton = ({ favorited, favoritesCount, action, disabled, sh
); );
return ( return (
<form action={action} className={clsx(styles["form"], className)}> <Form action={action} className={clsx(styles["form"], className)}>
<Button component="button" variant={favorited ? "filled" : "outline"} disabled={disabled}> <Button component="button" variant={favorited ? "filled" : "outline"} disabled={disabled}>
{content} {content}
</Button> </Button>
</form> </Form>
); );
}; };
@@ -1,9 +1,11 @@
import { Badge } from "react-bootstrap";
import { ExhaustiveError } from "@/utils/errors"; import { ExhaustiveError } from "@/utils/errors";
import clsx from "clsx"; import clsx from "clsx";
import Link from "next/link"; import Link from "next/link";
import { ComponentPropsWithoutRef } from "react"; import { ComponentPropsWithoutRef } from "react";
type TagVariant = "outline" | "filled"; type TagVariant = "outline" | "filled";
type TagColor = "primary" | "secondary" | "success" | "danger" | "warning" | "info" | "light" | "dark";
const variantClassNameMaps: Record<TagVariant, string> = { const variantClassNameMaps: Record<TagVariant, string> = {
outline: "tag-outline", outline: "tag-outline",
@@ -12,6 +14,7 @@ const variantClassNameMaps: Record<TagVariant, string> = {
type CommonTagProps = { type CommonTagProps = {
variant?: TagVariant; variant?: TagVariant;
color?: TagColor;
}; };
////////////////////////// //////////////////////////
@@ -57,8 +60,22 @@ const TagAsSpan = ({ children, variant = "filled", className, ...rest }: TagProp
); );
////////////////////////// //////////////////////////
// badge pattern
export type TagProps = TagPropsAsListItem | TagPropsAsAnchor | TagPropsAsSpan; type TagPropsAsBadge = CommonTagProps &
ComponentPropsWithoutRef<"span"> & {
component: "badge";
};
const TagAsBadge = ({ children, color = "primary", className, ...rest }: TagPropsAsBadge) => (
<Badge bg={color} {...rest}>
{children}
</Badge>
);
//////////////////////////
export type TagProps = TagPropsAsListItem | TagPropsAsAnchor | TagPropsAsSpan | TagPropsAsBadge;
export const Tag = (props: TagProps) => { export const Tag = (props: TagProps) => {
switch (props.component) { switch (props.component) {
@@ -68,6 +85,8 @@ export const Tag = (props: TagProps) => {
return <TagAsAnchor {...props} />; return <TagAsAnchor {...props} />;
case "span": case "span":
return <TagAsSpan {...props} />; return <TagAsSpan {...props} />;
case "badge":
return <TagAsBadge {...props} />;
default: default:
// compilation fails if all cases are not covered // compilation fails if all cases are not covered
throw new ExhaustiveError(props); throw new ExhaustiveError(props);
@@ -1,17 +1,22 @@
"use client" "use client"
import { User } from "@/utils/types/models"; import { User } from "@/utils/types/models";
import { Container, Nav, Navbar, NavDropdown } from "react-bootstrap"; import { Button, Form, Container, Nav, Navbar, NavDropdown } from "react-bootstrap";
import { HeaderMenuItem } from "./headerMenuItem"; import { HeaderMenuItem } from "./headerMenuItem";
import LogoSmall from "@/app/_components/layoutElements/logoSmall"; import LogoSmall from "@/app/_components/layoutElements/logoSmall";
import { LogoutButton } from "@/modules/features/auth/components/logoutButton";
import ButtonOffcanvas from "@/modules/common/components/button/buttonOffcanvas"; import ButtonOffcanvas from "@/modules/common/components/button/buttonOffcanvas";
const UnauthenticatedMenus = () => { const UnauthenticatedMenus = () => {
return ( return (
<> <>
<HeaderMenuItem href="/login" segment="login"> <HeaderMenuItem href="/login" segment="login">
Se connecter Se connecter
</HeaderMenuItem> </HeaderMenuItem>
<Navbar.Text>
/
</Navbar.Text>
<HeaderMenuItem href="/register" segment="register"> <HeaderMenuItem href="/register" segment="register">
Créer un compte Créer un compte
</HeaderMenuItem> </HeaderMenuItem>
@@ -22,15 +27,19 @@ const UnauthenticatedMenus = () => {
const AuthenticatedMenus = ({ authUser }: { authUser: User }) => { const AuthenticatedMenus = ({ authUser }: { authUser: User }) => {
return ( return (
<> <>
<HeaderMenuItem href="/editor" segment="editor"> <NavDropdown title={authUser.username} id="basic-nav-dropdown">
<span className="icon-barcode me-2"></span>Ajouter un produit <NavDropdown.Item href={`/profile/${authUser.username}`}>
</HeaderMenuItem> <span className="icon-user me-2"></span>Mon compte
<HeaderMenuItem href="/settings" segment="settings"> </NavDropdown.Item>
<NavDropdown.Item href="/settings">
<span className="icon-cog me-2"></span>Paramètres <span className="icon-cog me-2"></span>Paramètres
</HeaderMenuItem> </NavDropdown.Item>
<HeaderMenuItem href={`/profile/${authUser.username}`} segment="profile"> <NavDropdown.Item href="/editor">
<span className="icon-user me-2"></span>{authUser.username} <span className="icon-barcode me-2"></span>Ajouter un produit
</HeaderMenuItem> </NavDropdown.Item>
<NavDropdown.Divider />
<LogoutButton variant="outline-danger" />
</NavDropdown>
<ButtonOffcanvas className="ms-3" /> <ButtonOffcanvas className="ms-3" />
</> </>
); );
@@ -39,7 +48,7 @@ const AuthenticatedMenus = ({ authUser }: { authUser: User }) => {
export const Header = ({ authUser }: { authUser?: User }) => { export const Header = ({ authUser }: { authUser?: User }) => {
return ( return (
<header> <header>
<Navbar bg="dark" data-bs-theme="dark" expand="lg" className="bg-darker mb-4 pt-1 pb-2"> <Navbar bg="dark" data-bs-theme="dark" expand="lg" className="bg-dark-blue mb-4 pt-1 pb-2">
<Container> <Container>
<Navbar.Brand href="/"> <Navbar.Brand href="/">
<LogoSmall /> <LogoSmall />
@@ -4,8 +4,16 @@ import { useActionState } from "react";
import { logoutAction } from "./action"; import { logoutAction } from "./action";
import { LogoutButton as LogoutButtonPresentation } from "./presentation"; import { LogoutButton as LogoutButtonPresentation } from "./presentation";
export const LogoutButton = () => { type Variant = "primary" | "secondary" | "success" | "danger" | "warning" | "info" | "light" | "dark"
| "outline-primary" | "outline-secondary" | "outline-success" | "outline-danger" | "outline-warning" | "outline-info" | "outline-light" | "outline-dark";
const DEFAULT_VARIANT: Variant = "danger";
type CommonProps = {
variant?: Variant;
};
export const LogoutButton = ({variant = DEFAULT_VARIANT}: CommonProps) => {
const [_state, action, isPending] = useActionState(logoutAction, undefined); const [_state, action, isPending] = useActionState(logoutAction, undefined);
return <LogoutButtonPresentation action={action} isPending={isPending} />; return <LogoutButtonPresentation variant={variant} action={action} isPending={isPending} />;
}; };
@@ -1,13 +1,13 @@
import { Button } from "@/modules/common/components/button"; import { Button, Form } from "react-bootstrap";
type Props = { action?: () => void; isPending?: boolean }; type Props = { action?: () => void; isPending?: boolean; variant?: string; };
export const LogoutButton = ({ action, isPending }: Props) => { export const LogoutButton = ({ action, isPending, variant }: Props) => {
return ( return (
<form action={action}> <Form action={action}>
<Button component="button" color="danger" type="submit" size="lg" disabled={isPending}> <Button variant={variant} type="submit" disabled={isPending}>
Or click here to logout. <i className="icon-switch me-2" />Se déconnecter
</Button> </Button>
</form> </Form>
); );
}; };
@@ -1,3 +1,4 @@
import { Form } from "react-bootstrap";
import { Button, Color } from "@/modules/common/components/button"; import { Button, Color } from "@/modules/common/components/button";
import styles from "./presentation.module.css"; import styles from "./presentation.module.css";
import clsx from "clsx"; import clsx from "clsx";
@@ -13,7 +14,7 @@ type Props = {
export const FollowButton = ({ username, color, following, action, isPending, className }: Props) => { export const FollowButton = ({ username, color, following, action, isPending, className }: Props) => {
return ( return (
<form action={action} className={clsx(className, styles["form"])}> <Form action={action} className={clsx(className, styles["form"])}>
<Button <Button
component="button" component="button"
type="submit" type="submit"
@@ -24,6 +25,6 @@ export const FollowButton = ({ username, color, following, action, isPending, cl
> >
<i className="ion-plus-round"></i> {following ? "Unfollow" : "Follow"} {username} <i className="ion-plus-round"></i> {following ? "Unfollow" : "Follow"} {username}
</Button> </Button>
</form> </Form>
); );
}; };
@@ -16,6 +16,7 @@ export const fetchProfile = cache(async (username: string) => {
const response = await client.sendRequest(); const response = await client.sendRequest();
if (response.result === "success") { if (response.result === "success") {
console.log(response.data);
return Profile.parse(response.data.profile); return Profile.parse(response.data.profile);
} }
Binary file not shown.
+26
View File
@@ -8,7 +8,12 @@
<missing-glyph horiz-adv-x="1024" /> <missing-glyph horiz-adv-x="1024" />
<glyph unicode="&#x20;" horiz-adv-x="512" d="" /> <glyph unicode="&#x20;" horiz-adv-x="512" d="" />
<glyph unicode="&#xe900;" glyph-name="home" d="M1024 369.556l-512 397.426-512-397.428v162.038l512 397.426 512-397.428zM896 384v-384h-256v256h-256v-256h-256v384l384 288z" /> <glyph unicode="&#xe900;" glyph-name="home" d="M1024 369.556l-512 397.426-512-397.428v162.038l512 397.426 512-397.428zM896 384v-384h-256v256h-256v-256h-256v384l384 288z" />
<glyph unicode="&#xe901;" glyph-name="close" d="M569.436 447.998l214.93 214.946c15.84 15.866 15.84 41.556 0 57.42-15.89 15.866-41.598 15.866-57.436 0l-214.93-214.93-214.93 214.93c-15.88 15.866-41.546 15.866-57.436 0-15.84-15.866-15.84-41.556 0-57.42l214.93-214.946-214.93-214.938c-15.84-15.84-15.84-41.546 0-57.436 7.966-7.914 18.338-11.886 28.72-11.886 10.414 0 20.794 3.962 28.712 11.886l214.93 214.93 214.93-214.93c7.916-7.914 18.338-11.886 28.712-11.886 10.38 0 20.754 3.962 28.72 11.886 15.84 15.89 15.84 41.598 0 57.436l-214.916 214.94z" />
<glyph unicode="&#xe902;" glyph-name="hash" d="M1023.731 372.060c-0.698 5.633-1.845 10.827-4.012 15.228-12.298 25.835-95.102 172.248-146.822 239.683-38.699 53.765-42.736 59.39-106.637 57.508-66.542-1.957-286.595-18.614-288.812-18.784-6.333-1.548-12.807-3.755-18.699-5.418-35.353 35.473-100.463 91.806-143.344 121.231-45.726 31.378-61.557 15.527-103.922-26.815-7.715-7.715-16.49-16.467-26.533-26.040-63.759-60.821-161.499-182.063-162.514-183.332-27.448-34.555-27.261-51.845-12.585-89.644 12.939-33.238 64.896-167.997 82.986-220.238 11.56-32.939 18.173-46.618 28.765-57.014 5.456-5.304 11.704-9.114 19.786-13.742 10.423-5.952 29.403-14.844 51.349-25.125 21.806-10.231 46.504-21.828 66.427-32.271 38.766-21.008 66.332-2.815 98.628 18.986 16.983 10.979 62.19 63.173 110.622 119.252 8.119-30.717 18.32-66.347 24.992-78.949 18.704-35.333 32.879-40.046 79.286-40.046 30.75 0 162.935 18.626 259.451 32.231 43.654 6.149 78.136 11.011 89.923 12.253 39.754 4.202 76.109 13.203 84.24 76.239 4.548 40.133 19.901 91.165 17.425 124.807v0zM470.964 654.085c16.327 5.186 225.27 17.751 295.572 20.99 58.906 1.728 60.395-0.349 98.72-53.603 51.339-66.99 133.864-212.576 145.974-238.256 1.060-2.204 1.823-4.733 2.381-7.493-28.658-3.015-175.662-18.487-276.262-27.304-33.617-2.942-63.066-6.82-89.058-10.233-48.409-6.373-83.198-10.959-101.451-3.501 8.371 9.031 15.594 16.392 21.098 21.379 36.41 34.059 77.436 71.429 51.234 115.681-21.621 34.909-104.208 124.605-142.713 169.548-2.75 3.294-6.234 7.104-10.276 11.385 1.529 0.456 3.117 0.923 4.78 1.406zM310.086 773.748c51.416-36.358 119.339-94.277 159.155-138.499 38.101-44.494 120.783-134.292 141.955-168.466 3.857-6.209 6.072-12.395 6.75-18.629-41.734 36.131-113.335 89.492-155.622 120.905-0.005 0.002-0.007 0.007-0.012 0.010-0.025 8.52-10.966 32.348-87.704 121.795-32.752 38.173-66.457 75.391-83.188 93.696 5.556-2.429 11.665-6.004 18.666-10.812zM18.624 459.091c-13.619 35.049-13.759 48.995 11.173 80.375 1.551 1.905 98.558 122.199 161.646 182.367 10.136 9.667 18.933 18.464 26.698 26.227 26.164 26.164 40.275 40.253 56.986 40.34 8.012-8.687 49.581-53.934 90.245-101.224 82.42-95.853 87.829-114.586 87.395-118.112-5.675-10.867-32.879-38.704-64.357-70.913-27.416-28.054-58.488-59.851-88.080-92.97-59.049-66.113-156.477-190.526-176.071-215.648-6.912 8.657-13.31 22.347-22.526 48.987-18.14 52.386-70.17 187.309-83.108 220.57zM352.688 134.178c-28.907-18.661-52.421-38.31-89.173-18.557-32.301 17.153-89.098 41.886-117.449 57.253-6.002 3.436-10.872 6.214-15.2 9.837 38.692 51.194 188.229 237.935 264.274 308.865 30.832 31.548 54.057 55.331 63.233 68.708 45.828-34.006 123.054-91.903 159.058-124.291-4.092-21.666-24.651-44.718-55.817-72.965-6.024-5.458-13.809-13.435-22.863-23.219-45.008-47.561-154.737-183.215-186.062-205.631v0zM501.719 170.982c-5.276 9.962-14.44 39.482-25.843 83.183 21.038 24.379 42.205 48.84 59.899 68.442-2.621-31.169-10.565-128.056-12.455-178.744-8.129 5.134-14.392 13.505-21.601 27.119v0zM1006.483 304.659c-15.096-69.813-2.613-118.172-85.405-124.284-75.952-9.386-309.284-44.793-348.387-44.429-17.988-0.002-30.436 0.588-40.1 3.673 1.646 51.049 10.515 158.003 12.844 185.526 7.543-2.628 16.826-3.725 27.987-3.725 19.547 0 44.763 3.314 76.092 7.431 95.252 12.403 322.168 31.705 365.128 37.517 0.561-16.061-3.566-37.714-8.159-61.709v0z" />
<glyph unicode="&#xe903;" glyph-name="molecule" d="M568.662 567.666l181.009-103.915c2.325-1.185 4.651-4.654 4.651-7.027v-209.009c0-1.188 0-2.328 1.185-2.328l156.46-88.768h2.325l45.527 26.868c2.325 1.188 5.839 1.188 8.164 0l51.364-30.382c2.325-1.185 4.651-4.651 4.651-7.024v-59.576c0-3.513-1.185-5.839-4.651-7.024l-51.364-30.382c-2.325-1.185-5.839-1.185-8.164 0l-51.364 30.382c-2.328 1.185-4.654 4.651-4.654 7.024v53.737c0 1.188 0 2.328-1.185 2.328l-156.46 86.441h-2.325l-181.009-103.915c-2.325-1.185-5.836-1.185-9.349 0l-181.009 103.915h-3.51l-246.381-142.458c-1.188 0-1.188-1.188-1.188-2.328v-53.737c0-3.513-2.325-5.839-4.651-7.024l-52.552-30.334c-2.325-1.188-5.839-1.188-8.164 0l-51.364 30.379c-2.325 1.188-4.654 4.654-4.654 7.027v59.576c0 3.51 1.188 5.839 4.654 7.024l51.364 30.382c2.325 1.185 5.839 1.185 8.164 0l45.527-26.868h3.51l247.56 143.556c1.188 0 1.188 1.185 1.188 2.325v202.038c0 1.185 0 2.325-1.188 2.325l-134.294 73.581h-2.328l-46.709-26.868c-2.328-1.185-5.839-1.185-8.167 0l-51.364 30.382c-2.325 1.185-4.651 4.654-4.651 7.024v59.576c0 3.513 1.185 5.839 4.651 7.027l51.364 30.382c2.328 1.185 5.839 1.185 8.167 0l51.364-30.382c2.325-1.185 4.651-4.654 4.651-7.027v-52.552c0-1.185 0-2.325 1.188-2.325l134.294-73.581h2.325l175.171 101.586c1.185 0 1.185 1.185 1.185 2.325v199.669c0 1.185 0 2.325-1.185 2.325l-44.34 26.868c-2.325 1.185-4.654 4.654-4.654 7.024v59.576c0 3.513 2.328 5.839 4.654 8.164l51.364 29.197c2.325 1.185 5.839 1.185 9.349 0l51.365-30.382c2.325-1.185 4.651-4.654 4.651-7.024v-59.576c0-3.513-2.325-5.839-4.651-8.167l-45.527-25.683c-1.185 0-1.185-1.185-1.185-2.325v-199.716c-1.14-1.14 0-1.14 1.185-2.325h0.008zM414.526 329.464v100.446c0 1.188 0 2.325 1.185 2.325l81.744 46.713c10.492 5.839 1.185 21.029-9.349 15.191l-86.399-50.225c-3.51-1.185-4.651-4.651-4.651-8.164v-107.425c-0.051-10.54 17.468-10.54 17.468 1.14v0zM18.623 86.548c-1.185 0-1.185-1.185-1.185-2.325v-46.713c0-1.188 0-2.325 1.185-2.325l39.686-23.358h2.328l39.686 23.358c1.188 0 1.188 1.185 1.188 2.325v46.713c0 1.185 0 2.325-1.188 2.325l-39.686 23.355h-2.328l-39.686-23.355zM130.749 592.214c-1.185 0-1.185-1.185-1.185-2.328v-46.713c0-1.185 0-2.325 1.185-2.325l39.686-23.355h2.325l39.688 23.355c1.185 0 1.185 1.185 1.185 2.325v46.713c0 1.185 0 2.328-1.185 2.328l-39.688 23.355h-2.325l-39.686-23.355zM923.655 140.29c-1.188 0-1.188-1.188-1.188-2.325v-46.713c0-1.188 0-2.325 1.188-2.325l39.686-23.358h2.325l39.686 23.358c1.188 0 1.188 1.185 1.188 2.325v46.713c0 1.185 0 2.325-1.188 2.325l-39.686 23.355h-2.325l-39.686-23.355zM559.315 885.303h-3.51l-39.688-23.355c-1.185 0-1.185-1.185-1.185-2.325v-46.713c0-1.185 0-2.325 1.185-2.325l39.688-23.355h3.51l39.688 23.355c1.185 0 1.185 1.185 1.185 2.325v46.713c0 1.185 0 2.325-1.185 2.325l-39.688 23.355zM559.315 552.484h-2.325l-175.167-101.586c-1.188 0-1.188-1.185-1.188-2.328v-202.038c0-1.188 0-2.328 1.188-2.328l175.167-101.586h3.513l175.167 101.586c1.188 0 1.188 1.188 1.188 2.328l-0.048 203.218c0 1.185 0 2.328-1.185 2.328l-176.311 100.406z" />
<glyph unicode="&#xe904;" glyph-name="marijuana" d="M960.897 196.35l26.114 12.546-26.114 12.546c-4.734 2.303-114.817 54.529-253.825 56.32 6.271 6.271 12.417 12.674 18.303 19.074 133.632 143.998 193.535 309.887 195.97 316.927l10.24 28.8-26.752-11.009c-6.529-2.689-160.387-67.072-294.145-211.202-0.514-0.511-1.023-1.151-1.537-1.666 0.643 16.003 1.023 32.003 1.023 47.617 0 132.739-23.423 252.033-43.137 328.833-21.374 83.2-42.366 134.529-43.263 136.579l-11.774 28.286-11.649-28.16c-0.894-2.174-22.014-53.374-43.263-136.575-19.711-76.672-43.137-196.099-43.137-328.833 0-15.617 0.383-31.614 1.023-47.617-0.514 0.514-1.023 1.154-1.537 1.666-133.886 144-287.745 208.512-294.273 211.202l-26.752 11.009 10.24-28.8c2.434-7.040 62.334-172.798 195.97-316.931 5.889-6.397 12.031-12.671 18.303-19.071-139.006-1.791-249.219-54.017-253.825-56.32l-26.112-12.546 26.112-12.546c4.737-2.306 118.787-56.32 261.25-56.32 25.986 0 52.609 1.791 79.615 5.506-63.997-71.554-92.797-151.427-93.952-154.88l-10.24-28.8 26.752 11.009c3.329 1.409 81.535 34.049 149.246 107.137 9.471 10.24 18.689 21.12 27.52 32.64-0.254-59.009-1.534-118.017-4.097-176.769 8.577 0 17.026 0 25.603 0-2.56 58.752-3.843 117.76-3.971 176.641 8.834-11.52 18.049-22.529 27.523-32.64 67.837-73.089 146.046-105.857 149.246-107.137l26.752-11.009-10.24 28.8c-1.28 3.454-29.952 83.329-93.956 154.88 27.009-3.586 53.632-5.506 79.617-5.506 142.472 0 256.393 54.017 261.127 56.32zM572.929 155.39c8.317-7.551 16.254-15.489 23.551-23.423 38.397-41.346 64.383-87.426 79.103-117.632-28.157 15.871-70.78 43.774-109.183 85.12-15.489 16.766-30.334 35.583-44.032 56.192l-10.369 15.617-10.369-15.617c-13.697-20.48-28.414-39.426-44.032-56.192-38.4-41.346-81.152-69.377-109.312-85.249 14.589 30.209 40.574 76.289 79.103 117.76 7.426 7.934 15.363 15.874 23.554 23.423l36.48 33.409-47.103-9.346c-39.554-7.809-78.72-11.906-116.097-11.906-94.337 0-177.41 25.474-220.162 41.346 42.752 16.003 125.695 41.346 220.162 41.346 8.577 0 17.28-0.257 25.986-0.64l36.863-1.794-27.906 25.986c-14.974 13.951-29.186 28.157-42.497 42.494-95.743 103.169-153.472 220.547-177.282 275.588 51.074-25.726 160-87.935 255.747-191.103 8.32-8.96 16.769-18.431 25.086-28.286l25.089-29.573-2.814 39.941c-2.049 28.157-3.071 56.189-3.071 83.455 0 190.722 49.409 355.716 72.575 422.531 23.166-66.814 72.575-231.682 72.575-422.531 0-27.266-1.023-55.297-3.071-83.455l-2.814-39.941 25.086 29.573c8.32 9.854 16.769 19.329 25.089 28.286 95.746 103.169 204.672 165.379 255.747 191.103-23.937-55.040-81.666-172.415-177.282-275.588-13.314-14.337-27.523-28.543-42.497-42.494l-27.906-25.986 36.863 1.794c8.706 0.383 17.537 0.64 25.986 0.64 94.337 0 177.41-25.472 220.162-41.346-42.752-16-125.695-41.346-220.162-41.346-37.503 0-76.543 3.971-116.097 11.906l-47.103 9.346 36.354-33.409z" />
<glyph unicode="&#xe905;" glyph-name="pencil" d="M864 960c88.364 0 160-71.634 160-160 0-36.020-11.91-69.258-32-96l-64-64-224 224 64 64c26.742 20.090 59.978 32 96 32zM64 224l-64-288 288 64 592 592-224 224-592-592zM715.578 596.422l-448-448-55.156 55.156 448 448 55.156-55.156z" /> <glyph unicode="&#xe905;" glyph-name="pencil" d="M864 960c88.364 0 160-71.634 160-160 0-36.020-11.91-69.258-32-96l-64-64-224 224 64 64c26.742 20.090 59.978 32 96 32zM64 224l-64-288 288 64 592 592-224 224-592-592zM715.578 596.422l-448-448-55.156 55.156 448 448 55.156-55.156z" />
<glyph unicode="&#xe906;" glyph-name="cannabis" d="M488.786 290.304c-55.296 137.556-167.252 315.392-391.852 430.764 75.098-242.348 231.77-384 358.060-462.164-98.982 50.176-245.076 93.182-423.596 52.564 163.84-105.472 325.632-109.568 436.908-92.506-67.244-16.382-153.26-54.95-221.524-144.722 130.050 16.384 210.604 88.064 255.662 143.020v-281.26h19.116v281.26c45.056-54.956 125.612-126.636 255.662-143.020-68.268 89.772-154.284 128.34-221.524 144.722 111.276-17.068 273.068-12.972 436.908 92.506-178.516 40.614-324.61-2.388-423.596-52.564 126.292 78.162 282.964 219.82 358.060 462.164-224.596-115.372-336.558-293.204-391.852-430.764 54.272 160.084 90.11 400.384-23.212 669.696-113.329-269.312-77.489-509.612-23.217-669.696v0z" />
<glyph unicode="&#xe90d;" glyph-name="image" d="M959.884 832c0.040-0.034 0.082-0.076 0.116-0.116v-767.77c-0.034-0.040-0.076-0.082-0.116-0.116h-895.77c-0.040 0.034-0.082 0.076-0.114 0.116v767.772c0.034 0.040 0.076 0.082 0.114 0.114h895.77zM960 896h-896c-35.2 0-64-28.8-64-64v-768c0-35.2 28.8-64 64-64h896c35.2 0 64 28.8 64 64v768c0 35.2-28.8 64-64 64v0zM832 672c0-53.020-42.98-96-96-96s-96 42.98-96 96 42.98 96 96 96 96-42.98 96-96zM896 128h-768v128l224 384 256-320h64l224 192z" /> <glyph unicode="&#xe90d;" glyph-name="image" d="M959.884 832c0.040-0.034 0.082-0.076 0.116-0.116v-767.77c-0.034-0.040-0.076-0.082-0.116-0.116h-895.77c-0.040 0.034-0.082 0.076-0.114 0.116v767.772c0.034 0.040 0.076 0.082 0.114 0.114h895.77zM960 896h-896c-35.2 0-64-28.8-64-64v-768c0-35.2 28.8-64 64-64h896c35.2 0 64 28.8 64 64v768c0 35.2-28.8 64-64 64v0zM832 672c0-53.020-42.98-96-96-96s-96 42.98-96 96 42.98 96 96 96 96-42.98 96-96zM896 128h-768v128l224 384 256-320h64l224 192z" />
<glyph unicode="&#xe91a;" glyph-name="bullhorn" d="M1024 530.744c0 200.926-58.792 363.938-131.482 365.226 0.292 0.006 0.578 0.030 0.872 0.030h-82.942c0 0-194.8-146.336-475.23-203.754-8.56-45.292-14.030-99.274-14.030-161.502s5.466-116.208 14.030-161.5c280.428-57.418 475.23-203.756 475.23-203.756h82.942c-0.292 0-0.578 0.024-0.872 0.032 72.696 1.288 131.482 164.298 131.482 365.224zM864.824 220.748c-9.382 0-19.532 9.742-24.746 15.548-12.63 14.064-24.792 35.96-35.188 63.328-23.256 61.232-36.066 143.31-36.066 231.124 0 87.81 12.81 169.89 36.066 231.122 10.394 27.368 22.562 49.266 35.188 63.328 5.214 5.812 15.364 15.552 24.746 15.552 9.38 0 19.536-9.744 24.744-15.552 12.634-14.064 24.796-35.958 35.188-63.328 23.258-61.23 36.068-143.312 36.068-231.122 0-87.804-12.81-169.888-36.068-231.124-10.39-27.368-22.562-49.264-35.188-63.328-5.208-5.806-15.36-15.548-24.744-15.548zM251.812 530.744c0 51.95 3.81 102.43 11.052 149.094-47.372-6.554-88.942-10.324-140.34-10.324-67.058 0-67.058 0-67.058 0l-55.466-94.686v-88.17l55.46-94.686c0 0 0 0 67.060 0 51.398 0 92.968-3.774 140.34-10.324-7.236 46.664-11.048 97.146-11.048 149.096zM368.15 317.828l-127.998 24.51 81.842-321.544c4.236-16.634 20.744-25.038 36.686-18.654l118.556 47.452c15.944 6.376 22.328 23.964 14.196 39.084l-123.282 229.152zM864.824 411.27c-3.618 0-7.528 3.754-9.538 5.992-4.87 5.42-9.556 13.86-13.562 24.408-8.962 23.6-13.9 55.234-13.9 89.078s4.938 65.478 13.9 89.078c4.006 10.548 8.696 18.988 13.562 24.408 2.010 2.24 5.92 5.994 9.538 5.994 3.616 0 7.53-3.756 9.538-5.994 4.87-5.42 9.556-13.858 13.56-24.408 8.964-23.598 13.902-55.234 13.902-89.078 0-33.842-4.938-65.478-13.902-89.078-4.004-10.548-8.696-18.988-13.56-24.408-2.008-2.238-5.92-5.992-9.538-5.992z" /> <glyph unicode="&#xe91a;" glyph-name="bullhorn" d="M1024 530.744c0 200.926-58.792 363.938-131.482 365.226 0.292 0.006 0.578 0.030 0.872 0.030h-82.942c0 0-194.8-146.336-475.23-203.754-8.56-45.292-14.030-99.274-14.030-161.502s5.466-116.208 14.030-161.5c280.428-57.418 475.23-203.756 475.23-203.756h82.942c-0.292 0-0.578 0.024-0.872 0.032 72.696 1.288 131.482 164.298 131.482 365.224zM864.824 220.748c-9.382 0-19.532 9.742-24.746 15.548-12.63 14.064-24.792 35.96-35.188 63.328-23.256 61.232-36.066 143.31-36.066 231.124 0 87.81 12.81 169.89 36.066 231.122 10.394 27.368 22.562 49.266 35.188 63.328 5.214 5.812 15.364 15.552 24.746 15.552 9.38 0 19.536-9.744 24.744-15.552 12.634-14.064 24.796-35.958 35.188-63.328 23.258-61.23 36.068-143.312 36.068-231.122 0-87.804-12.81-169.888-36.068-231.124-10.39-27.368-22.562-49.264-35.188-63.328-5.208-5.806-15.36-15.548-24.744-15.548zM251.812 530.744c0 51.95 3.81 102.43 11.052 149.094-47.372-6.554-88.942-10.324-140.34-10.324-67.058 0-67.058 0-67.058 0l-55.466-94.686v-88.17l55.46-94.686c0 0 0 0 67.060 0 51.398 0 92.968-3.774 140.34-10.324-7.236 46.664-11.048 97.146-11.048 149.096zM368.15 317.828l-127.998 24.51 81.842-321.544c4.236-16.634 20.744-25.038 36.686-18.654l118.556 47.452c15.944 6.376 22.328 23.964 14.196 39.084l-123.282 229.152zM864.824 411.27c-3.618 0-7.528 3.754-9.538 5.992-4.87 5.42-9.556 13.86-13.562 24.408-8.962 23.6-13.9 55.234-13.9 89.078s4.938 65.478 13.9 89.078c4.006 10.548 8.696 18.988 13.562 24.408 2.010 2.24 5.92 5.994 9.538 5.994 3.616 0 7.53-3.756 9.538-5.994 4.87-5.42 9.556-13.858 13.56-24.408 8.964-23.598 13.902-55.234 13.902-89.078 0-33.842-4.938-65.478-13.902-89.078-4.004-10.548-8.696-18.988-13.56-24.408-2.008-2.238-5.92-5.992-9.538-5.992z" />
<glyph unicode="&#xe920;" glyph-name="books" horiz-adv-x="1152" d="M224 832h-192c-17.6 0-32-14.4-32-32v-704c0-17.6 14.4-32 32-32h192c17.6 0 32 14.4 32 32v704c0 17.6-14.4 32-32 32zM192 640h-128v64h128v-64zM544 832h-192c-17.6 0-32-14.4-32-32v-704c0-17.6 14.4-32 32-32h192c17.6 0 32 14.4 32 32v704c0 17.6-14.4 32-32 32zM512 640h-128v64h128v-64zM765.088 782.52l-171.464-86.394c-15.716-7.918-22.096-27.258-14.178-42.976l287.978-571.548c7.918-15.718 27.258-22.098 42.976-14.178l171.464 86.392c15.716 7.92 22.096 27.26 14.178 42.974l-287.978 571.55c-7.92 15.718-27.26 22.1-42.976 14.18z" /> <glyph unicode="&#xe920;" glyph-name="books" horiz-adv-x="1152" d="M224 832h-192c-17.6 0-32-14.4-32-32v-704c0-17.6 14.4-32 32-32h192c17.6 0 32 14.4 32 32v704c0 17.6-14.4 32-32 32zM192 640h-128v64h128v-64zM544 832h-192c-17.6 0-32-14.4-32-32v-704c0-17.6 14.4-32 32-32h192c17.6 0 32 14.4 32 32v704c0 17.6-14.4 32-32 32zM512 640h-128v64h128v-64zM765.088 782.52l-171.464-86.394c-15.716-7.918-22.096-27.258-14.178-42.976l287.978-571.548c7.918-15.718 27.258-22.098 42.976-14.178l171.464 86.392c15.716 7.92 22.096 27.26 14.178 42.974l-287.978 571.55c-7.92 15.718-27.26 22.1-42.976 14.18z" />
@@ -20,16 +25,37 @@
<glyph unicode="&#xe945;" glyph-name="envelop" d="M928 832h-832c-52.8 0-96-43.2-96-96v-640c0-52.8 43.2-96 96-96h832c52.8 0 96 43.2 96 96v640c0 52.8-43.2 96-96 96zM398.74 409.628l-270.74-210.892v501.642l270.74-290.75zM176.38 704h671.24l-335.62-252-335.62 252zM409.288 398.302l102.712-110.302 102.71 110.302 210.554-270.302h-626.528l210.552 270.302zM625.26 409.628l270.74 290.75v-501.642l-270.74 210.892z" /> <glyph unicode="&#xe945;" glyph-name="envelop" d="M928 832h-832c-52.8 0-96-43.2-96-96v-640c0-52.8 43.2-96 96-96h832c52.8 0 96 43.2 96 96v640c0 52.8-43.2 96-96 96zM398.74 409.628l-270.74-210.892v501.642l270.74-290.75zM176.38 704h671.24l-335.62-252-335.62 252zM409.288 398.302l102.712-110.302 102.71 110.302 210.554-270.302h-626.528l210.552 270.302zM625.26 409.628l270.74 290.75v-501.642l-270.74 210.892z" />
<glyph unicode="&#xe947;" glyph-name="location" d="M512 960c-176.732 0-320-143.268-320-320 0-320 320-704 320-704s320 384 320 704c0 176.732-143.27 320-320 320zM512 448c-106.040 0-192 85.96-192 192s85.96 192 192 192 192-85.96 192-192-85.96-192-192-192z" /> <glyph unicode="&#xe947;" glyph-name="location" d="M512 960c-176.732 0-320-143.268-320-320 0-320 320-704 320-704s320 384 320 704c0 176.732-143.27 320-320 320zM512 448c-106.040 0-192 85.96-192 192s85.96 192 192 192 192-85.96 192-192-85.96-192-192-192z" />
<glyph unicode="&#xe953;" glyph-name="calendar" d="M320 576h128v-128h-128zM512 576h128v-128h-128zM704 576h128v-128h-128zM128 192h128v-128h-128zM320 192h128v-128h-128zM512 192h128v-128h-128zM320 384h128v-128h-128zM512 384h128v-128h-128zM704 384h128v-128h-128zM128 384h128v-128h-128zM832 960v-64h-128v64h-448v-64h-128v64h-128v-1024h960v1024h-128zM896 0h-832v704h832v-704z" /> <glyph unicode="&#xe953;" glyph-name="calendar" d="M320 576h128v-128h-128zM512 576h128v-128h-128zM704 576h128v-128h-128zM128 192h128v-128h-128zM320 192h128v-128h-128zM512 192h128v-128h-128zM320 384h128v-128h-128zM512 384h128v-128h-128zM704 384h128v-128h-128zM128 384h128v-128h-128zM832 960v-64h-128v64h-448v-64h-128v64h-128v-1024h960v1024h-128zM896 0h-832v704h832v-704z" />
<glyph unicode="&#xe962;" glyph-name="floppy-disk" d="M896 960h-896v-1024h1024v896l-128 128zM512 832h128v-256h-128v256zM896 64h-768v768h64v-320h576v320h74.978l53.022-53.018v-714.982z" />
<glyph unicode="&#xe971;" glyph-name="user" d="M576 253.388v52.78c70.498 39.728 128 138.772 128 237.832 0 159.058 0 288-192 288s-192-128.942-192-288c0-99.060 57.502-198.104 128-237.832v-52.78c-217.102-17.748-384-124.42-384-253.388h896c0 128.968-166.898 235.64-384 253.388z" /> <glyph unicode="&#xe971;" glyph-name="user" d="M576 253.388v52.78c70.498 39.728 128 138.772 128 237.832 0 159.058 0 288-192 288s-192-128.942-192-288c0-99.060 57.502-198.104 128-237.832v-52.78c-217.102-17.748-384-124.42-384-253.388h896c0 128.968-166.898 235.64-384 253.388z" />
<glyph unicode="&#xe986;" glyph-name="search" d="M992.262 88.604l-242.552 206.294c-25.074 22.566-51.89 32.926-73.552 31.926 57.256 67.068 91.842 154.078 91.842 249.176 0 212.078-171.922 384-384 384-212.076 0-384-171.922-384-384s171.922-384 384-384c95.098 0 182.108 34.586 249.176 91.844-1-21.662 9.36-48.478 31.926-73.552l206.294-242.552c35.322-39.246 93.022-42.554 128.22-7.356s31.892 92.898-7.354 128.22zM384 320c-141.384 0-256 114.616-256 256s114.616 256 256 256 256-114.616 256-256-114.614-256-256-256z" /> <glyph unicode="&#xe986;" glyph-name="search" d="M992.262 88.604l-242.552 206.294c-25.074 22.566-51.89 32.926-73.552 31.926 57.256 67.068 91.842 154.078 91.842 249.176 0 212.078-171.922 384-384 384-212.076 0-384-171.922-384-384s171.922-384 384-384c95.098 0 182.108 34.586 249.176 91.844-1-21.662 9.36-48.478 31.926-73.552l206.294-242.552c35.322-39.246 93.022-42.554 128.22-7.356s31.892 92.898-7.354 128.22zM384 320c-141.384 0-256 114.616-256 256s114.616 256 256 256 256-114.616 256-256-114.614-256-256-256z" />
<glyph unicode="&#xe98f;" glyph-name="lock" d="M592 512h-16v192c0 105.87-86.13 192-192 192h-128c-105.87 0-192-86.13-192-192v-192h-16c-26.4 0-48-21.6-48-48v-480c0-26.4 21.6-48 48-48h544c26.4 0 48 21.6 48 48v480c0 26.4-21.6 48-48 48zM192 704c0 35.29 28.71 64 64 64h128c35.29 0 64-28.71 64-64v-192h-256v192z" />
<glyph unicode="&#xe990;" glyph-name="unlocked" d="M768 896c105.87 0 192-86.13 192-192v-192h-128v192c0 35.29-28.71 64-64 64h-128c-35.29 0-64-28.71-64-64v-192h16c26.4 0 48-21.6 48-48v-480c0-26.4-21.6-48-48-48h-544c-26.4 0-48 21.6-48 48v480c0 26.4 21.6 48 48 48h400v192c0 105.87 86.13 192 192 192h128z" />
<glyph unicode="&#xe992;" glyph-name="equalizer" d="M448 832v16c0 26.4-21.6 48-48 48h-160c-26.4 0-48-21.6-48-48v-16h-192v-128h192v-16c0-26.4 21.6-48 48-48h160c26.4 0 48 21.6 48 48v16h576v128h-576zM256 704v128h128v-128h-128zM832 528c0 26.4-21.6 48-48 48h-160c-26.4 0-48-21.6-48-48v-16h-576v-128h576v-16c0-26.4 21.6-48 48-48h160c26.4 0 48 21.6 48 48v16h192v128h-192v16zM640 384v128h128v-128h-128zM448 208c0 26.4-21.6 48-48 48h-160c-26.4 0-48-21.6-48-48v-16h-192v-128h192v-16c0-26.4 21.6-48 48-48h160c26.4 0 48 21.6 48 48v16h576v128h-576v16zM256 64v128h128v-128h-128z" />
<glyph unicode="&#xe994;" glyph-name="cog" d="M933.79 349.75c-53.726 93.054-21.416 212.304 72.152 266.488l-100.626 174.292c-28.75-16.854-62.176-26.518-97.846-26.518-107.536 0-194.708 87.746-194.708 195.99h-201.258c0.266-33.41-8.074-67.282-25.958-98.252-53.724-93.056-173.156-124.702-266.862-70.758l-100.624-174.292c28.97-16.472 54.050-40.588 71.886-71.478 53.638-92.908 21.512-211.92-71.708-266.224l100.626-174.292c28.65 16.696 61.916 26.254 97.4 26.254 107.196 0 194.144-87.192 194.7-194.958h201.254c-0.086 33.074 8.272 66.57 25.966 97.218 53.636 92.906 172.776 124.594 266.414 71.012l100.626 174.29c-28.78 16.466-53.692 40.498-71.434 71.228zM512 240.668c-114.508 0-207.336 92.824-207.336 207.334 0 114.508 92.826 207.334 207.336 207.334 114.508 0 207.332-92.826 207.332-207.334-0.002-114.51-92.824-207.334-207.332-207.334z" /> <glyph unicode="&#xe994;" glyph-name="cog" d="M933.79 349.75c-53.726 93.054-21.416 212.304 72.152 266.488l-100.626 174.292c-28.75-16.854-62.176-26.518-97.846-26.518-107.536 0-194.708 87.746-194.708 195.99h-201.258c0.266-33.41-8.074-67.282-25.958-98.252-53.724-93.056-173.156-124.702-266.862-70.758l-100.624-174.292c28.97-16.472 54.050-40.588 71.886-71.478 53.638-92.908 21.512-211.92-71.708-266.224l100.626-174.292c28.65 16.696 61.916 26.254 97.4 26.254 107.196 0 194.144-87.192 194.7-194.958h201.254c-0.086 33.074 8.272 66.57 25.966 97.218 53.636 92.906 172.776 124.594 266.414 71.012l100.626 174.29c-28.78 16.466-53.692 40.498-71.434 71.228zM512 240.668c-114.508 0-207.336 92.824-207.336 207.334 0 114.508 92.826 207.334 207.336 207.334 114.508 0 207.332-92.826 207.332-207.334-0.002-114.51-92.824-207.334-207.332-207.334z" />
<glyph unicode="&#xe997;" glyph-name="magic-wand" d="M256 768l-128 128h-64v-64l128-128zM320 960h64v-128h-64zM576 640h128v-64h-128zM640 832v64h-64l-128-128 64-64zM0 640h128v-64h-128zM320 384h64v-128h-64zM64 384v-64h64l128 128-64 64zM1010 78l-636.118 636.118c-18.668 18.668-49.214 18.668-67.882 0l-60.118-60.118c-18.668-18.668-18.668-49.214 0-67.882l636.118-636.118c18.668-18.668 49.214-18.668 67.882 0l60.118 60.118c18.668 18.668 18.668 49.214 0 67.882zM480 416l-192 192 64 64 192-192-64-64z" />
<glyph unicode="&#xe99e;" glyph-name="trophy" d="M832 768v128h-640v-128h-192v-128c0-106.038 85.958-192 192-192 20.076 0 39.43 3.086 57.62 8.802 46.174-66.008 116.608-113.796 198.38-130.396v-198.406h-64c-70.694 0-128-57.306-128-128h512c0 70.694-57.306 128-128 128h-64v198.406c81.772 16.6 152.206 64.386 198.38 130.396 18.19-5.716 37.544-8.802 57.62-8.802 106.042 0 192 85.962 192 192v128h-192zM192 524c-63.962 0-116 52.038-116 116v64h116v-64c0-40.186 7.43-78.632 20.954-114.068-6.802-1.246-13.798-1.932-20.954-1.932zM948 640c0-63.962-52.038-116-116-116-7.156 0-14.152 0.686-20.954 1.932 13.524 35.436 20.954 73.882 20.954 114.068v64h116v-64z" />
<glyph unicode="&#xe99f;" glyph-name="gift" d="M771.516 640c18.126 12.88 35.512 27.216 51.444 43.148 33.402 33.402 55.746 74.5 62.912 115.722 7.858 45.186-3.672 87.14-31.63 115.1-22.3 22.298-52.51 34.086-87.364 34.086-49.632 0-101.922-23.824-143.46-65.362-66.476-66.476-105.226-158.238-126.076-223.722-15.44 65.802-46.206 154.644-106.018 214.458-32.094 32.092-73.114 48.57-111.846 48.57-31.654 0-61.78-11.004-84.26-33.486-49.986-49.988-43.232-137.786 15.086-196.104 20.792-20.792 45.098-38.062 70.72-52.412h-217.024v-256h64v-448h768v448.002h64v256h-188.484zM674.326 831.782c27.724 27.724 62.322 44.274 92.55 44.274 10.7 0 25.708-2.254 36.45-12.998 26.030-26.028 11.412-86.308-31.28-128.998-43.946-43.946-103.060-74.168-154.432-94.060h-50.672c18.568 57.548 52.058 136.456 107.384 191.782zM233.934 799.11c-0.702 9.12-0.050 26.248 12.196 38.494 10.244 10.244 23.788 12.396 33.348 12.396v0c21.258 0 43.468-10.016 60.932-27.48 33.872-33.872 61.766-87.772 80.668-155.876 0.51-1.84 1.008-3.67 1.496-5.486-1.816 0.486-3.646 0.984-5.486 1.496-68.104 18.904-122.002 46.798-155.874 80.67-15.828 15.826-25.77 36.16-27.28 55.786zM448 0h-256v416h256v-416zM448 448h-320v128h320v-128zM832 0h-256v416h256v-416zM896 448h-320v128h320v-128z" />
<glyph unicode="&#xe9a5;" glyph-name="rocket" d="M704 896l-320-320h-192l-192-256c0 0 203.416 56.652 322.066 30.084l-322.066-414.084 421.902 328.144c58.838-134.654-37.902-328.144-37.902-328.144l256 192v192l320 320 64 320-320-64z" />
<glyph unicode="&#xe9a9;" glyph-name="fire" d="M321.008-64c-68.246 142.008-31.902 223.378 20.55 300.044 57.44 83.956 72.244 167.066 72.244 167.066s45.154-58.7 27.092-150.508c79.772 88.8 94.824 230.28 82.782 284.464 180.314-126.012 257.376-398.856 153.522-601.066 552.372 312.532 137.398 780.172 65.154 832.85 24.082-52.676 28.648-141.85-20-185.126-82.352 312.276-285.972 376.276-285.972 376.276 24.082-161.044-87.296-337.144-194.696-468.73-3.774 64.216-7.782 108.528-41.55 169.98-7.58-116.656-96.732-211.748-120.874-328.628-32.702-158.286 24.496-274.18 241.748-396.622z" /> <glyph unicode="&#xe9a9;" glyph-name="fire" d="M321.008-64c-68.246 142.008-31.902 223.378 20.55 300.044 57.44 83.956 72.244 167.066 72.244 167.066s45.154-58.7 27.092-150.508c79.772 88.8 94.824 230.28 82.782 284.464 180.314-126.012 257.376-398.856 153.522-601.066 552.372 312.532 137.398 780.172 65.154 832.85 24.082-52.676 28.648-141.85-20-185.126-82.352 312.276-285.972 376.276-285.972 376.276 24.082-161.044-87.296-337.144-194.696-468.73-3.774 64.216-7.782 108.528-41.55 169.98-7.58-116.656-96.732-211.748-120.874-328.628-32.702-158.286 24.496-274.18 241.748-396.622z" />
<glyph unicode="&#xe9aa;" glyph-name="lab" d="M956.29 155.518l-316.29 527.024v213.458h32c17.6 0 32 14.4 32 32s-14.4 32-32 32h-320c-17.6 0-32-14.4-32-32s14.4-32 32-32h32v-213.458l-316.288-527.024c-72.442-120.734-16.512-219.518 124.288-219.518h640c140.8 0 196.73 98.784 124.29 219.518zM241.038 320l206.962 344.938v231.062h128v-231.062l206.964-344.938h-541.926z" /> <glyph unicode="&#xe9aa;" glyph-name="lab" d="M956.29 155.518l-316.29 527.024v213.458h32c17.6 0 32 14.4 32 32s-14.4 32-32 32h-320c-17.6 0-32-14.4-32-32s14.4-32 32-32h32v-213.458l-316.288-527.024c-72.442-120.734-16.512-219.518 124.288-219.518h640c140.8 0 196.73 98.784 124.29 219.518zM241.038 320l206.962 344.938v231.062h128v-231.062l206.964-344.938h-541.926z" />
<glyph unicode="&#xe9ac;" glyph-name="bin" d="M128 640v-640c0-35.2 28.8-64 64-64h576c35.2 0 64 28.8 64 64v640h-704zM320 64h-64v448h64v-448zM448 64h-64v448h64v-448zM576 64h-64v448h64v-448zM704 64h-64v448h64v-448zM848 832h-208v80c0 26.4-21.6 48-48 48h-224c-26.4 0-48-21.6-48-48v-80h-208c-26.4 0-48-21.6-48-48v-80h832v80c0 26.4-21.6 48-48 48zM576 832h-192v63.198h192v-63.198z" /> <glyph unicode="&#xe9ac;" glyph-name="bin" d="M128 640v-640c0-35.2 28.8-64 64-64h576c35.2 0 64 28.8 64 64v640h-704zM320 64h-64v448h64v-448zM448 64h-64v448h64v-448zM576 64h-64v448h64v-448zM704 64h-64v448h64v-448zM848 832h-208v80c0 26.4-21.6 48-48 48h-224c-26.4 0-48-21.6-48-48v-80h-208c-26.4 0-48-21.6-48-48v-80h832v80c0 26.4-21.6 48-48 48zM576 832h-192v63.198h192v-63.198z" />
<glyph unicode="&#xe9ae;" glyph-name="briefcase" d="M960 704h-256v64c0 35.2-28.8 64-64 64h-256c-35.204 0-64-28.8-64-64v-64h-256c-35.2 0-64-28.8-64-64v-576c0-35.202 28.796-64 64-64h896c35.2 0 64 28.798 64 64v576c0 35.2-28.8 64-64 64zM384 767.884c0.034 0.040 0.074 0.082 0.114 0.116h255.772c0.042-0.034 0.082-0.076 0.118-0.116v-63.884h-256.004v63.884zM960 448h-128v-96c0-17.602-14.4-32-32-32h-64c-17.604 0-32 14.398-32 32v96h-384v-96c0-17.602-14.4-32-32-32h-64c-17.602 0-32 14.398-32 32v96h-128v64h896v-64z" /> <glyph unicode="&#xe9ae;" glyph-name="briefcase" d="M960 704h-256v64c0 35.2-28.8 64-64 64h-256c-35.204 0-64-28.8-64-64v-64h-256c-35.2 0-64-28.8-64-64v-576c0-35.202 28.796-64 64-64h896c35.2 0 64 28.798 64 64v576c0 35.2-28.8 64-64 64zM384 767.884c0.034 0.040 0.074 0.082 0.114 0.116h255.772c0.042-0.034 0.082-0.076 0.118-0.116v-63.884h-256.004v63.884zM960 448h-128v-96c0-17.602-14.4-32-32-32h-64c-17.604 0-32 14.398-32 32v96h-384v-96c0-17.602-14.4-32-32-32h-64c-17.602 0-32 14.398-32 32v96h-128v64h896v-64z" />
<glyph unicode="&#xe9b0;" glyph-name="truck" d="M1024 384l-128 256h-192v128c0 35.2-28.8 64-64 64h-576c-35.2 0-64-28.8-64-64v-512l64-64h81.166c-10.898-18.832-17.166-40.678-17.166-64 0-70.692 57.308-128 128-128s128 57.308 128 128c0 23.322-6.268 45.168-17.166 64h354.334c-10.898-18.832-17.168-40.678-17.168-64 0-70.692 57.308-128 128-128s128 57.308 128 128c0 23.322-6.27 45.168-17.168 64h81.168v192zM704 384v192h132.668l96-192h-228.668z" /> <glyph unicode="&#xe9b0;" glyph-name="truck" d="M1024 384l-128 256h-192v128c0 35.2-28.8 64-64 64h-576c-35.2 0-64-28.8-64-64v-512l64-64h81.166c-10.898-18.832-17.166-40.678-17.166-64 0-70.692 57.308-128 128-128s128 57.308 128 128c0 23.322-6.268 45.168-17.166 64h354.334c-10.898-18.832-17.168-40.678-17.168-64 0-70.692 57.308-128 128-128s128 57.308 128 128c0 23.322-6.27 45.168-17.168 64h81.168v192zM704 384v192h132.668l96-192h-228.668z" />
<glyph unicode="&#xe9b5;" glyph-name="power" d="M384 960l-384-512h384l-256-512 896 640h-512l384 384z" />
<glyph unicode="&#xe9b6;" glyph-name="switch" d="M640 813.412v-135.958c36.206-15.804 69.5-38.408 98.274-67.18 60.442-60.44 93.726-140.8 93.726-226.274s-33.286-165.834-93.726-226.274c-60.44-60.44-140.798-93.726-226.274-93.726s-165.834 33.286-226.274 93.726c-60.44 60.44-93.726 140.8-93.726 226.274s33.286 165.834 93.726 226.274c28.774 28.774 62.068 51.378 98.274 67.182v135.956c-185.048-55.080-320-226.472-320-429.412 0-247.424 200.578-448 448-448 247.424 0 448 200.576 448 448 0 202.94-134.95 374.332-320 429.412zM448 960h128v-512h-128z" />
<glyph unicode="&#xe9ca;" glyph-name="earth" d="M512 960c-282.77 0-512-229.23-512-512s229.23-512 512-512 512 229.23 512 512-229.23 512-512 512zM512-0.002c-62.958 0-122.872 13.012-177.23 36.452l233.148 262.29c5.206 5.858 8.082 13.422 8.082 21.26v96c0 17.674-14.326 32-32 32-112.99 0-232.204 117.462-233.374 118.626-6 6.002-14.14 9.374-22.626 9.374h-128c-17.672 0-32-14.328-32-32v-192c0-12.122 6.848-23.202 17.69-28.622l110.31-55.156v-187.886c-116.052 80.956-192 215.432-192 367.664 0 68.714 15.49 133.806 43.138 192h116.862c8.488 0 16.626 3.372 22.628 9.372l128 128c6 6.002 9.372 14.14 9.372 22.628v77.412c40.562 12.074 83.518 18.588 128 18.588 70.406 0 137.004-16.26 196.282-45.2-4.144-3.502-8.176-7.164-12.046-11.036-36.266-36.264-56.236-84.478-56.236-135.764s19.97-99.5 56.236-135.764c36.434-36.432 85.218-56.264 135.634-56.26 3.166 0 6.342 0.080 9.518 0.236 13.814-51.802 38.752-186.656-8.404-372.334-0.444-1.744-0.696-3.488-0.842-5.224-81.324-83.080-194.7-134.656-320.142-134.656z" /> <glyph unicode="&#xe9ca;" glyph-name="earth" d="M512 960c-282.77 0-512-229.23-512-512s229.23-512 512-512 512 229.23 512 512-229.23 512-512 512zM512-0.002c-62.958 0-122.872 13.012-177.23 36.452l233.148 262.29c5.206 5.858 8.082 13.422 8.082 21.26v96c0 17.674-14.326 32-32 32-112.99 0-232.204 117.462-233.374 118.626-6 6.002-14.14 9.374-22.626 9.374h-128c-17.672 0-32-14.328-32-32v-192c0-12.122 6.848-23.202 17.69-28.622l110.31-55.156v-187.886c-116.052 80.956-192 215.432-192 367.664 0 68.714 15.49 133.806 43.138 192h116.862c8.488 0 16.626 3.372 22.628 9.372l128 128c6 6.002 9.372 14.14 9.372 22.628v77.412c40.562 12.074 83.518 18.588 128 18.588 70.406 0 137.004-16.26 196.282-45.2-4.144-3.502-8.176-7.164-12.046-11.036-36.266-36.264-56.236-84.478-56.236-135.764s19.97-99.5 56.236-135.764c36.434-36.432 85.218-56.264 135.634-56.26 3.166 0 6.342 0.080 9.518 0.236 13.814-51.802 38.752-186.656-8.404-372.334-0.444-1.744-0.696-3.488-0.842-5.224-81.324-83.080-194.7-134.656-320.142-134.656z" />
<glyph unicode="&#xe9cb;" glyph-name="link" d="M440.236 324.234c-13.31 0-26.616 5.076-36.77 15.23-95.134 95.136-95.134 249.934 0 345.070l192 192c46.088 46.086 107.36 71.466 172.534 71.466s126.448-25.38 172.536-71.464c95.132-95.136 95.132-249.934 0-345.070l-87.766-87.766c-20.308-20.308-53.23-20.308-73.54 0-20.306 20.306-20.306 53.232 0 73.54l87.766 87.766c54.584 54.586 54.584 143.404 0 197.99-26.442 26.442-61.6 41.004-98.996 41.004s-72.552-14.562-98.996-41.006l-192-191.998c-54.586-54.586-54.586-143.406 0-197.992 20.308-20.306 20.306-53.232 0-73.54-10.15-10.152-23.462-15.23-36.768-15.23zM256-52c-65.176 0-126.45 25.38-172.534 71.464-95.134 95.136-95.134 249.934 0 345.070l87.764 87.764c20.308 20.306 53.234 20.306 73.54 0 20.308-20.306 20.308-53.232 0-73.54l-87.764-87.764c-54.586-54.586-54.586-143.406 0-197.992 26.44-26.44 61.598-41.002 98.994-41.002s72.552 14.562 98.998 41.006l192 191.998c54.584 54.586 54.584 143.406 0 197.992-20.308 20.308-20.306 53.232 0 73.54 20.306 20.306 53.232 20.306 73.54-0.002 95.132-95.134 95.132-249.932 0.002-345.068l-192.002-192c-46.090-46.088-107.364-71.466-172.538-71.466z" /> <glyph unicode="&#xe9cb;" glyph-name="link" d="M440.236 324.234c-13.31 0-26.616 5.076-36.77 15.23-95.134 95.136-95.134 249.934 0 345.070l192 192c46.088 46.086 107.36 71.466 172.534 71.466s126.448-25.38 172.536-71.464c95.132-95.136 95.132-249.934 0-345.070l-87.766-87.766c-20.308-20.308-53.23-20.308-73.54 0-20.306 20.306-20.306 53.232 0 73.54l87.766 87.766c54.584 54.586 54.584 143.404 0 197.99-26.442 26.442-61.6 41.004-98.996 41.004s-72.552-14.562-98.996-41.006l-192-191.998c-54.586-54.586-54.586-143.406 0-197.992 20.308-20.306 20.306-53.232 0-73.54-10.15-10.152-23.462-15.23-36.768-15.23zM256-52c-65.176 0-126.45 25.38-172.534 71.464-95.134 95.136-95.134 249.934 0 345.070l87.764 87.764c20.308 20.306 53.234 20.306 73.54 0 20.308-20.306 20.308-53.232 0-73.54l-87.764-87.764c-54.586-54.586-54.586-143.406 0-197.992 26.44-26.44 61.598-41.002 98.994-41.002s72.552 14.562 98.998 41.006l192 191.998c54.584 54.586 54.584 143.406 0 197.992-20.308 20.308-20.306 53.232 0 73.54 20.306 20.306 53.232 20.306 73.54-0.002 95.132-95.134 95.132-249.932 0.002-345.068l-192.002-192c-46.090-46.088-107.364-71.466-172.538-71.466z" />
<glyph unicode="&#xe9ce;" glyph-name="eye" d="M512 768c-223.318 0-416.882-130.042-512-320 95.118-189.958 288.682-320 512-320 223.312 0 416.876 130.042 512 320-95.116 189.958-288.688 320-512 320zM764.45 598.296c60.162-38.374 111.142-89.774 149.434-150.296-38.292-60.522-89.274-111.922-149.436-150.296-75.594-48.218-162.89-73.704-252.448-73.704-89.56 0-176.858 25.486-252.452 73.704-60.158 38.372-111.138 89.772-149.432 150.296 38.292 60.524 89.274 111.924 149.434 150.296 3.918 2.5 7.876 4.922 11.86 7.3-9.96-27.328-15.41-56.822-15.41-87.596 0-141.382 114.616-256 256-256 141.382 0 256 114.618 256 256 0 30.774-5.452 60.268-15.408 87.598 3.978-2.378 7.938-4.802 11.858-7.302v0zM512 544c0-53.020-42.98-96-96-96s-96 42.98-96 96 42.98 96 96 96 96-42.982 96-96z" />
<glyph unicode="&#xe9d7;" glyph-name="star-empty" d="M1024 562.95l-353.78 51.408-158.22 320.582-158.216-320.582-353.784-51.408 256-249.538-60.432-352.352 316.432 166.358 316.432-166.358-60.434 352.352 256.002 249.538zM512 206.502l-223.462-117.48 42.676 248.83-180.786 176.222 249.84 36.304 111.732 226.396 111.736-226.396 249.836-36.304-180.788-176.222 42.678-248.83-223.462 117.48z" />
<glyph unicode="&#xe9d9;" glyph-name="star-full" d="M1024 562.95l-353.78 51.408-158.22 320.582-158.216-320.582-353.784-51.408 256-249.538-60.432-352.352 316.432 166.358 316.432-166.358-60.434 352.352 256.002 249.538z" />
<glyph unicode="&#xe9da;" glyph-name="heart" d="M755.188 896c-107.63 0-200.258-87.554-243.164-179-42.938 91.444-135.578 179-243.216 179-148.382 0-268.808-120.44-268.808-268.832 0-301.846 304.5-380.994 512.022-679.418 196.154 296.576 511.978 387.206 511.978 679.418 0 148.392-120.43 268.832-268.812 268.832z" /> <glyph unicode="&#xe9da;" glyph-name="heart" d="M755.188 896c-107.63 0-200.258-87.554-243.164-179-42.938 91.444-135.578 179-243.216 179-148.382 0-268.808-120.44-268.808-268.832 0-301.846 304.5-380.994 512.022-679.418 196.154 296.576 511.978 387.206 511.978 679.418 0 148.392-120.43 268.832-268.812 268.832z" />
<glyph unicode="&#xea07;" glyph-name="warning" d="M512 867.226l429.102-855.226h-858.206l429.104 855.226zM512 960c-22.070 0-44.14-14.882-60.884-44.648l-437.074-871.112c-33.486-59.532-5-108.24 63.304-108.24h869.308c68.3 0 96.792 48.708 63.3 108.24h0.002l-437.074 871.112c-16.742 29.766-38.812 44.648-60.882 44.648v0zM576 128c0-35.346-28.654-64-64-64s-64 28.654-64 64c0 35.346 28.654 64 64 64s64-28.654 64-64zM512 256c-35.346 0-64 28.654-64 64v192c0 35.346 28.654 64 64 64s64-28.654 64-64v-192c0-35.346-28.654-64-64-64z" />
<glyph unicode="&#xea08;" glyph-name="notification" d="M512 864c-111.118 0-215.584-43.272-294.156-121.844s-121.844-183.038-121.844-294.156c0-111.118 43.272-215.584 121.844-294.156s183.038-121.844 294.156-121.844c111.118 0 215.584 43.272 294.156 121.844s121.844 183.038 121.844 294.156c0 111.118-43.272 215.584-121.844 294.156s-183.038 121.844-294.156 121.844zM512 960v0c282.77 0 512-229.23 512-512s-229.23-512-512-512c-282.77 0-512 229.23-512 512s229.23 512 512 512zM448 256h128v-128h-128zM448 768h128v-384h-128z" />
<glyph unicode="&#xea09;" glyph-name="question" d="M448 256h128v-128h-128zM704 704c35.346 0 64-28.654 64-64v-192l-192-128h-128v64l192 128v64h-320v128h384zM512 864c-111.118 0-215.584-43.272-294.156-121.844s-121.844-183.038-121.844-294.156c0-111.118 43.272-215.584 121.844-294.156s183.038-121.844 294.156-121.844c111.118 0 215.584 43.272 294.156 121.844s121.844 183.038 121.844 294.156c0 111.118-43.272 215.584-121.844 294.156s-183.038 121.844-294.156 121.844zM512 960v0c282.77 0 512-229.23 512-512s-229.23-512-512-512c-282.77 0-512 229.23-512 512s229.23 512 512 512z" />
<glyph unicode="&#xea0d;" glyph-name="cancel-circle" d="M512 960c-282.77 0-512-229.23-512-512s229.23-512 512-512 512 229.23 512 512-229.23 512-512 512zM512 32c-229.75 0-416 186.25-416 416s186.25 416 416 416 416-186.25 416-416-186.25-416-416-416zM672 704l-160-160-160 160-96-96 160-160-160-160 96-96 160 160 160-160 96 96-160 160 160 160z" />
<glyph unicode="&#xea41;" glyph-name="circle-up" d="M0 448c0-282.77 229.23-512 512-512s512 229.23 512 512-229.23 512-512 512-512-229.23-512-512zM928 448c0-229.75-186.25-416-416-416s-416 186.25-416 416 186.25 416 416 416 416-186.25 416-416zM706.744 290.744l90.512 90.512-285.256 285.254-285.254-285.256 90.508-90.508 194.746 194.744z" />
<glyph unicode="&#xea42;" glyph-name="circle-right" d="M512 960c-282.77 0-512-229.23-512-512s229.23-512 512-512 512 229.23 512 512-229.23 512-512 512zM512 32c-229.75 0-416 186.25-416 416s186.25 416 416 416 416-186.25 416-416-186.25-416-416-416zM354.744 253.256l90.512-90.512 285.254 285.256-285.256 285.254-90.508-90.508 194.744-194.746z" />
<glyph unicode="&#xea43;" glyph-name="circle-down" d="M1024 448c0 282.77-229.23 512-512 512s-512-229.23-512-512 229.23-512 512-512 512 229.23 512 512zM96 448c0 229.75 186.25 416 416 416s416-186.25 416-416-186.25-416-416-416-416 186.25-416 416zM317.256 605.256l-90.512-90.512 285.256-285.254 285.254 285.256-90.508 90.508-194.746-194.744z" />
<glyph unicode="&#xea44;" glyph-name="circle-left" d="M512-64c282.77 0 512 229.23 512 512s-229.23 512-512 512-512-229.23-512-512 229.23-512 512-512zM512 864c229.75 0 416-186.25 416-416s-186.25-416-416-416-416 186.25-416 416 186.25 416 416 416zM669.256 642.744l-90.512 90.512-285.254-285.256 285.256-285.254 90.508 90.508-194.744 194.746z" />
<glyph unicode="&#xea7e;" glyph-name="new-tab" d="M192 896v-768h768v768h-768zM896 192h-640v640h640v-640zM128 64v672l-64 64v-800h800l-64 64h-672zM352 704l160-160-192-192 96-96 192 192 160-160v416z" /> <glyph unicode="&#xea7e;" glyph-name="new-tab" d="M192 896v-768h768v768h-768zM896 192h-640v640h640v-640zM128 64v672l-64 64v-800h800l-64 64h-672zM352 704l160-160-192-192 96-96 192 192 160-160v416z" />
</font></defs></svg> </font></defs></svg>

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 32 KiB

Binary file not shown.
Binary file not shown.
+83 -30
View File
@@ -1,10 +1,10 @@
@font-face { @font-face {
font-family: 'icomoon'; font-family: 'icomoon';
src: url('fonts/icomoon.eot?4ozr25'); src: url('fonts/icomoon.eot?eqbps9');
src: url('fonts/icomoon.eot?4ozr25#iefix') format('embedded-opentype'), src: url('fonts/icomoon.eot?eqbps9#iefix') format('embedded-opentype'),
url('fonts/icomoon.ttf?4ozr25') format('truetype'), url('fonts/icomoon.ttf?eqbps9') format('truetype'),
url('fonts/icomoon.woff?4ozr25') format('woff'), url('fonts/icomoon.woff?eqbps9') format('woff'),
url('fonts/icomoon.svg?4ozr25#icomoon') format('svg'); url('fonts/icomoon.svg?eqbps9#icomoon') format('svg');
font-weight: normal; font-weight: normal;
font-style: normal; font-style: normal;
font-display: block; font-display: block;
@@ -14,7 +14,6 @@
[class*=" icon-"] { [class*=" icon-"] {
/* use !important to prevent issues with browser extensions that change fonts */ /* use !important to prevent issues with browser extensions that change fonts */
font-family: 'icomoon' !important; font-family: 'icomoon' !important;
speak: never;
font-style: normal; font-style: normal;
font-weight: normal; font-weight: normal;
font-variant: normal; font-variant: normal;
@@ -26,102 +25,156 @@
-moz-osx-font-smoothing: grayscale; -moz-osx-font-smoothing: grayscale;
} }
.icon-close:before {
content: "\e901";
}
.icon-home:before { .icon-home:before {
content: "\e900"; content: "\e900";
} }
.icon-pencil:before { .icon-pencil:before {
content: "\e905"; content: "\e905";
} }
.icon-image:before { .icon-image:before {
content: "\e90d"; content: "\e90d";
} }
.icon-bullhorn:before { .icon-bullhorn:before {
content: "\e91a"; content: "\e91a";
} }
.icon-books:before { .icon-books:before {
content: "\e920"; content: "\e920";
} }
.icon-library:before { .icon-library:before {
content: "\e921"; content: "\e921";
} }
.icon-barcode:before { .icon-barcode:before {
content: "\e937"; content: "\e937";
} }
.icon-cart:before { .icon-cart:before {
content: "\e93a"; content: "\e93a";
} }
.icon-credit-card:before { .icon-credit-card:before {
content: "\e93f"; content: "\e93f";
} }
.icon-phone:before { .icon-phone:before {
content: "\e942"; content: "\e942";
} }
.icon-envelop:before { .icon-envelop:before {
content: "\e945"; content: "\e945";
} }
.icon-location:before { .icon-location:before {
content: "\e947"; content: "\e947";
} }
.icon-calendar:before { .icon-calendar:before {
content: "\e953"; content: "\e953";
} }
.icon-floppy-disk:before {
content: "\e962";
}
.icon-user:before { .icon-user:before {
content: "\e971"; content: "\e971";
} }
.icon-search:before { .icon-search:before {
content: "\e986"; content: "\e986";
} }
.icon-lock:before {
content: "\e98f";
}
.icon-unlocked:before {
content: "\e990";
}
.icon-equalizer:before {
content: "\e992";
}
.icon-cog:before { .icon-cog:before {
content: "\e994"; content: "\e994";
} }
.icon-magic-wand:before {
content: "\e997";
}
.icon-trophy:before {
content: "\e99e";
}
.icon-gift:before {
content: "\e99f";
}
.icon-rocket:before {
content: "\e9a5";
}
.icon-fire:before { .icon-fire:before {
content: "\e9a9"; content: "\e9a9";
} }
.icon-lab:before { .icon-lab:before {
content: "\e9aa"; content: "\e9aa";
} }
.icon-bin:before { .icon-bin:before {
content: "\e9ac"; content: "\e9ac";
} }
.icon-briefcase:before { .icon-briefcase:before {
content: "\e9ae"; content: "\e9ae";
} }
.icon-truck:before { .icon-truck:before {
content: "\e9b0"; content: "\e9b0";
} }
.icon-power:before {
content: "\e9b5";
}
.icon-switch:before {
content: "\e9b6";
}
.icon-earth:before { .icon-earth:before {
content: "\e9ca"; content: "\e9ca";
} }
.icon-link:before { .icon-link:before {
content: "\e9cb"; content: "\e9cb";
} }
.icon-eye:before {
content: "\e9ce";
}
.icon-star-empty:before {
content: "\e9d7";
}
.icon-star-full:before {
content: "\e9d9";
}
.icon-heart:before { .icon-heart:before {
content: "\e9da"; content: "\e9da";
} }
.icon-warning:before {
content: "\ea07";
}
.icon-notification:before {
content: "\ea08";
}
.icon-question:before {
content: "\ea09";
}
.icon-cancel-circle:before {
content: "\ea0d";
}
.icon-circle-up:before {
content: "\ea41";
}
.icon-circle-right:before {
content: "\ea42";
}
.icon-circle-down:before {
content: "\ea43";
}
.icon-circle-left:before {
content: "\ea44";
}
.icon-new-tab:before { .icon-new-tab:before {
content: "\ea7e"; content: "\ea7e";
} }
.icon-hash:before {
content: "\e902";
}
.icon-molecule:before {
content: "\e903";
}
.icon-marijuana:before {
content: "\e904";
}
.icon-cannabis:before {
content: "\e906";
}
+39 -11
View File
@@ -2,7 +2,8 @@ $success: #7952b3;
@import "bootstrap/scss/bootstrap.scss"; @import "bootstrap/scss/bootstrap.scss";
$dark-blue: #141d5e; /*#171f50;*/ $dark-blue: #141d5e;
/*#171f50;*/
$dark-grey: #222222; $dark-grey: #222222;
$gold: #d7c067; $gold: #d7c067;
$orange: #ff8300; $orange: #ff8300;
@@ -21,16 +22,16 @@ body {
.bg-darker { .bg-darker {
background-color: $dark-grey !important; background-color: $dark-grey !important;
} }
.bg-dark-blue {
.bg-blue-gold {
--bs-bg-opacity: 1; --bs-bg-opacity: 1;
--dark-blue: 20, 29, 94; --dark-blue: 20, 29, 94;
background-color: rgba(var(--dark-blue), var(--bs-bg-opacity)) !important; background-color: rgba(var(--dark-blue), var(--bs-bg-opacity)) !important;
h5 { color: var(--bs-gray-400) !important;
&.gold h5 {
color: $gold; color: $gold;
} }
a { a {
color: var(--bs-secondary-color) !important; color: var(--bs-gray-400) !important;
} }
} }
@@ -45,27 +46,31 @@ body {
height: 100px; height: 100px;
.divider { .divider {
width: 2px; width: 2px;
background-color: $time-grey; background-color: var(--bs-gray-400);
height: 60px; height: 60px;
top: 20px; top: 20px;
left: calc(50% - 1px); left: calc(50% - 1px);
} }
} }
.datelib { .datelib {
color: $time-grey; color: $dark-blue;
border-bottom: 1px solid $time-grey; border-bottom: 1px solid $dark-blue;
width: 328px; width: 328px;
opacity: 0.8;
} }
.block { .block {
width: 24px; width: 24px;
color: $time-grey-dark; color: var(--bs-gray-400);
transition: 0.4s; transition: 0.4s;
&.active:before { &.active:before {
color: $time-grey; color: $dark-blue;
font-weight: 500; font-weight: 500;
opacity: 0.8;
} }
&.second:before { &.second:before {
color: $gold; color: $orange;
} }
&:not(:nth-child(n + 16)):nth-child(n + 11), &:not(:nth-child(n + 16)):nth-child(n + 11),
&:not(:nth-child(n + 46)):nth-child(n + 41) { &:not(:nth-child(n + 46)):nth-child(n + 41) {
@@ -88,3 +93,26 @@ body {
content: "0" attr(data-num); content: "0" attr(data-num);
} }
} }
[data-bs-theme=dark] {
.clock {
.divider {
background-color: $time-grey;
}
}
.datelib {
color: $time-grey;
border-bottom: 1px solid $time-grey;
opacity: 0.5;
}
.block {
color: $time-grey-dark;
&.active:before {
color: $time-grey;
opacity: 1;
}
&.second:before {
color: $gold;
}
}
}