/* eslint-disable max-lines */
/* eslint-disable @typescript-eslint/naming-convention */
/* eslint-disable filename-rules/match */
import { useEffect, useMemo, useState } from 'react';
import clsx from 'clsx';
import { CssVarsProvider, styled } from '@mui/joy/styles';
import { Box, Button, Container, Grid, SvgIcon, Typography } from '@mui/joy';
import GitHubIcon from '@mui/icons-material/GitHub';
import RedditIcon from '@mui/icons-material/Reddit';
import TelegramIcon from '@mui/icons-material/Telegram';
// eslint-disable-next-line no-restricted-imports
import { useMediaQuery } from '@mui/material';
import LogoImage from './logo.png';
import CollaborationImage from './collaboration.png';
import PageImage from './page.png';
import ShapeImage from './shape.png';
import TaskImage from './task.png';
const DiscordIcon = (props: any) => {
return (
);
};
const VenusContainer = styled(Container)({
margin: '1em auto',
});
const Alternatives = styled(Box)<{ width: string }>(({ width }) => ({
position: 'relative',
width: '24em',
height: '128px',
transform: 'translateY(-8px)',
overflowY: 'hidden',
'@media (max-width: 1024px)': {
width,
height: '48px',
transform: 'translateY(0)',
},
'& .scroll-element': {
width: 'inherit',
height: 'inherit',
position: 'absolute',
left: '0%',
top: '0%',
lineHeight: '96px',
'@media (max-width: 1024px)': {
lineHeight: '32px',
},
},
'& .scroll-element.active': {
animation: 'primary 500ms linear infinite',
},
'.primary.active': {
animation: 'primary 500ms linear infinite',
},
'.secondary.active': {
animation: 'secondary 500ms linear infinite',
},
'@keyframes primary': {
from: {
top: '0%',
},
to: {
top: '-100%',
},
},
'@keyframes secondary': {
from: {
top: '100%',
},
to: {
top: '0%',
},
},
}));
const _alternatives = ['Notion', 'Miro', 'Monday'];
const _alternativesSize = [8, 6, 10];
const Product = () => {
const [idx, setIdx] = useState(0);
const [last, current] = useMemo(
() => [
_alternatives[idx],
_alternatives[idx + 1] ? _alternatives[idx + 1] : _alternatives[0],
],
[idx]
);
const maxWidth = useMemo(() => _alternativesSize[idx], [idx]);
const [active, setActive] = useState(false);
const matches = useMediaQuery('(max-width: 1024px)');
useEffect(() => {
const handle = setInterval(() => {
setActive(true);
setTimeout(
() => {
setIdx(idx => (_alternatives[idx + 1] ? idx + 1 : 0));
setActive(false);
},
matches ? 450 : 380
);
}, 2000);
return () => clearInterval(handle);
}, [matches]);
return (
{last}
{current}
);
};
const AffineImage = styled('img')({
maxWidth: '100%',
objectFit: 'contain',
});
const GitHub = (props: { center?: boolean; flat?: boolean }) => {
const matches = useMediaQuery('(max-width: 1024px)');
return (
);
};
export function App() {
const matches = useMediaQuery('(max-width: 1024px)');
return (
div': {
marginTop: '1em',
},
}}
>
Open Source,
Privacy First
Alternative
Affine is the next-generation collaborative
knowledge base for professionals.
Try it on
It’s not just add-up of Docs, whiteboard, and
tables.
Transform any building blocks as you like.
Say goodbye to redundancy, and keep all your
knowledge minimal, in your way.
Shape Your Page
Docs, kanban, and databases are all fully
functional at any place. You always keep
what-you-see-is-what-you-get.
All pages come with docs and whiteboard mode.
Plan Your Task
No more chaos between so many views.
Set a TODO with Markdown, and manage it in
Kanban.
Managing multi-dimensional tables should be
simple as that.
Privacy-first, and collaborative. No compromises
whatsoever.
We don’t like cloud lock-in. Your data is always
locally stored and secured, while you can still
collaborate in real-time with others.
Privacy is the foundation of everything we do. But
it is no excuse for the bad experience.
Build for an open and semantic future
Keep Updated on
Join Our Community
AFFiNE is an
#OpenSource
company
Copyright © 2022 AFFiNE.
);
}
export default App;