fork refine

This commit is contained in:
Stefan Pejcic
2024-02-05 10:23:04 +01:00
parent 3fffde9a8f
commit 8496a83edb
3634 changed files with 715528 additions and 2 deletions

View File

@@ -0,0 +1,113 @@
import React from "react";
import clsx from "clsx";
import Link from "@docusaurus/Link";
import { useBlogPost } from "@docusaurus/theme-common/internal";
import { Github, Twitter, Linkedin } from "../icons";
export const AuthorCardWithHook = ({ className }) => {
const { metadata } = useBlogPost();
const author = metadata.authors[0];
return <AuthorCard author={author} className={className} />;
};
export const AuthorCardWithProps = ({ author, className }) => {
return <AuthorCard author={author} className={className} />;
};
const AuthorCard = ({ author }) => {
const authorHasSocialInfo =
author.github || author.twitter || author.linkedin;
return (
<div
className={clsx(
"px-4",
"blog-md:px-7",
"blog-2xl:px-0",
"max-w-[640px]",
"blog-md:max-w-screen-blog-md",
"blog-2xl:max-w-screen-blog-md",
"w-full",
"mx-auto",
)}
>
<div className={clsx("flex", "justify-between", "items-center")}>
<div
className={clsx(
"w-full",
"flex items-center justify-between flex-wrap",
)}
>
<div
className={clsx("flex items-center", "gap-2 sm:gap-6")}
>
<Link
to={`/blog/author/${author?.key}`}
itemProp="url"
className="flex-shrink-0"
>
<img
src={author?.imageURL}
alt={author?.name}
loading="lazy"
className={clsx(
"flex flex-shrink-0",
"h-12 w-12",
"blog-sm:h-[88px] blog-sm:w-[88px]",
"blog-md:h-[120px] blog-md:w-[120px]",
"rounded-full object-cover",
)}
/>
</Link>
<div
className={clsx(
"not-prose flex flex-col justify-between",
)}
>
<h1
className={clsx(
"text-xl sm:text-[40px] sm:leading-[56px]",
"m-0 p-0 pb-2 font-bold text-gray-900 dark:text-gray-200",
)}
>
{author?.name}
</h1>
<div
className={clsx(
"text-xs sm:text-base",
"text-gray-600 dark:text-gray-400",
)}
>
{author?.title}
</div>
</div>
</div>
{authorHasSocialInfo && (
<div className="flex justify-center gap-3">
{author?.github && (
<Link to={author?.github}>
<Github className="h-6 w-6" />
</Link>
)}
{author?.twitter && (
<Link to={author?.twitter}>
<Twitter className="h-6 w-6" />
</Link>
)}
{author?.linkedin && (
<Link to={author?.linkedin}>
<Linkedin className="h-6 w-6" />
</Link>
)}
</div>
)}
</div>
</div>
<div className="border-b border-gray-200 dark:border-gray-700 mb-8" />
</div>
);
};

View File

@@ -0,0 +1,60 @@
import React from "react";
import BlogLayout from "@theme/BlogLayout";
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
import { PageMetadata } from "@docusaurus/theme-common";
import SearchMetadata from "@theme/SearchMetadata";
import BlogPostItems from "@theme/BlogPostItems";
import { AuthorCardWithProps } from "@site/src/components/blog";
import clsx from "clsx";
const BlogListPageMetadata = () => {
const {
siteConfig: { title, tagline },
} = useDocusaurusContext();
return (
<>
<PageMetadata title={title} description={tagline} />
<SearchMetadata tag="author_blog_posts_list" />
</>
);
};
const AuthorPage = (props) => {
const { items } = props;
const author = items[0].content.metadata.authors[0];
return (
<>
<BlogListPageMetadata />
<BlogLayout showSidebarBanner={false}>
<div className="h-12" />
<AuthorCardWithProps author={author} />
<div
className={clsx(
"px-4",
"max-w-[512px]",
"blog-md:px-7",
"blog-md:max-w-screen-blog-md",
"blog-2xl:px-0",
"blog-2xl:max-w-screen-blog-md",
"w-full",
"mx-auto",
)}
>
<h1 className="text-4xl !mb-0 px-0 lg:px-4">Posts</h1>
</div>
<div className={clsx("px-4", "blog-md:px-7", "blog-2xl:px-0")}>
<BlogPostItems
items={items}
showTitle={false}
isAuthorPage={true}
/>
</div>
</BlogLayout>
</>
);
};
export default AuthorPage;

View File

@@ -0,0 +1,155 @@
import React from "react";
import Link from "@docusaurus/Link";
import { useBlogPost } from "@docusaurus/theme-common/internal";
import { blogPostContainerID } from "@docusaurus/utils-common";
import MDXContent from "@theme/MDXContent";
import BlogPostItemContainer from "@theme/BlogPostItem/Container";
import useDocusaurusContext from "@docusaurus/useDocusaurusContext";
import {
LinkedinShareButton,
RedditShareButton,
TwitterShareButton,
TwitterIcon,
RedditIcon,
LinkedinIcon,
} from "react-share";
import clsx from "clsx";
import { Date, ReadingTime } from "@site/src/components/blog/common";
import { BannerRandom } from "@site/src/components/banner/banner-random";
import { Twitter } from "../icons";
export const BlogPostPageView = ({ children }) => {
const { metadata, isBlogPostPage } = useBlogPost();
const {
permalink,
title,
date,
formattedDate,
readingTime,
frontMatter,
tags,
description,
authors,
} = metadata;
const author = authors[0];
const {
siteConfig: { url },
} = useDocusaurusContext();
return (
<BlogPostItemContainer
className={clsx(
"py-10",
"px-4 sm:px-0",
"blog-sm:py-12",
"blog-md:py-16",
"w-full",
"mx-auto",
"max-w-[512px]",
"blog-sm:max-w-screen-blog-sm",
"blog-lg:max-w-screen-content-2xl",
)}
>
<div
className={clsx(
"flex",
"justify-between",
"items-center",
"blog-sm:px-6",
)}
>
<Link
to="/blog"
className={clsx("!text-gray-500 text-sm no-underline")}
>
Back to blog
</Link>
<div className="flex items-center space-x-2 px-2 py-1">
<span className="text-gray-500 text-sm">Share on</span>
<TwitterShareButton
windowWidth={750}
windowHeight={800}
url={url + permalink}
className="flex"
title={title}
hashtags={tags.map((tag) => tag.label)}
>
<Twitter width={26} height={26} />
</TwitterShareButton>
<RedditShareButton
className="flex"
windowWidth={750}
windowHeight={600}
url={url + permalink}
title={title}
>
<RedditIcon size={26} round />
</RedditShareButton>
<LinkedinShareButton
url={url + permalink}
title={title}
source={url}
summary={description}
className="flex"
>
<LinkedinIcon size={26} round />
</LinkedinShareButton>
</div>
</div>
<div>
<img
className="mb-2 w-full rounded-xl"
src={`https://refine-web.imgix.net${frontMatter.image?.replace(
"https://refine.ams3.cdn.digitaloceanspaces.com",
"",
)}?w=800`}
alt={title}
/>
</div>
<div className="blog-sm:px-6">
<div className="mb-6 text-sm">
<div
className={clsx(
"flex",
"justify-between",
"sm:flex-row flex-col",
)}
>
<div className="flex justify-center items-center gap-2"></div>
<div className="flex items-center gap-2 text-gray-600 dark:text-gray-400">
<Date date={date} formattedDate={formattedDate} />
{typeof readingTime !== "undefined" && (
<>
<span className="w-[4px] h-[4px] rounded-full bg-gray-600 dark:bg-gray-500"></span>
<ReadingTime readingTime={readingTime} />
</>
)}
</div>
</div>
<div className="m-6 mb-12">
<BannerRandom />
</div>
</div>
<h1 className="text-xl md:text-4xl" itemProp="headline">
{isBlogPostPage ? (
title
) : (
<Link itemProp="url" to={permalink}>
{title}
</Link>
)}
</h1>
<div
id={blogPostContainerID}
className="markdown"
itemProp="articleBody"
>
<MDXContent>{children}</MDXContent>
</div>
</div>
</BlogPostItemContainer>
);
};

View File

@@ -0,0 +1,9 @@
import React from "react";
export function Date({ date, formattedDate }) {
return (
<time dateTime={date} itemProp="datePublished">
{formattedDate}
</time>
);
}

View File

@@ -0,0 +1,3 @@
export * from "./date";
export * from "./reading-time";
export * from "./spacer";

View File

@@ -0,0 +1,27 @@
import React from "react";
import { usePluralForm } from "@docusaurus/theme-common";
import { translate } from "@docusaurus/Translate";
function useReadingTimePlural() {
const { selectMessage } = usePluralForm();
return (readingTimeFloat) => {
const readingTime = Math.ceil(readingTimeFloat);
return selectMessage(
readingTime,
translate(
{
id: "theme.blog.post.readingTime.plurals",
description:
'Pluralized label for "{readingTime} min read". Use as much plural forms (separated by "|") as your language support (see https://www.unicode.org/cldr/cldr-aux/charts/34/supplemental/language_plural_rules.html)',
message: "One min read|{readingTime} min read",
},
{ readingTime },
),
);
};
}
export function ReadingTime({ readingTime }) {
const readingTimePlural = useReadingTimePlural();
return <>{readingTimePlural(readingTime)}</>;
}

View File

@@ -0,0 +1,5 @@
import React from "react";
export function Spacer() {
return <>{" · "}</>;
}

View File

@@ -0,0 +1,31 @@
import React from "react";
import Link from "@docusaurus/Link";
const DiscordBanner = () => {
return (
<div className="flex flex-col md:flex-row justify-between items-center gap-4 md:gap-0 h-auto md:h-[150px] bg-[#5865F2] w-full rounded-2xl py-5 px-5 md:px-12">
<div className="flex items-center gap-16">
<img
className="hidden md:block"
src="/img/blog-static/discord-banner.png"
alt="Discord Logo"
/>
<div className="text-white font-montserrat font-bold max-w-md text-center md:text-left">
<h1 className="text-2xl uppercase leading-tight mb-0 font-montserrat">
Join to refine discord server
</h1>
<p className="mb-0 text-base">
to get help, share ideas, and discuss the latest news.
</p>
</div>
</div>
<Link to="https://discord.gg/refine">
<button className="bg-transparent text-white font-bold py-2 px-4 rounded-lg h-12 w-44 border-white cursor-pointer font-montserrat uppercase text-xl border-solid active:scale-[0.99]">
Join Us
</button>
</Link>
</div>
);
};
export default DiscordBanner;

View File

@@ -0,0 +1,108 @@
import React from "react";
import Link from "@docusaurus/Link";
import { useBlogPost } from "@docusaurus/theme-common/internal";
import BlogPostItemContainer from "@theme/BlogPostItem/Container";
import { Date } from "@site/src/components/blog/common";
import clsx from "clsx";
export const FeaturedBlogPostItem = () => {
const { metadata } = useBlogPost();
const {
permalink,
title,
date,
formattedDate,
frontMatter,
description,
tags,
} = metadata;
const author = metadata.authors[0];
return (
<BlogPostItemContainer>
<Link itemProp="url" to={permalink}>
<div className="not-prose relative m-0 h-40 hover:brightness-90 md:h-64">
<img
src={`https://refine-web.imgix.net${frontMatter.image?.replace(
"https://refine.ams3.cdn.digitaloceanspaces.com",
"",
)}?h=256`}
alt={title}
className="absolute inset-0 mt-0 h-full w-full rounded-[10px] object-cover"
loading="lazy"
/>
</div>
</Link>
<div className="px-4 py-4 md:px-6 md:py-6">
<div
className={clsx(
"mb-2 gap-1 md:mb-4 2xl:mb-6",
"flex flex-wrap items-center",
)}
>
{tags.map((tag) => (
<Link
className={clsx(
"text-xs",
"bg-gray-100 dark:bg-gray-700",
"text-gray-600 hover:text-gray-600 dark:text-gray-400 dark:hover:text-gray-400",
"no-underline",
"rounded",
"px-2 py-1",
)}
href={tag.permalink}
key={tag.permalink}
>
{tag.label}
</Link>
))}
</div>
<div className="mb-2 md:mb-4 2xl:mb-6">
<Link
itemProp="url"
to={permalink}
className="no-underline hover:no-underline"
rel="noopener dofollow"
>
<div
className={clsx(
"mb-2 md:mb-4 2xl:mb-6",
"text-gray-700 dark:text-gray-200",
"text-sm sm:text-2xl 2xl:text-[32px] 2xl:leading-10",
"font-lg",
"font-bold",
)}
>
{title}
</div>
</Link>
<div
className={clsx(
"line-clamp-3",
"text-gray-700 dark:text-gray-300",
"text-xs md:text-base 2xl:text-xl",
)}
>
{description}
</div>
</div>
<div className="flex items-center gap-2">
<span
className={clsx(
"text-gray-600 hover:text-gray-600",
"dark:text-gray-400 hover:dark:text-gray-400",
"text-xs 2xl:text-base",
"leading-6",
"no-underline",
)}
>
<Date date={date} formattedDate={formattedDate} />
</span>
</div>
</div>
</BlogPostItemContainer>
);
};

View File

@@ -0,0 +1,48 @@
import React from "react";
import { BlogPostProvider } from "@docusaurus/theme-common/internal";
import { FeaturedBlogPostItem } from "../featured-blog-post-item";
import clsx from "clsx";
export const FeaturedBlogPostItems = ({ items }) => {
return (
<div
className={clsx(
"py-10",
"px-4",
"max-w-[512px]",
"blog-md:px-7",
"blog-md:max-w-screen-blog-md",
"blog-2xl:px-0",
"blog-2xl:max-w-screen-blog-md",
"w-full",
"mx-auto",
"not-prose",
)}
>
<h2
className={clsx(
"m-0 p-0",
"blog-lg:mb-12 blog-md:mb-8 mb-10",
"text-xl blog-sm:text-4xl blog-lg:text-5xl",
"text-gray-900 dark:text-gray-0",
"px-0 blog-sm:px-6",
"font-semibold",
)}
>
Featured Posts
</h2>
<div className="grid grid-cols-1 blog-md:grid-cols-2 blog-lg:gap-12 gap-8">
{items.map(({ content: BlogPostContent }) => (
<BlogPostProvider
key={BlogPostContent.metadata.permalink}
content={BlogPostContent}
>
<FeaturedBlogPostItem />
</BlogPostProvider>
))}
</div>
</div>
);
};

View File

@@ -0,0 +1,74 @@
import React from "react";
import Link from "@docusaurus/Link";
import { CloudTipIcon, GithubIcon } from "../../landing/icons";
const token = "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";
const repo = "refine";
const org = "pankod";
const GithubBanner = () => {
const [githubStarCount, setGithubStarCount] = React.useState(0);
React.useEffect(() => {
(async () => {
const response = await fetch(
`https://api.github.com/repos/${org}/${repo}?access_token=${token}`,
{
method: "GET",
headers: {
"Content-Type": "application/json",
Authorization: `token ${token}`,
},
},
);
const json = await response.json();
setGithubStarCount(json.stargazers_count ?? 2000);
})();
}, []);
return (
<div className="flex flex-col md:flex-row justify-between items-center gap-4 md:gap-0 h-auto md:h-[150px] w-full rounded-2xl py-5 px-5 md:px-12 github-banner-bg">
<div className="flex items-center gap-16">
<img
className="hidden md:block"
src="/img/blog-static/github-banner-icon.png"
alt="Github Logo"
/>
<div className="font-montserrat max-w-md text-center md:text-left">
<h1 className="text-2xl uppercase leading-tight mb-0 font-montserrat font-bold">
Star us on github
</h1>
<p className="mb-0 text-base leading-tight">
<b>refine</b> is an{" "}
<b>open-source React-based framework</b>
for building <b>CRUD applications</b> without
constraints. Please show us your <b>support</b> with a
shining <b>GitHub star</b>.
</p>
</div>
</div>
{/* eslint-disable react/jsx-no-target-blank */}
<Link
to="https://github.com/refinedev/refine"
rel="noopener"
className="bg-[#211d21] no-underline rounded-xl h-[54px] flex gap-2 pl-3.5 py-2.5 pr-2.5 items-center"
>
<GithubIcon />
<div className="font-bold font-montserrat text-base text-white">
Star
</div>
<div className="flex items-start h-full">
<CloudTipIcon className="mt-2 -mr-px" />
<div className="cloud rounded-md bg-white text-[#211d21] h-full flex items-center justify-center px-1.5 font-montserrat font-bold text-base">
{`${githubStarCount}`.padStart(4, "0")}
</div>
</div>
</Link>
</div>
);
};
export default GithubBanner;

View File

@@ -0,0 +1,91 @@
import clsx from "clsx";
import React from "react";
export const ChevronLeft = (
props: React.SVGProps<SVGSVGElement>,
): JSX.Element => (
<svg
aria-hidden="true"
className="h-5 w-5"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
fillRule="evenodd"
d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z"
clipRule="evenodd"
></path>
</svg>
);
export const ChevronRight = (
props: React.SVGProps<SVGSVGElement>,
): JSX.Element => (
<svg
aria-hidden="true"
className="h-5 w-5"
fill="currentColor"
viewBox="0 0 20 20"
xmlns="http://www.w3.org/2000/svg"
{...props}
>
<path
fillRule="evenodd"
d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z"
clipRule="evenodd"
></path>
</svg>
);
export const Github = (props: React.SVGProps<SVGSVGElement>): JSX.Element => (
<svg
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
fill="none"
{...props}
>
<path
fill="#fff"
fillRule="evenodd"
d="M12.058 0a11.894 11.894 0 0 0-7.814 2.929 12.37 12.37 0 0 0-4.088 7.404 12.523 12.523 0 0 0 1.588 8.344A12.094 12.094 0 0 0 8.25 23.98c.606.112.82-.273.82-.597V21.29c-3.364.747-4.073-1.655-4.073-1.655A3.285 3.285 0 0 0 3.66 17.83c-1.088-.755.088-.755.088-.755.382.055.745.196 1.064.417.32.22.584.511.777.85.164.304.384.571.65.787a2.523 2.523 0 0 0 2.855.241 2.631 2.631 0 0 1 .74-1.646c-2.677-.31-5.487-1.367-5.487-6.042a4.816 4.816 0 0 1 1.235-3.3A4.575 4.575 0 0 1 5.7 5.127s1.012-.333 3.311 1.261a11.156 11.156 0 0 1 6.034 0c2.3-1.593 3.305-1.261 3.305-1.261a4.55 4.55 0 0 1 .147 3.232 4.816 4.816 0 0 1 1.235 3.301c0 4.728-2.816 5.762-5.501 6.041.288.296.51.651.652 1.042.142.39.199.808.17 1.224v3.377c0 .4.213.71.827.59a12.1 12.1 0 0 0 6.414-5.322 12.524 12.524 0 0 0 1.548-8.29 12.37 12.37 0 0 0-4.047-7.36A11.897 11.897 0 0 0 12.058 0Z"
clipRule="evenodd"
/>
</svg>
);
export const Twitter = (props: React.SVGProps<SVGSVGElement>): JSX.Element => (
<svg
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
viewBox="0 0 50 50"
{...props}
className={clsx("dark:text-[#e7e9ea] text-[#0f1419]")}
>
<path
fillRule="evenodd"
d="M 5.9199219 6 L 20.582031 27.375 L 6.2304688 44 L 9.4101562 44 L 21.986328 29.421875 L 31.986328 44 L 44 44 L 28.681641 21.669922 L 42.199219 6 L 39.029297 6 L 27.275391 19.617188 L 17.933594 6 L 5.9199219 6 z M 9.7167969 8 L 16.880859 8 L 40.203125 42 L 33.039062 42 L 9.7167969 8 z"
clipRule="evenodd"
fill="currentColor"
/>
</svg>
);
export const Linkedin = (props: React.SVGProps<SVGSVGElement>): JSX.Element => (
<svg
xmlns="http://www.w3.org/2000/svg"
width={24}
height={24}
fill="none"
{...props}
>
<rect width={24} height={24} fill="#0A66C2" rx={12} />
<path
fill="#fff"
d="M9.364 16.762H7.385V10.4h1.979v6.362ZM8.375 9.53a1.146 1.146 0 1 1 0-2.293 1.146 1.146 0 0 1 0 2.293Zm8.395 7.233h-1.977v-3.094c0-.738-.013-1.687-1.027-1.687-1.03 0-1.188.803-1.188 1.633v3.148h-1.974V10.4H12.5v.87h.027c.263-.5.908-1.028 1.871-1.028 2.003 0 2.372 1.318 2.372 3.031v3.49h-.001Z"
/>
</svg>
);

View File

@@ -0,0 +1,9 @@
export * from "./featured-blog-post-item";
export * from "./featured-blog-post-items";
export * from "./blog-post-page";
export * from "./author-card";
export * from "./discord-banner";
export * from "./github-banner";
export * from "./twitter-banner";
export * from "./tags";
export * from "./post-paginator";

View File

@@ -0,0 +1,79 @@
import React from "react";
import Link from "@docusaurus/Link";
import { Date } from "@site/src/components/blog/common";
import clsx from "clsx";
export const PostPaginator = ({ posts, title }) => {
if (posts.length < 1) {
return null;
}
return (
<div
className={clsx(
"mx-auto w-full",
"py-10",
"blog-sm:py-12",
"blog-md:py-16",
"max-w-[512px]",
"blog-sm:max-w-screen-blog-sm",
"blog-lg:max-w-screen-content-2xl",
)}
>
<div className="blog-sm:px-6 w-full px-4">
<h2 className="m-0 mb-4 p-0 pl-4 text-2xl font-semibold text-gray-900 dark:text-gray-200">
{title}
</h2>
<div className="flex flex-col">
{posts.map((post) => (
<div
key={post.permalink ?? post.id}
className={clsx(
"flex",
"flex-col",
"p-5",
"mb-5",
"rounded-md",
"bg-gray-50 dark:bg-gray-800",
)}
>
<Link
to={post.permalink}
rel="dofollow"
className={clsx(
"font-bold",
"text-gray-800 dark:text-gray-200",
"no-underline",
"hover:text-gray-800 hover:no-underline dark:hover:text-gray-200",
"mb-2",
)}
>
{post.title}
</Link>
<p
className={clsx(
"font-sm",
"text-gray-700 dark:text-gray-400",
)}
>
{post.description}
</p>
<div
id="post-info"
className="flex items-center gap-2 text-sm text-gray-600 dark:text-gray-400"
>
<Date
date={post.date}
formattedDate={post.formattedDate}
/>
</div>
</div>
))}
</div>
</div>
</div>
);
};

View File

@@ -0,0 +1,90 @@
/* eslint-disable react/jsx-no-target-blank */
import React from "react";
const PromotionBanner = ({ image, title, description, isDark }) => {
let renderDescription;
if (description === "refineNew") {
renderDescription = (
<div>
{" "}
<a href="https://s.refine.dev/new-blog" target="_blank">
refine.new
</a>{" "}
enables you to create React-based, headless UI enterprise
applications within your browser that you can preview, tweak and
download instantly.
<br />
<br />
🚀 By visually combining options for your preferred
<b> React platform,</b> <b>UI framework</b>, {" "}
<b>backend connector</b>, and <b>auth provider</b>; you can
create tailor-made architectures for your project in seconds. It
feels like having access to thousands of project templates at
your fingertips, allowing you to choose the one that best suits
your needs!
<br />
<br />
<br />
</div>
);
} else {
renderDescription = description ?? (
<div>
Meet the headless, React-based solution to build sleek{" "}
<b>CRUD</b> applications. With refine, you can be confident that
your codebase will always stay clean and boilerplate-free.
<br />
<br />
Try{" "}
<a href="https://github.com/refinedev/refine" target="_blank">
refine
</a>{" "}
to rapidly build your next <b>CRUD</b> project, whether {"it's"}{" "}
an admin panel, dashboard, internal tool or storefront.
</div>
);
}
const imgBase =
image ??
"https://refine.ams3.cdn.digitaloceanspaces.com/website/static/img/generic_banner.png";
const imgUrl = imgBase.startsWith("http")
? imgBase
: `https://refine.ams3.cdn.digitaloceanspaces.com/website/static${
imgBase.startsWith("/") ? imgBase : `/${imgBase}`
}`;
return (
/* <div className={`banner-container ${isDark && "dark"}`}>
<div className="banner-header">
{title ?? "Does your CRUD app need server state management?"}
</div>
{renderDescription}
<div>
<a
href={
description === "refineNew"
? "https://s.refine.dev/new-blog"
: "https://github.com/refinedev/refine"
}
target="_blank"
>
<img src={imgUrl} alt="refine blog logo" />
</a>
</div>
<br />
</div> */
<a
href="https://s.refine.dev/hackathon2"
target="_blank"
rel="noreferrer"
>
<img src="https://refine.ams3.cdn.digitaloceanspaces.com/hackathon-2/hackathon_cover.png" />
</a>
);
};
export default PromotionBanner;

View File

@@ -0,0 +1,31 @@
import React from "react";
import Link from "@docusaurus/Link";
import { useBlogPost } from "@docusaurus/theme-common/internal";
import clsx from "clsx";
export const Tags = () => {
const { metadata } = useBlogPost();
return (
<div className="flex flex-wrap gap-2 pb-6 pl-1">
{metadata.tags.map((tag) => (
<Link
to={tag.permalink}
className={clsx(
"text-xs",
"bg-gray-100 dark:bg-gray-700",
"text-gray-600 dark:text-gray-400",
"rounded",
"py-1",
"px-2",
"no-underline hover:no-underline",
"whitespace-nowrap",
)}
key={tag.permalink}
>
{tag.label}
</Link>
))}
</div>
);
};

View File

@@ -0,0 +1,53 @@
import React from "react";
import Link from "@docusaurus/Link";
const TwitterBanner = ({ children }) => {
return (
<div className="flex flex-col md:flex-row items-center twitter-banner-bg px-5 md:px-10 py-5 rounded-xl gap-2">
<div className="flex flex-col justify-center items-center md:items-start gap-4">
<div className="text-center md:text-left">
<h1 className="text-white font-montserrat text-2xl leading-tight mb-0">
WANT TO HEAR THE LATEST DEVELOPMENTS ABOUT refine?
</h1>
<p className="mb-0 uppercase font-montserrat text-white">
Follow us on Twitter.
</p>
</div>
<Link to="https://twitter.com/refine_dev">
<button className="bg-transparent text-white font-bold py-2 px-8 rounded-lg border-white cursor-pointer font-montserrat uppercase text-xl border-solid active:scale-[0.99]">
Follow Us
</button>
</Link>
</div>
<div className="w-[350px]">
{children ? (
children
) : (
<blockquote className="twitter-tweet" data-cards="hidden">
<p lang="en" dir="ltr">
💥New Blog Post!
<br />
<br />
Animations in React with Framer Motion
<a href="https://t.co/7kWU1ROPYd">
https://t.co/7kWU1ROPYd
</a>
<a href="https://twitter.com/hashtag/opensource?src=hash&amp;ref_src=twsrc%5Etfw">
#opensource
</a>{" "}
<a href="https://twitter.com/hashtag/ReactJS?src=hash&amp;ref_src=twsrc%5Etfw">
#ReactJS
</a>
</p>
&mdash; refine (@refine_dev){" "}
<a href="https://twitter.com/refine_dev/status/1565321477628510208?ref_src=twsrc%5Etfw">
September 1, 2022
</a>
</blockquote>
)}
</div>
</div>
);
};
export default TwitterBanner;