Add social preview page
This commit is contained in:
@@ -55,6 +55,7 @@ const Routes = () => {
|
||||
<Route path="/u/{userName}" page={UserPage} name="user" />
|
||||
<Route path="/u/{userName}/{projectTitle}" page={ProjectPage} name="project" />
|
||||
<Route path="/u/{userName}/{projectTitle}/ide" page={IdeProjectPage} name="ide" />
|
||||
<Route path="/u/{userName}/{projectTitle}/social-card" page={SocialCardPage} name="socialCard" />
|
||||
|
||||
<Private unauthenticated="home" role="admin">
|
||||
<Route path="/admin/users" page={UsersPage} name="users" />
|
||||
|
||||
@@ -4,9 +4,10 @@ import { Image as CloudinaryImage } from 'cloudinary-react'
|
||||
interface Props {
|
||||
image: string
|
||||
className?: string
|
||||
size?: number
|
||||
}
|
||||
|
||||
const Gravatar = ({ image, className = '' }: Props) => {
|
||||
const Gravatar = ({ image, size = 40, className = '' }: Props) => {
|
||||
return (
|
||||
<div
|
||||
className={
|
||||
@@ -17,7 +18,7 @@ const Gravatar = ({ image, className = '' }: Props) => {
|
||||
<CloudinaryImage
|
||||
cloudName="irevdev"
|
||||
publicId={image || 'CadHub/eia1kwru54g2kf02s2xx'}
|
||||
width={40}
|
||||
width={size}
|
||||
crop="scale"
|
||||
/>
|
||||
</div>
|
||||
|
||||
@@ -19,7 +19,7 @@ export const useSaveCode = () => {
|
||||
setNowError(!!error)
|
||||
}
|
||||
if (!currentUser || project?.user?.id !== currentUser?.sub) {
|
||||
return () => console.log('not your project')
|
||||
return () => {}
|
||||
}
|
||||
return (input: Prisma.ProjectUpdateInput) => {
|
||||
updateProject({ variables: { id: project.id, input } })
|
||||
|
||||
144
app/web/src/components/SocialCardCell/SocialCardCell.tsx
Normal file
144
app/web/src/components/SocialCardCell/SocialCardCell.tsx
Normal file
@@ -0,0 +1,144 @@
|
||||
import type { FindSocialCardQuery } from 'types/graphql'
|
||||
import type { CellSuccessProps, CellFailureProps } from '@redwoodjs/web'
|
||||
import Svg from 'src/components/Svg/Svg'
|
||||
import { Image as CloudinaryImage } from 'cloudinary-react'
|
||||
import Gravatar from 'src/components/Gravatar/Gravatar'
|
||||
import CadPackage from 'src/components/CadPackage/CadPackage'
|
||||
|
||||
export const QUERY = gql`
|
||||
query FindSocialCardQuery($userName: String!, $projectTitle: String) {
|
||||
userProject: userName(userName: $userName) {
|
||||
userName
|
||||
image
|
||||
Project(projectTitle: $projectTitle) {
|
||||
id
|
||||
title
|
||||
description
|
||||
mainImage
|
||||
createdAt
|
||||
updatedAt
|
||||
userId
|
||||
cadPackage
|
||||
Reaction {
|
||||
emote
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export const Loading = () => <div>Loading...</div>
|
||||
|
||||
export const Empty = () => <div>Empty</div>
|
||||
|
||||
export const Failure = ({ error }: CellFailureProps) => (
|
||||
<div style={{ color: 'red' }}>Error: {error.message}</div>
|
||||
)
|
||||
|
||||
export const Success = ({
|
||||
userProject,
|
||||
}: CellSuccessProps<FindSocialCardQuery>) => {
|
||||
const image = userProject?.Project?.mainImage
|
||||
const gravatar = userProject?.image
|
||||
return (
|
||||
<div className="flex-col flex h-screen bg-ch-gray-800 text-ch-gray-300">
|
||||
<div
|
||||
className="flex-grow grid"
|
||||
style={{ gridTemplateColumns: '7fr 5fr' }}
|
||||
>
|
||||
<div className="bg-ch-gray-800 relative">
|
||||
<div className="absolute bottom-0 left-0 transform scale-200 aspect-h-1 h-full -translate-x-24 translate-y-24 rotate-45 rounded-full overflow-hidden">
|
||||
{/* <CloudinaryImage
|
||||
cloudName="irevdev"
|
||||
publicId={image || 'CadHub/eia1kwru54g2kf02s2xx'}
|
||||
width={500}
|
||||
crop="scale"
|
||||
/> */}
|
||||
</div>
|
||||
|
||||
<div className="relative bg-ch-gray-760 bg-opacity-90 pt-10 pl-20 pr-12 h-full backdrop-filter backdrop-blur">
|
||||
<div className="flex justify-between items-center">
|
||||
<div className="flex items-center">
|
||||
{gravatar && (
|
||||
<Gravatar image={gravatar} className="w-14 h-14" size={60} />
|
||||
)}
|
||||
<div className="text-2xl font-fira-sans ml-6">
|
||||
{userProject?.userName}
|
||||
</div>
|
||||
</div>
|
||||
<CadPackage
|
||||
cadPackage={userProject?.Project?.cadPackage}
|
||||
className="p-2 rounded px-4"
|
||||
/>
|
||||
</div>
|
||||
|
||||
<h1 className="text-6xl font-fira-sans mt-16 capitalize">
|
||||
{userProject?.Project?.title.replace(/-/g, ' ')}
|
||||
</h1>
|
||||
|
||||
<p className="mt-10 text-2xl font-fira-sans text-ch-gray-400">
|
||||
{(userProject?.Project?.description || '').slice(0, 150)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-full overflow-hidden relative">
|
||||
<div className="absolute inset-0 flex items-center">
|
||||
<CloudinaryImage
|
||||
cloudName="irevdev"
|
||||
publicId={image || 'CadHub/eia1kwru54g2kf02s2xx'}
|
||||
width={500}
|
||||
height={522}
|
||||
crop="crop"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
className="h-24 grid bg-ch-gray-900 relative"
|
||||
style={{ gridTemplateColumns: '7fr 5fr' }}
|
||||
>
|
||||
<div className="flex items-center justify-center gap-16">
|
||||
{[
|
||||
{
|
||||
svg: 'reactions',
|
||||
title: 'Reactions',
|
||||
count: userProject?.Project?.Reaction?.length,
|
||||
},
|
||||
{
|
||||
svg: 'fork-new',
|
||||
title: 'Forks',
|
||||
count: 0,
|
||||
},
|
||||
].map(({ svg, title, count }, index) => (
|
||||
<div className="flex gap-4" key={index}>
|
||||
<Svg className="w-10" name={svg} />
|
||||
<div className="flex flex-col">
|
||||
<div className="text-3xl">{count}</div>
|
||||
<div className="text-xl text-ch-gray-400">{title}</div>
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<div className="flex items-center justify-center">
|
||||
<Svg className="w-10 md:w-16" name="favicon" />
|
||||
<div className="ml-2 md:ml-6 flex">
|
||||
{/* Because of how specific these styles are to this heading/logo and it doesn't need to be replicated else where as well as it's very precise with the placement of "pre-alpha" I think it's appropriate. */}
|
||||
<h2
|
||||
className="text-indigo-300 text-2xl md:text-5xl font-ropa-sans py-1 md:tracking-wider"
|
||||
style={{ letterSpacing: '0.3em' }}
|
||||
>
|
||||
CadHub
|
||||
</h2>
|
||||
<div
|
||||
className="text-pink-400 text-sm font-bold font-ropa-sans hidden md:block"
|
||||
style={{ paddingBottom: '2rem', marginLeft: '-1.8rem' }}
|
||||
>
|
||||
pre-alpha
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="h-3 relative bg-gradient-to-r from-blue-500 via-purple-500 to-pink-500" />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
@@ -13,6 +13,7 @@ type SvgNames =
|
||||
| 'flag'
|
||||
| 'floppy-disk'
|
||||
| 'fork'
|
||||
| 'fork-new'
|
||||
| 'gear'
|
||||
| 'lightbulb'
|
||||
| 'logout'
|
||||
@@ -22,6 +23,7 @@ type SvgNames =
|
||||
| 'photograph'
|
||||
| 'plus'
|
||||
| 'plus-circle'
|
||||
| 'reactions'
|
||||
| 'refresh'
|
||||
| 'save'
|
||||
| 'share'
|
||||
@@ -294,6 +296,39 @@ const Svg = ({
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
'fork-new': (
|
||||
<svg viewBox="0 0 44 35" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<circle
|
||||
cx="37.5926"
|
||||
cy="11.0463"
|
||||
r="4.10521"
|
||||
transform="rotate(90 37.5926 11.0463)"
|
||||
stroke="#79B2F8"
|
||||
strokeWidth="2.0526"
|
||||
/>
|
||||
<path
|
||||
d="M33.3431 11.0462L11.9351 11.0462C24.663 11.0462 19.2994 28.7435 31.0553 28.7435"
|
||||
stroke="#79B2F8"
|
||||
strokeWidth="2.0526"
|
||||
/>
|
||||
<circle
|
||||
cx="6.80367"
|
||||
cy="11.0463"
|
||||
r="4.10521"
|
||||
transform="rotate(90 6.80367 11.0463)"
|
||||
stroke="#79B2F8"
|
||||
strokeWidth="2.0526"
|
||||
/>
|
||||
<circle
|
||||
cx="35.9624"
|
||||
cy="28.744"
|
||||
r="4.10521"
|
||||
transform="rotate(90 35.9624 28.744)"
|
||||
stroke="#79B2F8"
|
||||
strokeWidth="2.0526"
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
gear: (
|
||||
<svg viewBox="0 0 19 18" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
@@ -421,6 +456,20 @@ const Svg = ({
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
reactions: (
|
||||
<svg viewBox="0 0 39 35" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path
|
||||
d="M11.3685 7.40424C12.3853 6.66677 13.7445 6.21539 15.174 6.21539C16.7174 6.21539 18.3268 7.40424 19.2807 9.22797C13.8753 11.5332 11.3685 17.1771 12.0536 22.7215C11.5324 23.0974 11.2977 23.2986 10.7673 23.723C10.5085 23.93 10.1407 23.93 9.8819 23.723C8.75687 22.8229 7.64408 22.055 6.58014 21.3208L6.58009 21.3207L6.39858 21.1955C5.28973 20.4298 4.22507 19.6873 3.31 18.8827C1.44249 17.2406 0.159668 15.302 0.159668 12.2584C0.159668 10.7521 0.730921 9.26001 1.66183 8.13847C2.5939 7.01554 3.93183 6.21546 5.47525 6.21546C6.90467 6.21546 8.26393 6.66682 9.28067 7.40427C9.68031 7.69414 10.0381 8.03767 10.3246 8.42447C10.6111 8.03766 10.9689 7.69412 11.3685 7.40424Z"
|
||||
fill="#FFA5D4"
|
||||
/>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
clipRule="evenodd"
|
||||
d="M38.1039 21.5456C38.1039 28.2024 32.7075 33.5987 26.0507 33.5987C19.394 33.5987 13.9976 28.2024 13.9976 21.5456C13.9976 14.8888 19.394 9.49237 26.0507 9.49237C32.7075 9.49237 38.1039 14.8888 38.1039 21.5456ZM30.5015 20.7908C31.8412 20.7908 32.9273 19.7047 32.9273 18.365C32.9273 17.0253 31.8412 15.9392 30.5015 15.9392C29.1618 15.9392 28.0757 17.0253 28.0757 18.365C28.0757 19.7047 29.1618 20.7908 30.5015 20.7908ZM24.0146 18.365C24.0146 19.7016 22.9311 20.7851 21.5945 20.7851C20.2579 20.7851 19.1743 19.7016 19.1743 18.365C19.1743 17.0284 20.2579 15.9448 21.5945 15.9448C22.9311 15.9448 24.0146 17.0284 24.0146 18.365ZM20.8725 24.5888C20.3795 24.1896 19.6562 24.2658 19.257 24.7589C18.8579 25.252 18.9341 25.9752 19.4272 26.3744C21.5168 28.0658 23.6982 29.0304 25.989 29.0473C28.283 29.0642 30.5062 28.1295 32.6744 26.3744C33.1675 25.9752 33.2437 25.252 32.8445 24.7589C32.4454 24.2658 31.7221 24.1896 31.229 24.5888C29.3448 26.114 27.6222 26.7619 26.0059 26.75C24.3865 26.7381 22.6932 26.0625 20.8725 24.5888Z"
|
||||
fill="#FFDF50"
|
||||
/>
|
||||
</svg>
|
||||
),
|
||||
refresh: (
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 14 17" fill="none">
|
||||
<path
|
||||
|
||||
13
app/web/src/pages/SocialCardPage/SocialCardPage.tsx
Normal file
13
app/web/src/pages/SocialCardPage/SocialCardPage.tsx
Normal file
@@ -0,0 +1,13 @@
|
||||
import { Link, routes } from '@redwoodjs/router'
|
||||
import SocialCardCell from 'src/components/SocialCardCell'
|
||||
|
||||
interface Props {
|
||||
userName: string
|
||||
projectTitle: string
|
||||
}
|
||||
|
||||
const SocialCardPage = ({ userName, projectTitle }: Props) => {
|
||||
return <SocialCardCell userName={userName} projectTitle={projectTitle} />
|
||||
}
|
||||
|
||||
export default SocialCardPage
|
||||
@@ -22,6 +22,7 @@ module.exports = {
|
||||
700: '#2A3038',
|
||||
600: '#3B3E4B',
|
||||
500: '#9F9FB4',
|
||||
400: '#A4A4B0',
|
||||
300: '#CFCFD8',
|
||||
},
|
||||
'ch-purple': {
|
||||
@@ -31,6 +32,7 @@ module.exports = {
|
||||
},
|
||||
'ch-blue': {
|
||||
600: '#79B2F8',
|
||||
500: '5098F1',
|
||||
300: '#08466F'
|
||||
},
|
||||
'ch-pink': {
|
||||
|
||||
Reference in New Issue
Block a user