@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
import { ResponsiveTimeRange } from '@nivo/calendar';
|
import { ResponsiveTimeRange } from '@nivo/calendar';
|
||||||
|
|
||||||
import { CardContainer } from '@/app/developers/contributors/[slug]/components/CardContainer';
|
import { CardContainer } from '@/app/_components/contributors/CardContainer';
|
||||||
import { Title } from '@/app/developers/contributors/[slug]/components/Title';
|
import { Title } from '@/app/_components/contributors/Title';
|
||||||
|
|
||||||
export const ActivityLog = ({
|
export const ActivityLog = ({
|
||||||
data,
|
data,
|
||||||
@ -66,7 +66,7 @@ const AvatarGrid = ({ users }: { users: User[] }) => {
|
|||||||
return (
|
return (
|
||||||
<AvatarGridContainer>
|
<AvatarGridContainer>
|
||||||
{users.map((user) => (
|
{users.map((user) => (
|
||||||
<Link href={`/developers/contributors/${user.id}`} key={`l_${user.id}`}>
|
<Link href={`/contributors/${user.id}`} key={`l_${user.id}`}>
|
||||||
<AvatarItem key={user.id}>
|
<AvatarItem key={user.id}>
|
||||||
<img src={user.avatarUrl} alt={user.id} />
|
<img src={user.avatarUrl} alt={user.id} />
|
||||||
<span className="username">{user.id}</span>
|
<span className="username">{user.id}</span>
|
||||||
@ -1,10 +1,10 @@
|
|||||||
'use client';
|
'use client';
|
||||||
|
|
||||||
import { Breadcrumbs } from '@/app/components/Breadcrumbs';
|
import { Breadcrumbs } from '@/app/_components/ui/layout/Breadcrumbs';
|
||||||
|
|
||||||
const BREADCRUMB_ITEMS = [
|
const BREADCRUMB_ITEMS = [
|
||||||
{
|
{
|
||||||
uri: '/developers/contributors',
|
uri: '/contributors',
|
||||||
label: 'Contributors',
|
label: 'Contributors',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
@ -3,7 +3,7 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
|
|
||||||
import { GithubIcon } from '@/app/components/Icons';
|
import { GithubIcon } from '@/app/_components/ui/icons/SvgIcons';
|
||||||
|
|
||||||
const ProfileContainer = styled.div`
|
const ProfileContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { CardContainer } from '@/app/developers/contributors/[slug]/components/CardContainer';
|
import { CardContainer } from '@/app/_components/contributors/CardContainer';
|
||||||
|
|
||||||
const Container = styled(CardContainer)`
|
const Container = styled(CardContainer)`
|
||||||
flex-direction: row;
|
flex-direction: row;
|
||||||
@ -2,8 +2,8 @@ import { Tooltip } from 'react-tooltip';
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
|
|
||||||
import { PullRequestIcon } from '@/app/components/Icons';
|
import { PullRequestIcon } from '@/app/_components/ui/icons/SvgIcons';
|
||||||
import { formatIntoRelativeDate } from '@/lib/utils';
|
import { formatIntoRelativeDate } from '@/shared-utils/formatIntoRelativeDate';
|
||||||
|
|
||||||
const StyledTooltip = styled(Tooltip)``;
|
const StyledTooltip = styled(Tooltip)``;
|
||||||
|
|
||||||
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { CardContainer } from '@/app/developers/contributors/[slug]/components/CardContainer';
|
import { CardContainer } from '@/app/_components/contributors/CardContainer';
|
||||||
import { PullRequestItem } from '@/app/developers/contributors/[slug]/components/PullRequestItem';
|
import { PullRequestItem } from '@/app/_components/contributors/PullRequestItem';
|
||||||
import { Title } from '@/app/developers/contributors/[slug]/components/Title';
|
import { Title } from '@/app/_components/contributors/Title';
|
||||||
|
|
||||||
const List = styled.div`
|
const List = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { HeartIcon } from '@/app/components/Icons';
|
import { CardContainer } from '@/app/_components/contributors/CardContainer';
|
||||||
import { CardContainer } from '@/app/developers/contributors/[slug]/components/CardContainer';
|
import { HeartIcon } from '@/app/_components/ui/icons/SvgIcons';
|
||||||
|
|
||||||
const StyledTitle = styled.div`
|
const StyledTitle = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -152,3 +152,20 @@ export const HeartIcon = ({ size = 'S', color = 'rgb(179,179,179)' }) => {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const ExternalArrow = () => {
|
||||||
|
return (
|
||||||
|
<div style={{ width: '14px', height: '14px', fill: 'rgb(179, 179, 179)' }}>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
viewBox="0 0 256 256"
|
||||||
|
focusable="false"
|
||||||
|
color="rgb(179, 179, 179)"
|
||||||
|
>
|
||||||
|
<g color="rgb(179, 179, 179)">
|
||||||
|
<path d="M200,64V168a8,8,0,0,1-16,0V83.31L69.66,197.66a8,8,0,0,1-11.32-11.32L172.69,72H88a8,8,0,0,1,0-16H192A8,8,0,0,1,200,64Z"></path>
|
||||||
|
</g>
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
@ -5,8 +5,11 @@ import styled from '@emotion/styled';
|
|||||||
import { IconChevronLeft } from '@tabler/icons-react';
|
import { IconChevronLeft } from '@tabler/icons-react';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
|
|
||||||
import { Theme } from '@/app/ui/theme/theme';
|
import {
|
||||||
import { DeviceType, useDeviceType } from '@/app/ui/utilities/useDeviceType';
|
DeviceType,
|
||||||
|
useDeviceType,
|
||||||
|
} from '@/app/_components/client-utils/useDeviceType';
|
||||||
|
import { Theme } from '@/app/_components/ui/theme/theme';
|
||||||
|
|
||||||
const Container = styled.div`
|
const Container = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -3,7 +3,13 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { usePathname } from 'next/navigation';
|
import { usePathname } from 'next/navigation';
|
||||||
|
|
||||||
import { DiscordIcon, GithubIcon2, LinkedInIcon, XIcon } from './Icons';
|
import {
|
||||||
|
DiscordIcon,
|
||||||
|
GithubIcon2,
|
||||||
|
LinkedInIcon,
|
||||||
|
XIcon,
|
||||||
|
} from '../icons/SvgIcons';
|
||||||
|
|
||||||
import { Logo } from './Logo';
|
import { Logo } from './Logo';
|
||||||
|
|
||||||
const FooterContainer = styled.div`
|
const FooterContainer = styled.div`
|
||||||
@ -3,9 +3,10 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { ExternalArrow } from '@/app/components/ExternalArrow';
|
import { ExternalArrow } from '@/app/_components/ui/icons/SvgIcons';
|
||||||
|
|
||||||
|
import { GithubIcon } from '../icons/SvgIcons';
|
||||||
|
|
||||||
import { GithubIcon } from './Icons';
|
|
||||||
import { Logo } from './Logo';
|
import { Logo } from './Logo';
|
||||||
|
|
||||||
const Nav = styled.nav`
|
const Nav = styled.nav`
|
||||||
@ -4,9 +4,10 @@ import { useState } from 'react';
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { IBM_Plex_Mono } from 'next/font/google';
|
import { IBM_Plex_Mono } from 'next/font/google';
|
||||||
|
|
||||||
import { ExternalArrow } from '@/app/components/ExternalArrow';
|
import { ExternalArrow } from '@/app/_components/ui/icons/SvgIcons';
|
||||||
|
|
||||||
|
import { GithubIcon } from '../icons/SvgIcons';
|
||||||
|
|
||||||
import { GithubIcon } from './Icons';
|
|
||||||
import { Logo } from './Logo';
|
import { Logo } from './Logo';
|
||||||
|
|
||||||
const IBMPlexMono = IBM_Plex_Mono({
|
const IBMPlexMono = IBM_Plex_Mono({
|
||||||
@ -0,0 +1,18 @@
|
|||||||
|
import { Background } from '@/app/_components/ui/theme/background';
|
||||||
|
import { Border } from '@/app/_components/ui/theme/border';
|
||||||
|
import { Color } from '@/app/_components/ui/theme/colors';
|
||||||
|
import { Font } from '@/app/_components/ui/theme/font';
|
||||||
|
import { Icon } from '@/app/_components/ui/theme/icon';
|
||||||
|
import { Text } from '@/app/_components/ui/theme/text';
|
||||||
|
|
||||||
|
export const Theme = {
|
||||||
|
color: Color,
|
||||||
|
border: Border,
|
||||||
|
background: Background,
|
||||||
|
text: Text,
|
||||||
|
spacingMultiplicator: 4,
|
||||||
|
icon: Icon,
|
||||||
|
font: Font,
|
||||||
|
spacing: (...args: number[]) =>
|
||||||
|
args.map((multiplicator) => `${multiplicator * 4}px`).join(' '),
|
||||||
|
};
|
||||||
@ -2,8 +2,8 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
|
|
||||||
import { Theme } from '@/app/ui/theme/theme';
|
import { Theme } from '@/app/_components/ui/theme/theme';
|
||||||
import { UserGuideHomeCardsType } from '@/app/user-guide/constants/UserGuideHomeCards';
|
import { UserGuideHomeCardsType } from '@/content/user-guide/constants/UserGuideHomeCards';
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
color: ${Theme.border.color.plain};
|
color: ${Theme.border.color.plain};
|
||||||
@ -2,10 +2,13 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import { Breadcrumbs } from '@/app/components/Breadcrumbs';
|
import {
|
||||||
import { FileContent } from '@/app/get-posts';
|
DeviceType,
|
||||||
import { Theme } from '@/app/ui/theme/theme';
|
useDeviceType,
|
||||||
import { DeviceType, useDeviceType } from '@/app/ui/utilities/useDeviceType';
|
} from '@/app/_components/client-utils/useDeviceType';
|
||||||
|
import { Breadcrumbs } from '@/app/_components/ui/layout/Breadcrumbs';
|
||||||
|
import { Theme } from '@/app/_components/ui/theme/theme';
|
||||||
|
import { FileContent } from '@/app/_server-utils/get-posts';
|
||||||
|
|
||||||
const StyledContainer = styled.div<{ devicetype: string }>`
|
const StyledContainer = styled.div<{ devicetype: string }>`
|
||||||
width: ${({ devicetype }) =>
|
width: ${({ devicetype }) =>
|
||||||
@ -1,10 +1,13 @@
|
|||||||
'use client';
|
'use client';
|
||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
|
|
||||||
import UserGuideCard from '@/app/components/user-guide/UserGuideCard';
|
import {
|
||||||
import { Theme } from '@/app/ui/theme/theme';
|
DeviceType,
|
||||||
import { DeviceType, useDeviceType } from '@/app/ui/utilities/useDeviceType';
|
useDeviceType,
|
||||||
import { UserGuideHomeCards } from '@/app/user-guide/constants/UserGuideHomeCards';
|
} from '@/app/_components/client-utils/useDeviceType';
|
||||||
|
import { Theme } from '@/app/_components/ui/theme/theme';
|
||||||
|
import UserGuideCard from '@/app/_components/user-guide/UserGuideCard';
|
||||||
|
import { UserGuideHomeCards } from '@/content/user-guide/constants/UserGuideHomeCards';
|
||||||
|
|
||||||
const StyledContainer = styled.div<{ isMobile: boolean }>`
|
const StyledContainer = styled.div<{ isMobile: boolean }>`
|
||||||
width: ${({ isMobile }) => (isMobile ? '100%' : '60%')};
|
width: ${({ isMobile }) => (isMobile ? '100%' : '60%')};
|
||||||
@ -3,11 +3,14 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
|
|
||||||
import UserGuideSidebarSection from '@/app/components/user-guide/UserGuideSidebarSection';
|
import {
|
||||||
import { IconBook } from '@/app/ui/icons';
|
DeviceType,
|
||||||
import { Theme } from '@/app/ui/theme/theme';
|
useDeviceType,
|
||||||
import { DeviceType, useDeviceType } from '@/app/ui/utilities/useDeviceType';
|
} from '@/app/_components/client-utils/useDeviceType';
|
||||||
import { UserGuideIndex } from '@/app/user-guide/constants/UserGuideIndex';
|
import { IconBook } from '@/app/_components/ui/icons';
|
||||||
|
import { Theme } from '@/app/_components/ui/theme/theme';
|
||||||
|
import UserGuideSidebarSection from '@/app/_components/user-guide/UserGuideSidebarSection';
|
||||||
|
import { UserGuideIndex } from '@/content/user-guide/constants/UserGuideIndex';
|
||||||
|
|
||||||
const StyledContainer = styled.div<{ isTablet: boolean }>`
|
const StyledContainer = styled.div<{ isTablet: boolean }>`
|
||||||
width: ${({ isTablet }) => (isTablet ? '30%' : '20%')};
|
width: ${({ isTablet }) => (isTablet ? '30%' : '20%')};
|
||||||
@ -5,9 +5,9 @@ import styled from '@emotion/styled';
|
|||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import { usePathname } from 'next/navigation';
|
import { usePathname } from 'next/navigation';
|
||||||
|
|
||||||
import { IconChevronDown, IconChevronRight } from '@/app/ui/icons';
|
import { IconChevronDown, IconChevronRight } from '@/app/_components/ui/icons';
|
||||||
import { Theme } from '@/app/ui/theme/theme';
|
import { Theme } from '@/app/_components/ui/theme/theme';
|
||||||
import { IndexSubtopic } from '@/app/user-guide/constants/UserGuideIndex';
|
import { IndexSubtopic } from '@/content/user-guide/constants/UserGuideIndex';
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
@ -3,7 +3,7 @@
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
|
|
||||||
import { Theme } from '@/app/ui/theme/theme';
|
import { Theme } from '@/app/_components/ui/theme/theme';
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
width: 20%;
|
width: 20%;
|
||||||
@ -1,16 +0,0 @@
|
|||||||
export const ExternalArrow = () => {
|
|
||||||
return (
|
|
||||||
<div style={{ width: '14px', height: '14px', fill: 'rgb(179, 179, 179)' }}>
|
|
||||||
<svg
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
viewBox="0 0 256 256"
|
|
||||||
focusable="false"
|
|
||||||
color="rgb(179, 179, 179)"
|
|
||||||
>
|
|
||||||
<g color="rgb(179, 179, 179)">
|
|
||||||
<path d="M200,64V168a8,8,0,0,1-16,0V83.31L69.66,197.66a8,8,0,0,1-11.32-11.32L172.69,72H88a8,8,0,0,1,0-16H192A8,8,0,0,1,200,64Z"></path>
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
@ -1,31 +0,0 @@
|
|||||||
import React, { ReactNode, useState } from 'react';
|
|
||||||
|
|
||||||
import TokenForm, {
|
|
||||||
TokenFormProps,
|
|
||||||
} from '@/app/components/PlaygroundTokenForm';
|
|
||||||
|
|
||||||
type PlaygroundProps = TokenFormProps & {
|
|
||||||
children?: ReactNode;
|
|
||||||
};
|
|
||||||
|
|
||||||
const Playground = ({
|
|
||||||
children,
|
|
||||||
setOpenApiJson,
|
|
||||||
setToken,
|
|
||||||
}: PlaygroundProps) => {
|
|
||||||
const [isTokenValid, setIsTokenValid] = useState(false);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<TokenForm
|
|
||||||
setOpenApiJson={setOpenApiJson}
|
|
||||||
setToken={setToken}
|
|
||||||
isTokenValid={isTokenValid}
|
|
||||||
setIsTokenValid={setIsTokenValid}
|
|
||||||
/>
|
|
||||||
{isTokenValid && children}
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Playground;
|
|
||||||
@ -1,190 +0,0 @@
|
|||||||
import React, { useEffect, useState } from 'react';
|
|
||||||
import { TbLoader2 } from 'react-icons/tb';
|
|
||||||
import styled from '@emotion/styled';
|
|
||||||
import { parseJson } from 'nx/src/utils/json';
|
|
||||||
|
|
||||||
export type TokenFormProps = {
|
|
||||||
setOpenApiJson?: (json: object) => void;
|
|
||||||
setToken?: (token: string) => void;
|
|
||||||
isTokenValid: boolean;
|
|
||||||
setIsTokenValid: (boolean: boolean) => void;
|
|
||||||
};
|
|
||||||
|
|
||||||
const Container = styled.div`
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
height: 90vh;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const Form = styled.form`
|
|
||||||
text-align: center;
|
|
||||||
padding: 50px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const StyledLink = styled.a`
|
|
||||||
color: #16233f;
|
|
||||||
text-decoration: none;
|
|
||||||
position: relative;
|
|
||||||
font-weight: bold;
|
|
||||||
transition: color 0.3s ease;
|
|
||||||
|
|
||||||
[data-theme='dark'] & {
|
|
||||||
color: #a3c0f8;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const Input = styled.input`
|
|
||||||
padding: 6px;
|
|
||||||
margin: 20px 0 5px 0;
|
|
||||||
max-width: 460px;
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
background-color: #f3f3f3;
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
border-radius: 4px;
|
|
||||||
|
|
||||||
[data-theme='dark'] & {
|
|
||||||
background-color: #16233f;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.invalid {
|
|
||||||
border: 1px solid #f83e3e;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const TokenInvalid = styled.span`
|
|
||||||
color: #f83e3e;
|
|
||||||
font-size: 12px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const Loader = styled(TbLoader2)`
|
|
||||||
color: #16233f;
|
|
||||||
font-size: 2rem;
|
|
||||||
animation: animate 2s infinite;
|
|
||||||
|
|
||||||
[data-theme='dark'] & {
|
|
||||||
color: #a3c0f8;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.not-visible {
|
|
||||||
visibility: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes animate {
|
|
||||||
0% {
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
transform: rotate(720deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const LoaderContainer = styled.div`
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
height: 50px;
|
|
||||||
`;
|
|
||||||
|
|
||||||
const TokenForm = ({
|
|
||||||
setOpenApiJson,
|
|
||||||
setToken,
|
|
||||||
isTokenValid,
|
|
||||||
setIsTokenValid,
|
|
||||||
}: TokenFormProps) => {
|
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
|
||||||
const token =
|
|
||||||
parseJson(localStorage.getItem('TryIt_securitySchemeValues') || '')
|
|
||||||
?.bearerAuth ?? '';
|
|
||||||
|
|
||||||
const updateToken = async (event: React.ChangeEvent<HTMLInputElement>) => {
|
|
||||||
localStorage.setItem(
|
|
||||||
'TryIt_securitySchemeValues',
|
|
||||||
JSON.stringify({ bearerAuth: event.target.value }),
|
|
||||||
);
|
|
||||||
await submitToken(event.target.value);
|
|
||||||
};
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
const validateToken = (openApiJson: any) =>
|
|
||||||
setIsTokenValid(!!openApiJson.tags);
|
|
||||||
|
|
||||||
const getJson = async (token: string) => {
|
|
||||||
setIsLoading(true);
|
|
||||||
|
|
||||||
return await fetch('https://api.twenty.com/open-api', {
|
|
||||||
headers: { Authorization: `Bearer ${token}` },
|
|
||||||
})
|
|
||||||
.then((res) => res.json())
|
|
||||||
.then((result) => {
|
|
||||||
validateToken(result);
|
|
||||||
setIsLoading(false);
|
|
||||||
|
|
||||||
return result;
|
|
||||||
})
|
|
||||||
.catch(() => setIsLoading(false));
|
|
||||||
};
|
|
||||||
|
|
||||||
const submitToken = async (token: string) => {
|
|
||||||
if (isLoading) return;
|
|
||||||
|
|
||||||
const json = await getJson(token);
|
|
||||||
|
|
||||||
setToken && setToken(token);
|
|
||||||
|
|
||||||
setOpenApiJson && setOpenApiJson(json);
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
(async () => {
|
|
||||||
await submitToken(token);
|
|
||||||
})();
|
|
||||||
});
|
|
||||||
|
|
||||||
// We load playground style using useEffect as it breaks remaining docs style
|
|
||||||
useEffect(() => {
|
|
||||||
const styleElement = document.createElement('style');
|
|
||||||
styleElement.innerHTML = TokenForm.toString();
|
|
||||||
document.head.append(styleElement);
|
|
||||||
|
|
||||||
return () => styleElement.remove();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
!isTokenValid && (
|
|
||||||
<Container>
|
|
||||||
<Form>
|
|
||||||
<label>
|
|
||||||
To load your playground schema,{' '}
|
|
||||||
<StyledLink href="https://app.twenty.com/settings/developers">
|
|
||||||
generate an API key
|
|
||||||
</StyledLink>{' '}
|
|
||||||
and paste it here:
|
|
||||||
</label>
|
|
||||||
<p>
|
|
||||||
<Input
|
|
||||||
className={token && !isLoading ? 'input invalid' : 'input'}
|
|
||||||
type="text"
|
|
||||||
readOnly={isLoading}
|
|
||||||
placeholder="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIyMD..."
|
|
||||||
defaultValue={token}
|
|
||||||
onChange={updateToken}
|
|
||||||
/>
|
|
||||||
<TokenInvalid
|
|
||||||
className={`${(!token || isLoading) && 'not-visible'}`}
|
|
||||||
>
|
|
||||||
Token invalid
|
|
||||||
</TokenInvalid>
|
|
||||||
<LoaderContainer>
|
|
||||||
<Loader className={`${!isLoading && 'not-visible'}`} />
|
|
||||||
</LoaderContainer>
|
|
||||||
</p>
|
|
||||||
</Form>
|
|
||||||
</Container>
|
|
||||||
)
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default TokenForm;
|
|
||||||
@ -2,14 +2,14 @@ export const dynamic = 'force-dynamic';
|
|||||||
|
|
||||||
import { Metadata } from 'next';
|
import { Metadata } from 'next';
|
||||||
|
|
||||||
import { Background } from '@/app/components/oss-friends/Background';
|
import { ActivityLog } from '@/app/_components/contributors/ActivityLog';
|
||||||
import { ActivityLog } from '@/app/developers/contributors/[slug]/components/ActivityLog';
|
import { Breadcrumb } from '@/app/_components/contributors/Breadcrumb';
|
||||||
import { Breadcrumb } from '@/app/developers/contributors/[slug]/components/Breadcrumb';
|
import { ContentContainer } from '@/app/_components/contributors/ContentContainer';
|
||||||
import { ContentContainer } from '@/app/developers/contributors/[slug]/components/ContentContainer';
|
import { ProfileCard } from '@/app/_components/contributors/ProfileCard';
|
||||||
import { ProfileCard } from '@/app/developers/contributors/[slug]/components/ProfileCard';
|
import { ProfileInfo } from '@/app/_components/contributors/ProfileInfo';
|
||||||
import { ProfileInfo } from '@/app/developers/contributors/[slug]/components/ProfileInfo';
|
import { PullRequests } from '@/app/_components/contributors/PullRequests';
|
||||||
import { PullRequests } from '@/app/developers/contributors/[slug]/components/PullRequests';
|
import { ThankYou } from '@/app/_components/contributors/ThankYou';
|
||||||
import { ThankYou } from '@/app/developers/contributors/[slug]/components/ThankYou';
|
import { Background } from '@/app/_components/oss-friends/Background';
|
||||||
import { findAll } from '@/database/database';
|
import { findAll } from '@/database/database';
|
||||||
import { pullRequestModel, userModel } from '@/database/model';
|
import { pullRequestModel, userModel } from '@/database/model';
|
||||||
|
|
||||||
@ -1,9 +1,9 @@
|
|||||||
export const dynamic = 'force-dynamic';
|
export const dynamic = 'force-dynamic';
|
||||||
|
|
||||||
import AvatarGrid from '@/app/components/AvatarGrid';
|
import AvatarGrid from '@/app/_components/contributors/AvatarGrid';
|
||||||
import { Header } from '@/app/components/developers/contributors/Header';
|
import { Header } from '@/app/_components/contributors/Header';
|
||||||
import { Background } from '@/app/components/oss-friends/Background';
|
import { Background } from '@/app/_components/oss-friends/Background';
|
||||||
import { ContentContainer } from '@/app/components/oss-friends/ContentContainer';
|
import { ContentContainer } from '@/app/_components/oss-friends/ContentContainer';
|
||||||
import { findAll } from '@/database/database';
|
import { findAll } from '@/database/database';
|
||||||
import { pullRequestModel, userModel } from '@/database/model';
|
import { pullRequestModel, userModel } from '@/database/model';
|
||||||
|
|
||||||
@ -1,27 +0,0 @@
|
|||||||
'use client';
|
|
||||||
|
|
||||||
import { createGraphiQLFetcher } from '@graphiql/toolkit';
|
|
||||||
import { GraphiQL } from 'graphiql';
|
|
||||||
import dynamic from 'next/dynamic';
|
|
||||||
|
|
||||||
import 'graphiql/graphiql.css';
|
|
||||||
|
|
||||||
// Create a named function for your component
|
|
||||||
function GraphiQLComponent() {
|
|
||||||
const fetcher = createGraphiQLFetcher({
|
|
||||||
url: 'https://api.twenty.com/graphql',
|
|
||||||
});
|
|
||||||
|
|
||||||
return <GraphiQL fetcher={fetcher} />;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Dynamically import the GraphiQL component with SSR disabled
|
|
||||||
const GraphiQLWithNoSSR = dynamic(() => Promise.resolve(GraphiQLComponent), {
|
|
||||||
ssr: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const GraphQLDocs = () => {
|
|
||||||
return <GraphiQLWithNoSSR />;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default GraphQLDocs;
|
|
||||||
@ -1,63 +0,0 @@
|
|||||||
import { ContentContainer } from '@/app/components/ContentContainer';
|
|
||||||
|
|
||||||
const DeveloperDocsLayout = ({ children }: { children: React.ReactNode }) => {
|
|
||||||
return (
|
|
||||||
<ContentContainer>
|
|
||||||
<div style={{ display: 'flex', flexDirection: 'row' }}>
|
|
||||||
<div
|
|
||||||
style={{
|
|
||||||
borderRight: '1px solid rgba(20, 20, 20, 0.08)',
|
|
||||||
paddingRight: '24px',
|
|
||||||
minWidth: '200px',
|
|
||||||
paddingTop: '48px',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<h4 style={{ textTransform: 'uppercase', color: '#B3B3B3' }}>
|
|
||||||
Install & Maintain
|
|
||||||
</h4>
|
|
||||||
<a style={{ textDecoration: 'none', color: '#333' }} href="/">
|
|
||||||
Local setup
|
|
||||||
</a>{' '}
|
|
||||||
<br />
|
|
||||||
<a style={{ textDecoration: 'none', color: '#333' }} href="/">
|
|
||||||
Self-hosting
|
|
||||||
</a>{' '}
|
|
||||||
<br />
|
|
||||||
<a style={{ textDecoration: 'none', color: '#333' }} href="/">
|
|
||||||
Upgrade guide
|
|
||||||
</a>{' '}
|
|
||||||
<br /> <br />
|
|
||||||
<h4 style={{ textTransform: 'uppercase', color: '#B3B3B3' }}>
|
|
||||||
Resources
|
|
||||||
</h4>
|
|
||||||
<a style={{ textDecoration: 'none', color: '#333' }} href="/">
|
|
||||||
Contributors Guide
|
|
||||||
</a>{' '}
|
|
||||||
<br />
|
|
||||||
<a
|
|
||||||
style={{ textDecoration: 'none', color: '#333' }}
|
|
||||||
href="/developers/docs/graphql"
|
|
||||||
>
|
|
||||||
GraphQL API
|
|
||||||
</a>{' '}
|
|
||||||
<br />
|
|
||||||
<a
|
|
||||||
style={{ textDecoration: 'none', color: '#333', display: 'flex' }}
|
|
||||||
href="/developers/rest"
|
|
||||||
>
|
|
||||||
Rest API
|
|
||||||
</a>
|
|
||||||
<a style={{ textDecoration: 'none', color: '#333' }} href="/">
|
|
||||||
Twenty UI
|
|
||||||
</a>{' '}
|
|
||||||
<br />
|
|
||||||
</div>
|
|
||||||
<div style={{ padding: '24px', minHeight: '80vh', width: '100%' }}>
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</ContentContainer>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DeveloperDocsLayout;
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
const DeveloperDocs = () => {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<h1>Developer Docs</h1>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default DeveloperDocs;
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
'use client';
|
|
||||||
|
|
||||||
/*import { API } from '@stoplight/elements';/
|
|
||||||
|
|
||||||
import '@stoplight/elements/styles.min.css';
|
|
||||||
|
|
||||||
/*
|
|
||||||
const RestApiComponent = ({ openApiJson }: { openApiJson: any }) => {
|
|
||||||
// We load spotlightTheme style using useEffect as it breaks remaining docs style
|
|
||||||
useEffect(() => {
|
|
||||||
const styleElement = document.createElement('style');
|
|
||||||
// styleElement.innerHTML = spotlightTheme.toString();
|
|
||||||
document.head.append(styleElement);
|
|
||||||
|
|
||||||
return () => styleElement.remove();
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<API apiDescriptionDocument={JSON.stringify(openApiJson)} router="hash" />
|
|
||||||
);
|
|
||||||
};*/
|
|
||||||
|
|
||||||
const RestApi = () => {
|
|
||||||
/* const [openApiJson, setOpenApiJson] = useState({});
|
|
||||||
|
|
||||||
const children = <RestApiComponent openApiJson={openApiJson} />;*/
|
|
||||||
|
|
||||||
return <>API</>;
|
|
||||||
|
|
||||||
// return <Playground setOpenApiJson={setOpenApiJson}>{children}</Playground>;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default RestApi;
|
|
||||||
@ -1,9 +0,0 @@
|
|||||||
const Developers = () => {
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<p>This page should probably be built on Framer</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Developers;
|
|
||||||
@ -10,6 +10,7 @@ body {
|
|||||||
padding: 0;
|
padding: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
|
font-family: var(--font-gabarito);
|
||||||
}
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
import { Metadata } from 'next';
|
import { Metadata } from 'next';
|
||||||
import { Gabarito, Inter } from 'next/font/google';
|
import { Gabarito, Inter } from 'next/font/google';
|
||||||
|
|
||||||
import { HeaderMobile } from '@/app/components/HeaderMobile';
|
import { HeaderMobile } from '@/app/_components/ui/layout/HeaderMobile';
|
||||||
|
|
||||||
import { FooterDesktop } from './components/FooterDesktop';
|
import { FooterDesktop } from './_components/ui/layout/FooterDesktop';
|
||||||
import { HeaderDesktop } from './components/HeaderDesktop';
|
import { HeaderDesktop } from './_components/ui/layout/HeaderDesktop';
|
||||||
import EmotionRootStyleRegistry from './emotion-root-style-registry';
|
import EmotionRootStyleRegistry from './emotion-root-style-registry';
|
||||||
|
|
||||||
import './layout.css';
|
import './layout.css';
|
||||||
@ -37,7 +37,7 @@ export default function RootLayout({
|
|||||||
children: React.ReactNode;
|
children: React.ReactNode;
|
||||||
}) {
|
}) {
|
||||||
return (
|
return (
|
||||||
<html lang="en" className={`${gabarito.className} ${inter.className}`}>
|
<html lang="en" className={`${gabarito.variable} ${inter.variable}`}>
|
||||||
<body>
|
<body>
|
||||||
<EmotionRootStyleRegistry>
|
<EmotionRootStyleRegistry>
|
||||||
<HeaderDesktop />
|
<HeaderDesktop />
|
||||||
|
|||||||
@ -1,8 +1,8 @@
|
|||||||
import { Background } from '@/app/components/oss-friends/Background';
|
import { Background } from '@/app/_components/oss-friends/Background';
|
||||||
import { Card, OssData } from '@/app/components/oss-friends/Card';
|
import { Card, OssData } from '@/app/_components/oss-friends/Card';
|
||||||
import { CardContainer } from '@/app/components/oss-friends/CardContainer';
|
import { CardContainer } from '@/app/_components/oss-friends/CardContainer';
|
||||||
import { ContentContainer } from '@/app/components/oss-friends/ContentContainer';
|
import { ContentContainer } from '@/app/_components/oss-friends/ContentContainer';
|
||||||
import { Header } from '@/app/components/oss-friends/Header';
|
import { Header } from '@/app/_components/oss-friends/Header';
|
||||||
|
|
||||||
export default async function OssFriends() {
|
export default async function OssFriends() {
|
||||||
const ossList = await fetch('https://formbricks.com/api/oss-friends');
|
const ossList = await fetch('https://formbricks.com/api/oss-friends');
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { ContentContainer } from './components/ContentContainer';
|
import { ContentContainer } from './_components/ui/layout/ContentContainer';
|
||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -1,72 +0,0 @@
|
|||||||
import { Metadata } from 'next';
|
|
||||||
import { compileMDX } from 'next-mdx-remote/rsc';
|
|
||||||
import remarkBehead from 'remark-behead';
|
|
||||||
import gfm from 'remark-gfm';
|
|
||||||
|
|
||||||
import { ContentContainer } from '../components/ContentContainer';
|
|
||||||
|
|
||||||
interface Release {
|
|
||||||
id: number;
|
|
||||||
name: string;
|
|
||||||
body: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
|
||||||
title: 'Twenty - Releases',
|
|
||||||
description: 'Latest releases of Twenty',
|
|
||||||
};
|
|
||||||
|
|
||||||
const Home = async () => {
|
|
||||||
const response = await fetch(
|
|
||||||
'https://api.github.com/repos/twentyhq/twenty/releases',
|
|
||||||
);
|
|
||||||
const data: Release[] = await response.json();
|
|
||||||
|
|
||||||
const releases = await Promise.all(
|
|
||||||
data.map(async (release) => {
|
|
||||||
let mdxSource;
|
|
||||||
try {
|
|
||||||
mdxSource = await compileMDX({
|
|
||||||
source: release.body,
|
|
||||||
options: {
|
|
||||||
mdxOptions: {
|
|
||||||
remarkPlugins: [gfm, [remarkBehead, { depth: 2 }]],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
mdxSource = mdxSource.content;
|
|
||||||
} catch (error) {
|
|
||||||
console.error('An error occurred during MDX rendering:', error);
|
|
||||||
mdxSource = `<p>Oops! Something went wrong.</p> ${error}`;
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
id: release.id,
|
|
||||||
name: release.name,
|
|
||||||
body: mdxSource,
|
|
||||||
};
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<ContentContainer>
|
|
||||||
<h1>Releases</h1>
|
|
||||||
|
|
||||||
{releases.map((release, index) => (
|
|
||||||
<div
|
|
||||||
key={release.id}
|
|
||||||
style={{
|
|
||||||
padding: '24px 0px 24px 0px',
|
|
||||||
borderBottom:
|
|
||||||
index === releases.length - 1 ? 'none' : '1px solid #ccc',
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<h2>{release.name}</h2>
|
|
||||||
<div>{release.body}</div>
|
|
||||||
</div>
|
|
||||||
))}
|
|
||||||
</ContentContainer>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default Home;
|
|
||||||
@ -1,18 +0,0 @@
|
|||||||
import { Background } from '@/app/ui/theme/background';
|
|
||||||
import { Border } from '@/app/ui/theme/border';
|
|
||||||
import { Color } from '@/app/ui/theme/colors';
|
|
||||||
import { Font } from '@/app/ui/theme/font';
|
|
||||||
import { Icon } from '@/app/ui/theme/icon';
|
|
||||||
import { Text } from '@/app/ui/theme/text';
|
|
||||||
|
|
||||||
export const Theme = {
|
|
||||||
color: Color,
|
|
||||||
border: Border,
|
|
||||||
background: Background,
|
|
||||||
text: Text,
|
|
||||||
spacingMultiplicator: 4,
|
|
||||||
icon: Icon,
|
|
||||||
font: Font,
|
|
||||||
spacing: (...args: number[]) =>
|
|
||||||
args.map((multiplicator) => `${multiplicator * 4}px`).join(' '),
|
|
||||||
};
|
|
||||||
@ -1,5 +1,5 @@
|
|||||||
import UserGuideContent from '@/app/components/user-guide/UserGuideContent';
|
import UserGuideContent from '@/app/_components/user-guide/UserGuideContent';
|
||||||
import { getPost } from '@/app/get-posts';
|
import { getPost } from '@/app/_server-utils/get-posts';
|
||||||
|
|
||||||
export default async function UserGuideSlug({
|
export default async function UserGuideSlug({
|
||||||
params,
|
params,
|
||||||
|
|||||||
@ -3,10 +3,13 @@ import { ReactNode } from 'react';
|
|||||||
import styled from '@emotion/styled';
|
import styled from '@emotion/styled';
|
||||||
import { usePathname } from 'next/navigation';
|
import { usePathname } from 'next/navigation';
|
||||||
|
|
||||||
import UserGuideSidebar from '@/app/components/user-guide/UserGuideSidebar';
|
import {
|
||||||
import UserGuideTableContents from '@/app/components/user-guide/UserGuideTableContents';
|
DeviceType,
|
||||||
import { Theme } from '@/app/ui/theme/theme';
|
useDeviceType,
|
||||||
import { DeviceType, useDeviceType } from '@/app/ui/utilities/useDeviceType';
|
} from '@/app/_components/client-utils/useDeviceType';
|
||||||
|
import { Theme } from '@/app/_components/ui/theme/theme';
|
||||||
|
import UserGuideSidebar from '@/app/_components/user-guide/UserGuideSidebar';
|
||||||
|
import UserGuideTableContents from '@/app/_components/user-guide/UserGuideTableContents';
|
||||||
|
|
||||||
const StyledContainer = styled.div`
|
const StyledContainer = styled.div`
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import UserGuideMain from '@/app/components/user-guide/UserGuideMain';
|
import UserGuideMain from '@/app/_components/user-guide/UserGuideMain';
|
||||||
|
|
||||||
export default async function UserGuideHome() {
|
export default async function UserGuideHome() {
|
||||||
return <UserGuideMain />;
|
return <UserGuideMain />;
|
||||||
|
|||||||
Reference in New Issue
Block a user