diff --git a/.gitignore b/.gitignore index 1437c53..7a5437e 100644 --- a/.gitignore +++ b/.gitignore @@ -32,3 +32,6 @@ yarn-error.log* # vercel .vercel + +#purged +/purged \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..acf9043 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,20 @@ +{ + "cSpell.words": [ + "Kage", + "cstory", + "apos", + "dateofbirth", + "describedby", + "extralight", + "fullname", + "formify", + "imagepic", + "labelledby", + + "linkdin", + "multiselect", + "profilepic", + "upsert", + "useravatar" + ] +} \ No newline at end of file diff --git a/components/ActionAuth.js b/components/ActionAuth.js new file mode 100644 index 0000000..975397f --- /dev/null +++ b/components/ActionAuth.js @@ -0,0 +1,19 @@ +import Link from 'next/link'; + + +export default function LoginActionCard(props){ + return( + +
+
Personalize yours by signing in to your account.
+
+ +
+ Start +
+ +
+
+ + ) +} \ No newline at end of file diff --git a/components/Announcement.js b/components/Announcement.js new file mode 100644 index 0000000..1205a68 --- /dev/null +++ b/components/Announcement.js @@ -0,0 +1,20 @@ +import React from 'react'; + +export default function Announcement(){ + return( +
+
+
Join Big Events 🎊
+
Browse
+
+ + + +
+ + Be part of events & hackathons, building careers and leveraging your skill by taking internships & browsing job openings from top companies. + +
+
+ ) +} \ No newline at end of file diff --git a/components/ContentCard.js b/components/ContentCard.js new file mode 100644 index 0000000..75320f1 --- /dev/null +++ b/components/ContentCard.js @@ -0,0 +1,134 @@ +import { + Button, + IconHeart, + IconSave, + IconShare2, + IconActivity, + IconLock, +} from "@supabase/ui"; +import UserAvatar from "./UserAvatar"; +import Link from "next/link"; +import moment from "moment"; +import supabase from '../utils/initSupabase'; +import { useRouter } from "next/router"; + +export default function ContentCard(props) { + + const router =useRouter(); + + + async function NewLike(id){ + if(!supabase.auth.user()){ + alert('Please Log In To Perform This Action') + } + else{ + const {data}= await supabase.from('likes').select('post_id,user_id').filter('post_id','eq',id).filter('user_id','eq',supabase.auth.user().id); + + if (!data.length){ + await supabase.from('likes').insert([{user_id:supabase.auth.user().id,post_id:id}]) + alert('liked ❤️') +} +else{ + await supabase.from('likes').delete().filter('post_id','eq',id).filter('user_id','eq',supabase.auth.user().id) + alert('disliked 👎') +} + } + } + + function Like(id){ + NewLike(id) + } + + async function NewSave(id){ + if(!supabase.auth.user()){ + alert('Please Log In To Perform This Action') + } + else{ + const {data}= await supabase.from('saved').select('post_id,user_id').filter('post_id','eq',id).filter('user_id','eq',supabase.auth.user().id); + + if (!data.length){ + await supabase.from('saved').insert([{user_id:supabase.auth.user().id,post_id:id}]) + alert('saved 💾') + } + else{ + await supabase.from('saved').delete().filter('post_id','eq',id).filter('user_id','eq',supabase.auth.user().id) + alert('removed 😲') + } + } + } + + function Save(id){ + NewSave(id) + } + + + + + + return ( +
+
+
+ {" "} +
+ + + {props.name}  @{props.username} + + + + {moment(props.timestamp).fromNow()} + +
+
+ + +
+ +
+ + {props.category} + + {props.featured ? ( + + #featured + + ) : null} +
+ + +

+ {props.title} +

+ + +
+
+
Like(props.id)} className={`mr-4 flex align-middle hover:text-red-600 ${props.liked?'text-red-700':''}`}> + +
+ {/*
+ +
*/} +
Save(props.id)} className="mr-4 hover:text-purple-600"> + +
+ +
null} className={`mr-4 hover:text-green-600 ${props.isPrivate?'':'hidden'}`}> + +
+
+ +
+
+ +  
Share
+
+
+
+
+ ); +} diff --git a/components/Footer.js b/components/Footer.js new file mode 100644 index 0000000..37ef060 --- /dev/null +++ b/components/Footer.js @@ -0,0 +1,138 @@ +import React from 'react'; +import {Modal} from '@supabase/ui' +import {useState, useEffect, useRef} from 'react' +import supabase from '../utils/initSupabase' +import Link from 'next/link' + +export default function Footer(){ + const [user, setUser]=useState(null); + // early access mail + const [email, setEmail]= useState(''); + let buttonStatus= useRef(); + let inputStatus=useRef(); + + const [visibleFail, setVisibleFail] = useState(false); + const [visibleSuccess, setVisibleSuccess] = useState(false); + + + function toggleFail() { + setVisibleFail(!visibleFail); + } + + function toggleSuccess() { + setVisibleSuccess(!visibleSuccess); + } + + useEffect(()=>{ + const {data: authListener}= supabase.auth.onAuthStateChange( + async ()=> checkUser() + ) + + + + checkUser() + return ()=> { + authListener?.unsubscribe() + }; + }, []) + + async function checkUser(){ + const user= supabase.auth.user() + setUser(user) + } + + // Early access + async function sendEmailAddress(){ + + const re = /^[^\s@]+@[^\s@]+\.[^\s@]/ + if(!email.match(re) ) + { + await toggleFail() + } + + else { + const {data, error} = await supabase.from("early-access-email").select('email').filter('email','eq', email); + if (data.length>0){ + buttonStatus.current.innerHTML="Requested Earlier"; + buttonStatus.current.style.background="#9ca3af"; + } + else{ + await supabase.from("early-access-email").insert([{email}]) + toggleSuccess + } + } + } + + + + + return( + <> +
+ +
+
Explore
+ Home + Feeds + Pricing +
+ +
+
Company
+ About + Twitter + Instagram +
+ +
+
Support
+ Documentation + Contact + Request Feature +
+ +
+ + + Failed} + description="Try a valid email address" + visible={visibleFail} + onCancel={toggleFail} + onConfirm={toggleFail} + hideFooter + > + + + + Success} + description={

Thanks for subscribing to our Newsletter

} + visible={visibleSuccess} + onCancel={toggleSuccess} + onConfirm={toggleSuccess} + hideFooter + > +
+
+ + setEmail(e.target.value)} placeholder="Email" required type="email" className="pl-2 outline-none border-2 bg-gray-50 border-gray-200 placeholder-gray-500 rounded-md mt-2 mx-auto py-2 w-full md:w-1/3 p-1 text-sm font-normal"/> + + + +
+Receive exclusive updates and tips to make you the best creator... +
+
+ +
+© Cstory Inc. +
+ Privacy Policy +   + Terms +
+
+ +) +} \ No newline at end of file diff --git a/components/GlobalNavigationBar.js b/components/GlobalNavigationBar.js new file mode 100644 index 0000000..27ab26f --- /dev/null +++ b/components/GlobalNavigationBar.js @@ -0,0 +1,74 @@ +import React,{useState,useEffect} from 'react'; +import Link from 'next/link'; +import {IconBell, IconLogIn, IconTag, IconMenu, IconLogOut, IconBookOpen, IconUser, IconPlus, IconHome, IconEdit} from '@supabase/ui' +import supabase from '../utils/initSupabase'; +import {useRouter} from 'next/router' + + + + +export default function GlobalNavigation(){ +const [username, setUserName]=useState(''); +const [user, setUser]=useState(null); +const router= useRouter(); + useEffect(()=>{ + getUserName() + + async function getUserName(){ + const user = await supabase.auth.user(); + setUser(user); + if(user){ + const {data} = await supabase + .from('profiles') + .select('*') + .filter('id', 'eq', user.id) + setUserName(!data.length?" ":data[0].username)} + } + } + ,[user]); + + async function SignOut(){ + await supabase.auth.signOut() + router.push('/') + } + + + return(<> + + + ) +} \ No newline at end of file diff --git a/components/Header.js b/components/Header.js new file mode 100644 index 0000000..ef69d97 --- /dev/null +++ b/components/Header.js @@ -0,0 +1,21 @@ +import React from 'react'; +import Head from 'next/head' + +export default function Header(props){ +return( + + {props.title?props.title:'Cstory - Setup your micro-blogging community'} + + + + + + + + + + + +) +} \ No newline at end of file diff --git a/components/ProfilePicAvatar.js b/components/ProfilePicAvatar.js new file mode 100644 index 0000000..84b9041 --- /dev/null +++ b/components/ProfilePicAvatar.js @@ -0,0 +1,14 @@ +import Image from "next/image"; + +export default function ProfilePicAvatar(props){ + return( + profile + ) +} \ No newline at end of file diff --git a/components/SideNav.js b/components/SideNav.js new file mode 100644 index 0000000..23aeeac --- /dev/null +++ b/components/SideNav.js @@ -0,0 +1,38 @@ +import React from 'react'; +import Link from 'next/link'; +import {IconBell, IconLogIn, IconTag, IconMenu, IconLogOut, IconBookOpen, IconUser, IconPlus, IconHome, IconEdit} from '@supabase/ui' + +const SideNav=()=>{ + return( +
+
+
Links
+
+ + {/* {follow ? ( + follow.map((connection) => ( + + )) + ) : ( +

Opps you don't a connection yet!

+ )} */} + <> +    New + {/*    Home */} +    Edits + {/*  Tags */} + {/*  Notification */} +    Profile + {/*  Log Out */} + + +
+ ) +} + +export default SideNav; \ No newline at end of file diff --git a/components/UserAvatar.js b/components/UserAvatar.js new file mode 100644 index 0000000..42f65bf --- /dev/null +++ b/components/UserAvatar.js @@ -0,0 +1,14 @@ +import Image from "next/image"; + +export default function UserAvatar(props){ + return( + avatar + ) +} \ No newline at end of file diff --git a/components/UserCard.js b/components/UserCard.js new file mode 100644 index 0000000..be181b6 --- /dev/null +++ b/components/UserCard.js @@ -0,0 +1,22 @@ +import { Button } from '@supabase/ui'; +import UserAvatar from './UserAvatar'; +import Link from 'next/link'; + +export default function UserCard(props){ + return( + +
+
+ + +
{props.fullname}  @{props.username}
+ +
+
+

Subscribe

+ {/* */} +
+
+ + ) +} \ No newline at end of file diff --git a/constants/categories.js b/constants/categories.js new file mode 100644 index 0000000..2a2a232 --- /dev/null +++ b/constants/categories.js @@ -0,0 +1,18 @@ +export const categoryList=[ + 'technology', + 'career', + 'finance', + 'culture',, + 'programming', + 'diy', + 'nature', + 'health', + 'design', + 'entertainment', + 'relationship', + 'education', + 'fashion', + 'lifestyle', + 'food', + 'startup' +] \ No newline at end of file diff --git a/next.config.js b/next.config.js index 0d60710..55bc732 100644 --- a/next.config.js +++ b/next.config.js @@ -1,3 +1,6 @@ module.exports = { reactStrictMode: true, + images: { + domains: ['ywvrrnakhwjvloqqlbef.supabase.co'], + }, } diff --git a/package-lock.json b/package-lock.json index e01436f..089f5ea 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,12 +12,15 @@ "@tailwindcss/typography": "^0.4.1", "autoprefixer": "^10.3.1", "easymde": "^2.15.0", + "moment": "^2.29.1", + "multiselect-react-dropdown": "^2.0.5", "next": "11.0.1", "next-connect": "^0.10.1", "next-iron-session": "^4.2.0", "postcss": "^8.3.5", "react": "17.0.2", "react-dom": "17.0.2", + "react-loader-spinner": "^4.0.0", "react-markdown": "^6.0.2", "react-simplemde-editor": "^5.0.1", "tailwindcss": "^2.2.4", @@ -4048,11 +4051,27 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==", + "engines": { + "node": "*" + } + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "node_modules/multiselect-react-dropdown": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/multiselect-react-dropdown/-/multiselect-react-dropdown-2.0.5.tgz", + "integrity": "sha512-KIkhycdCrzLSMxnI9l2Q77BMx+qF3RYQwegZ5H70g3tcSae6h6JvEnwNm4oQWRiP0EMjlbYFl0aqd6KJEJyo5A==", + "peerDependencies": { + "react": "^16.7.0 || ^17.0.0-0" + } + }, "node_modules/nanoid": { "version": "3.1.23", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", @@ -5207,6 +5226,18 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "node_modules/react-loader-spinner": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/react-loader-spinner/-/react-loader-spinner-4.0.0.tgz", + "integrity": "sha512-RU2vpEej6G4ECei0h3q6bgLU10of9Lw5O+4AwF/mtkrX5oY20Sh/AxoPJ7etbrs/7Q3u4jN5qwCwGLRKCHpk6g==", + "dependencies": { + "prop-types": "^15.7.2" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, "node_modules/react-markdown": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-6.0.2.tgz", @@ -9907,11 +9938,22 @@ "resolved": "https://registry.npmjs.org/modern-normalize/-/modern-normalize-1.1.0.tgz", "integrity": "sha512-2lMlY1Yc1+CUy0gw4H95uNN7vjbpoED7NNRSBHE25nWfLBdmMzFCsPshlzbxHz+gYMcBEUN8V4pU16prcdPSgA==" }, + "moment": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz", + "integrity": "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" }, + "multiselect-react-dropdown": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/multiselect-react-dropdown/-/multiselect-react-dropdown-2.0.5.tgz", + "integrity": "sha512-KIkhycdCrzLSMxnI9l2Q77BMx+qF3RYQwegZ5H70g3tcSae6h6JvEnwNm4oQWRiP0EMjlbYFl0aqd6KJEJyo5A==", + "requires": {} + }, "nanoid": { "version": "3.1.23", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz", @@ -10793,6 +10835,14 @@ "resolved": "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz", "integrity": "sha512-w2GsyukL62IJnlaff/nRegPQR94C/XXamvMWmSHRJ4y7Ts/4ocGRmTHvOs8PSE6pB3dWOrD/nueuU5sduBsQ4w==" }, + "react-loader-spinner": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/react-loader-spinner/-/react-loader-spinner-4.0.0.tgz", + "integrity": "sha512-RU2vpEej6G4ECei0h3q6bgLU10of9Lw5O+4AwF/mtkrX5oY20Sh/AxoPJ7etbrs/7Q3u4jN5qwCwGLRKCHpk6g==", + "requires": { + "prop-types": "^15.7.2" + } + }, "react-markdown": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-6.0.2.tgz", diff --git a/package.json b/package.json index 7548035..4323745 100644 --- a/package.json +++ b/package.json @@ -14,12 +14,15 @@ "@tailwindcss/typography": "^0.4.1", "autoprefixer": "^10.3.1", "easymde": "^2.15.0", + "moment": "^2.29.1", + "multiselect-react-dropdown": "^2.0.5", "next": "11.0.1", "next-connect": "^0.10.1", "next-iron-session": "^4.2.0", "postcss": "^8.3.5", "react": "17.0.2", "react-dom": "17.0.2", + "react-loader-spinner": "^4.0.0", "react-markdown": "^6.0.2", "react-simplemde-editor": "^5.0.1", "tailwindcss": "^2.2.4", diff --git a/pages/404.js b/pages/404.js index eba5832..d4bcc54 100644 --- a/pages/404.js +++ b/pages/404.js @@ -1,9 +1,11 @@ import Image from 'next/image' +import Header from '../components/Header' export default function Error404(){ return(
-
+
+
404

Opps! you are not alone...

diff --git a/pages/500.js b/pages/500.js index 156e242..1f23aec 100644 --- a/pages/500.js +++ b/pages/500.js @@ -1,9 +1,11 @@ import Image from 'next/image' +import Header from '../components/Header' export default function Error500(){ return(
-
+
+
404

Sorry! we are solving this glitch immediately...

diff --git a/pages/[username]/[title].js b/pages/[username]/[title].js new file mode 100644 index 0000000..4d4c645 --- /dev/null +++ b/pages/[username]/[title].js @@ -0,0 +1,85 @@ +import { useRouter } from 'next/router' +import supabase from "../../utils/initSupabase"; +import {useEffect,useState} from 'react' +import dynamic from 'next/dynamic' +import Loader from "react-loader-spinner"; +import Header from '../../components/Header'; +import Link from 'next/link' + + + +const ReactMarkdown= dynamic(() => import('react-markdown'), { ssr: false }) +export default function PostView(){ + + const [post,setPost]=useState(null) + const [creator, setCreator]=useState(null) + const router=useRouter(); + const [loading, setLoading] = useState(true); + const {username,title}=router.query; + +useEffect(()=>{ +getCreator() + + async function getCreator(){ + const {data}= + await supabase + .from('profiles') + .select('username,id') + .filter('username', 'eq',username) ; + await setCreator(!data.length?null:data[0].id) + + } + +},[title,username]) + +useEffect(()=>{ + getPost() + async function getPost(){ + const {data}= + await supabase + .from('posts') + .select('title,content,user_id,creator: user_id(fullname,username)') + .filter('user_id','eq',creator) + .filter('title','eq',title===undefined?' ':title.replaceAll('-',' ')) + await setPost(!data?null:data[0]) + if(data){ + setLoading(false) + } + } +},[creator,title]) + + + + +while (loading){ + return (
+
+ +
+
) + } + + if (post===undefined) { + return
Not found
+ } + return ( +
+
+ +

{post.title}

+

{post.creator.fullname}

+
+ {// eslint-disable-next-line react/no-children-prop + + + }
+
+ ) +} + diff --git a/pages/[username]/index.js b/pages/[username]/index.js new file mode 100644 index 0000000..6f5ed05 --- /dev/null +++ b/pages/[username]/index.js @@ -0,0 +1,224 @@ +// pages/cstory.js +import { useState, useEffect, useCallback } from "react"; +import Link from "next/link"; +import dynamic from "next/dynamic"; +import supabase from "../../utils/initSupabase"; +import { useRouter } from "next/dist/client/router"; +import { + Auth, + Input, + Button, + IconSearch, + IconMoreHorizontal, + IconTwitter, + IconDribbble, + IconFacebook, + IconLinkedin, + IconLink, + IconGitHub, +} from "@supabase/ui"; +import Loader from "react-loader-spinner"; +import ContentCard from "../../components/ContentCard"; +import Header from "../../components/Header"; + +const DynamicImage = dynamic( + () => import("../../components/ProfilePicAvatar"), + { ssr: false } +); + +export default function Index(props) { + const [posts, setPosts] = useState([]); + const [userProfile, setUserProfile] = useState([]); + const [loading, setLoading] = useState(true); + const router = useRouter(); + const { username } = router.query; + + useEffect(() => { + getUserProfile(); + + async function getUserProfile() { + const profile = await supabase + .from("profiles") + .select("*") + .filter("username", "eq", username); + + if (!profile.data) { + router.push("/404"); + } else { + setUserProfile(profile.data[0]); + const { data } = await supabase + .from("posts") + .select( + `id,featured,category,content,inserted_at,isPrivate,title,user_id, creator: user_id(username,fullname,avatar_url)` + ) + .filter("user_id", "eq", userProfile ? userProfile.id : ""); + // .range(0,currentRange) + if (!data) { + return null; + } else { + setPosts(data); + setLoading(false); + } + } + } + }, [username, userProfile, router]); + + while (loading) { + return ( +
+
+ +
+
+ ); + } + + return ( +
+
+
+
+
+
+ +
+
+ + {userProfile.fullname} + + + @{userProfile.username} + +
+ {userProfile.bio ? ( +
+

{userProfile.bio}

+
+ ) : ( +
+

-

+
+ )} + +
+
+ {userProfile.twitter ? ( + + + + ) : ( + "" + )} + {userProfile.dribble ? ( + + + + ) : ( + "" + )} + {userProfile.facebook ? ( + + + + ) : ( + "" + )} + {userProfile.linkdn ? ( + + + + ) : ( + "" + )} + {userProfile.github ? ( + + + + ) : ( + "" + )} + {userProfile.website ? ( + + + + ) : ( + "" + )} +
+
+ +
+
+ Subscribe[beta] +
+
+
+ +
+
/{userProfile.username}'s Stories
+
+ {!posts.length ? ( +
+
+ Nothing Here ... +
+
+ ) : ( + posts.map((post, index) => ( + + )) + )} +
+
+
+
+ ); +} diff --git a/pages/_app.js b/pages/_app.js index b373827..5b430c7 100644 --- a/pages/_app.js +++ b/pages/_app.js @@ -1,183 +1,15 @@ -import '../styles/globals.css' -import Link from 'next/link'; -import {useState, useEffect, useRef} from 'react' -import {useRouter} from 'next/router' -import supabase from '../utils/initSupabase' +import "../styles/globals.css"; +import Footer from "../components/Footer"; +import GlobalNavigation from '../components/GlobalNavigationBar' function MyApp({ Component, pageProps }) { - const router= useRouter(); - const [user, setUser]=useState(null); - // early access mail - const [email, setEmail]= useState(""); - let buttonStatus= useRef(); - let inputStatus=useRef(); - - useEffect(()=>{ - const {data: authListener}= supabase.auth.onAuthStateChange( - async ()=> checkUser() - ) - - checkUser() - return ()=> { - authListener?.unsubscribe() - }; - }, []) - - async function checkUser(){ - const user= supabase.auth.user() - setUser(user) - } - - async function sendEmailAddress(){ - const {data, error} = await supabase.from("early-access-email").select('*').filter('email','eq', email); - - - if (data.length>0){ - - const re = /^[^\s@]+@[^\s@]+\.[^\s@]/ - if(!email.match(re) ) - { - inputStatus.current.placeholder="Please insert a valid email"; - buttonStatus.current.style.background="#ffa0a0"; - console.log(buttonStatus) - } - else { - buttonStatus.current.innerHTML="Requested Earlier"; - buttonStatus.current.style.background="#9ca3af"; - } - } - - - - else{ - await supabase.from("early-access-email").insert([{email}]) - router.push("/subscribe/early-access") - - } - - - } - - return( -
- -
- -
- -{/* Footer */} -
- -
-
Explore
- Feeds - Trending - Tags - Hack it -
- -
-
Company
- About Scrawlo - Career - Become an Ambassador -
- -
-
Support
- Documentation - Contact - Request Feature -
- + return ( +
+ + +
- -
- - setEmail(e.target.value)} placeholder="Email" required type="email" className="pl-2 outline-none border-2 bg-gray-50 border-gray-200 placeholder-gray-500 rounded-md mt-2 mx-auto w-full md:w-1/3 p-1 text-sm font-normal"/> - - - -
- Write, read, build a community and reach out to your audience in millions... -
-
- -
- © Scrawlo Inc. -
- Privacy Policy -   - Terms -
-
-{/* Footer Ends */} - - -
- ) - + ); } -export default MyApp +export default MyApp; diff --git a/pages/auth.js b/pages/auth.js new file mode 100644 index 0000000..d587198 --- /dev/null +++ b/pages/auth.js @@ -0,0 +1,68 @@ +import { useState, useEffect, useRef } from "react"; +import { Auth } from "@supabase/ui"; +import supabase from "../utils/initSupabase"; +import { useRouter } from "next/router"; +import Loader from "react-loader-spinner"; +import Header from "../components/Header"; + +function Profile(props) { + const { user } = Auth.useUser(); + const [loading, setLoading] = useState(true); + const router = useRouter(); + + useEffect(() => { + getProfile(); + async function getProfile() { + const { data } = await supabase + .from("profiles") + .select() + .filter( + "id", + "eq", + supabase.auth.user() === null ? " " : supabase.auth.user().id + ); + + if (!data) { + setLoading(false); + } else { + if (data[0].username) { + router.push(`/${data[0].username}`); + } else { + router.push("/profile"); + } + } + } + }, [user, loading, router]); + + while (loading) { + return ( +
+
+ +
+
+ ); + } + + return ( +
+
+ {props.children} +
+ ); +} + +export default function AuthProfile() { + return ( + + + + + + ); +} diff --git a/pages/connection.js b/pages/connection.js new file mode 100644 index 0000000..b8a5905 --- /dev/null +++ b/pages/connection.js @@ -0,0 +1,3 @@ +export default function Test(){ + return null +} \ No newline at end of file diff --git a/pages/create-post.js b/pages/create-post.js deleted file mode 100644 index 3a76fe3..0000000 --- a/pages/create-post.js +++ /dev/null @@ -1,57 +0,0 @@ -// pages/create-post.js -import { useState } from 'react' -import { v4 as uuid } from 'uuid' -import { useRouter } from 'next/router' -import dynamic from 'next/dynamic' -import "easymde/dist/easymde.min.css" -import supabase from "../utils/initSupabase"; - -const SimpleMDE = dynamic(() => import('react-simplemde-editor'), { ssr: false }) -const initialState = { title: '', content: '' } - -function CreatePost() { - const [post, setPost] = useState(initialState) - const { title, content } = post - const router = useRouter() - function onChange(e) { - setPost(() => ({ ...post, [e.target.name]: e.target.value })) - } - async function createNewPost() { - if (!title || !content) return - const user = supabase.auth.user() - const id = uuid() - post.id = id - const { data } = await supabase - .from('posts') - .insert([ - { title, content, user_id: user.id, user_email: user.email } - ]) - .single() - router.push(`/posts/${data.id}`) - } - - return ( -
-

Create new post

- - setPost({ ...post, content: value })} - /> - -
- ) -} - -export default CreatePost \ No newline at end of file diff --git a/pages/draft.js b/pages/draft.js new file mode 100644 index 0000000..f0de925 --- /dev/null +++ b/pages/draft.js @@ -0,0 +1,3 @@ +export default function Draft(){ + return null +} \ No newline at end of file diff --git a/pages/edit-post/[id].js b/pages/edit-post/[id].js deleted file mode 100644 index 49d5435..0000000 --- a/pages/edit-post/[id].js +++ /dev/null @@ -1,60 +0,0 @@ -// pages/edit-post/[id].js -import { useEffect, useState } from 'react' -import { useRouter } from 'next/router' -import dynamic from 'next/dynamic' -import "easymde/dist/easymde.min.css" -import supabase from "../../utils/initSupabase"; - -const SimpleMDE = dynamic(() => import('react-simplemde-editor'), { ssr: false }) - -function EditPost() { - const [post, setPost] = useState(null) - const router = useRouter() - const { id } = router.query - - useEffect(() => { - fetchPost() - async function fetchPost() { - if (!id) return - const { data } = await supabase - .from('posts') - .select() - .filter('id', 'eq', id) - .single() - setPost(data) - } - }, [id]) - if (!post) return null - function onChange(e) { - setPost(() => ({ ...post, [e.target.name]: e.target.value })) - } - const { title, content } = post - async function updateCurrentPost() { - if (!title || !content) return - await supabase - .from('posts') - .update([ - { title, content } - ]) - .match({ id }) - router.push('/my-posts') - } - return ( -
-

Edit post

- - setPost({ ...post, content: value })} /> - -
- ) -} - -export default EditPost \ No newline at end of file diff --git a/pages/explore.js b/pages/explore.js new file mode 100644 index 0000000..d937105 --- /dev/null +++ b/pages/explore.js @@ -0,0 +1,202 @@ +import { useState, useEffect, useRef, useCallback} from 'react' +import { Auth, Input, Button, IconSearch, IconMoreHorizontal} from "@supabase/ui"; +import supabase from "../utils/initSupabase"; +import {useRouter} from 'next/router'; +import Loader from "react-loader-spinner"; +import ContentCard from "../components/ContentCard"; +import LoginActionCard from "../components/ActionAuth"; +import {categoryList} from '../constants/categories' +import Header from '../components/Header' + + export default function Explore(props){ + const [loading, setLoading] = useState(true); + const loadMore=useRef(null); + const router=useRouter() + const [posts, setPosts] = useState([]) + const [currentRange, setRange]=useState(10) + const [currentCategory,setCategory]=useState('programming'); + const [search,setSearch]=useState(''); + + + + const fetchPosts=useCallback(()=>{ + + Get() + async function Get() { + const {id}=supabase.auth.user + if(id){ + return null + // router.push('/home') + } + else{ + const { data } = await supabase + .from('posts') + .select(`category,content,inserted_at,isPrivate,featured,title,user_id, creator: user_id(username,fullname,avatar_url)`) + .filter('category', 'eq', currentCategory) + .range(0,currentRange) + + if(!data){ + setLoading(false); + } + else{ + setLoading(false); + setPosts(data) + } + } + + } +}, [currentCategory, currentRange]); + + +useEffect(() => { + fetchPosts() +}, [fetchPosts]) + + + async function Search(){ + if(search){ + await router.push(`/search?q=${search}`) + } + } + + + + + + + + + + + while (loading){ + return (
+
+ +
+
) + } + + + return ( +
+
+
+
+
Quick Link
+
+ +
+ + + +
+
+
Posts
+
+{setSearch(e.target.value)}} + className="h-1" + actions={[ +

+ Search +

]} +/> +
+
+ +{/* posts */} +
+ {!posts.length? + (
+
Nothing Here ...
+
) + : + (posts.map((post, index)=>))} + +
+ + +
+
+
Join Big Events 🎊
+
Browse
+
+ + + +
+ + Be part of events & hackathons, building careers and leveraging your skill by taking internships & browsing job openings from top companies. + +
+
+ +{/* loading more */} + {/*
+
+ +
+
*/} + +
+
setRange((value)=>value+10)} className="text-sm flex mx-auto font-medium hover:text-purple-600 text-gray-800 text-center">Load More ...
+
+
+ +
+
+
+
Interests
+
More...
+
+ + +{/* category */} +
+ {categoryList.map((cat)=>setCategory(cat)} key={cat} className="font-extralight text-gray-800 cursor-pointer hover:text-purple-700 mr-2 mb-2">{cat})} + +
+
+ + + +
+
+
Join Big Events 🎊
+
Browse
+
+ + + +
+ + Be part of events & hackathons, building careers and leveraging your skill by taking internships & browsing job openings from top companies. + +
+
+ +
+ + + +
+ + + ) +} + + + + diff --git a/pages/index.js b/pages/index.js index 4c9a3df..3039481 100644 --- a/pages/index.js +++ b/pages/index.js @@ -1,205 +1,329 @@ // pages/index.js import { useState, useEffect } from "react"; import Link from "next/link"; -import Image from "next/image" -import supabase from "../utils/initSupabase"; +import Image from "next/image"; +// import supabase from "../utils/initSupabase"; +import "react-loader-spinner/dist/loader/css/react-spinner-loader.css"; +// import Loader from "react-loader-spinner"; +import Header from '../components/Header'; +import {IconArrowRight} from '@supabase/ui' export default function Home() { const [posts, setPosts] = useState([]); const [loading, setLoading] = useState(true); - - useEffect(() => { - fetchPosts(); - const mySubscription = supabase - .from("posts") - .on("*", () => fetchPosts()) - .subscribe(); - return () => supabase.removeSubscription(mySubscription); - }, []); - async function fetchPosts() { - const { data, error } = await supabase.from("posts").select(); - setPosts(data); - setLoading(false); - } + + + // useEffect(() => { + // fetchPosts(); + // const mySubscription = supabase + // .from("posts") + // .on("*", () => fetchPosts()) + // .subscribe(); + // return () => supabase.removeSubscription(mySubscription); + // }, []); + // async function fetchPosts() { + // const { data, error } = await supabase.from("posts").select(); + // setPosts(data); + // setLoading(false); + // } + return ( +
+
+ {/* Copy starts */} +
+

+ Setup your micro-blogging community +
+ without writing any line of code +

+ + + Get Started  + + + *free trial + {/* /profile to / */} +
+ {/* Copy ends */} - -
-{/* Copy starts */} -
-

All that you need to start writing to the

world!

-

Where your voice will be heard. Scrawlo gives blog space for writers and content creators to write about whatever they want, without being censored. -

-Start a Scrawlo -{/* /profile to / */} -
- label -
-
-{/* Copy ends */} - -
- -
- - - Spacecraft - A line styled icon from Orion Icon Library. - - - - - -Launch your space -
- -
- - Social - A line styled icon from Orion Icon Library. - - - - - - - - - -Connect & build your community -
- -
- - - Luxury - A line styled icon from Orion Icon Library. - - - - -Learn from PRO creators - -
- -
- -{/* Convince them */} -
-

Yes! you own it

-
- -
-scrawler_with_cup -

Share scrawls with swags

-

Create a scrawl and share with your audience. Scrawls are instant, unique for creative expression. Let the world see your scrawls, including photos, videos, drawings, and more. Make connections with strangers through likes, follows, comments and more.

-
- -
-scrawler_with_cup -

Free space for everyone

- -

-Scrawlo promotes your blog, and gives an additional ecosystem for people to read quickly or click through links. No more lengthy introductions and abstracts just to get to the good stuff. Bloggers can now focus on what they do best and get readers to visit their blogs directly. Users can simply click on the Scrawlo link in the post, which will take them directly to the blog. -

-
- -
-scrawler_with_cup -

Reach your brand goal

-

-Scrawlo is a tool that helps you create content that gets shared. When used strategically, scrawlo can help you reach your brand goals, increase engagement, and grow your audience. It's the only tool you need to create amazing original content. We built it to be easy to use, with features that help all types of businesses produce engaging content quickly and easily. -

-
- -
-
- - - -{/* WordCopy Start */} -
- - label - - -
-

- - Feather - A line styled icon from Orion Icon Library. - - - -Scrawlo - -

- -

-A personal space for you to start blogging, reading and building community. -Write amazing stuffs anywhere, connect & create memories, be in charge of everything. -

-
- -
-{/* Ends Here */} -{/* Content start */} -

- Trending -

-
-
- { - - loading?( -

Loading ...

) - : - !posts.length?(

No posts.

) - : - (posts.map(post => ( - -
-

{post.title}

-

Author: Scrawlo Kage

-
- ) - )) - } -{/* Checks if its loading above */} +
+
+ + Spacecraft + + + + + + + Launch + +
+ +
+ + Social + + + + + + + + + + + Connect & Build + +
+ +
+ + Pro + A line styled icon from Orion Icon Library. + + + + + + Be a PRO + +
+ + {/* Convince them */} +
+

+ Yes! you own it +

+
+
+ cstory_with_cup +
+ Share with swags +
+
+ Create a story and share with your audience. +
+
+ +
+ cstory_with_cup +
+ Minimalist Interface +
+ +
+ Bloggers can now focus on what they do best and get readers to + visit their blogs directly. +
+
+ +
+ cstory_with_cup +
+ Reach your goal +
+
+ Cstory help you reach your brand + goals, increase engagement, and grow your audience. +
+
+
+
+ + {/* WordCopy Start */} +
+ label + +
+
+ + + Cstory + +
+ +

+ A personal space for you to start blogging, reading and building + community. Write amazing stuffs anywhere, connect & create memories, + be in charge of everything. +

+
+ +
+ + +
+ Log In/Sign Up +
+ + {/* Ends Here */} +
-
- ) + ); } diff --git a/pages/m/edit/[title].js b/pages/m/edit/[title].js new file mode 100644 index 0000000..348732e --- /dev/null +++ b/pages/m/edit/[title].js @@ -0,0 +1,138 @@ +// pages/new.js +import { useState, useEffect, useCallback } from "react"; +import { Select, Checkbox, Input } from "@supabase/ui"; +import { v4 as uuid } from "uuid"; +import { useRouter } from "next/router"; +import dynamic from "next/dynamic"; +import "easymde/dist/easymde.min.css"; +import supabase from "../../../utils/initSupabase"; +import { categoryList } from "../../../constants/categories"; +import Loader from "react-loader-spinner"; +import Header from "../../../components/Header"; + +const SimpleMDE = dynamic(() => import("react-simplemde-editor"), { + ssr: false, +}); +const initialState = { title: "", content: "", category: "" }; + +function Edit() { + const [post, setPost] = useState(initialState); + + const router = useRouter(); + const [checked, setChecked] = useState(false); + const [loading, setLoading] = useState(true); + const { title } = router.query; + + const fetchPost = useCallback(() => { + const user = supabase.auth.user(); + Get(); + async function Get() { + + const { data } = await supabase + .from("posts") + .select( + `category,content,inserted_at,isPrivate,title,user_id,id,creator: user_id(username,fullname)` + ) + .filter("user_id", "eq", user.id) + .filter("title", "eq", title.replaceAll("-", " ")); + // .range(0,currentRange) + + if (!data) { + return null; + } else { + setPost(data[0]); + setChecked(data[0].isPrivate); + setLoading(false); + } + } + }, [title]); + + useEffect(() => { + fetchPost(); + }, [fetchPost]); + + function onChange(e) { + setPost(() => ({ ...post, [e.target.name]: e.target.value })); + } + + function handleOnChange() { + setChecked(!checked); + } + + async function UpdatePost() { + if (!title || !post.content) return null; + await supabase + .from("posts") + .update([ + { + title: post.title, + content: post.content, + category: post.category, + isPrivate: checked, + }, + ]) + .filter("user_id", "eq", supabase.auth.user().id) + .filter("id", "eq", post.id); + router.push(`/${post.creator.username}/${post.title.replaceAll(" ", "-")}`); + } + + while (loading) { + return ( +
+
+ +
+
+ ); + } + + return ( +
+
+

+ Edit +

+ + +
+ +
+ setPost({ ...post, content: value })} + /> + +
+ +
+ + +
+ ); +} + +export default Edit; diff --git a/pages/m/story.js b/pages/m/story.js new file mode 100644 index 0000000..656064c --- /dev/null +++ b/pages/m/story.js @@ -0,0 +1,121 @@ +// pages/cstory.js +import { useState, useEffect } from 'react' +import Link from 'next/link' +import supabase from "../../utils/initSupabase"; +import { Auth, Input, Button, IconSearch, IconMoreHorizontal} from "@supabase/ui"; +import Loader from "react-loader-spinner"; +import Header from '../../components/Header'; + + function MyPosts(props) { + const [posts, setPosts] = useState([]) + const [username, setUserName]=useState(); + const [loading, setLoading] = useState(true); + + useEffect(() => { + fetchPosts() + }, [posts]) + + async function fetchPosts() { + const user = supabase.auth.user() + const { data } = await supabase + .from('posts') + .select(`id,category,content,inserted_at,isPrivate,title,user_id, creator: user_id(username,fullname)`) + .filter('user_id', 'eq', user.id) + // .range(0,currentRange) + if(!data){ + setLoading(false) + return null; + + } + else{ + setPosts(data); + setLoading(false) + } + } + + async function deletePost(id,title) { + await supabase + .from('posts') + .delete() + .match({ id,title }) + fetchPosts() + } + + useEffect(()=>{ + getUserName() + + async function getUserName(){ + const user = await supabase.auth.user() + if (user){ + const {data} = await supabase + .from('profiles') + .select('*') + .filter('id', 'eq', user.id) + setUserName(data[0].username) + } + + } + }, [username]) + + while (loading){ + return (
+
+ +
+
) + } + + if (username) { + return ( +
+
+

My Story

+
+ + + { + posts.map((post,index) => ( +
+

{post.title}

+ Edit + View + +
+ )) + } + + +
+
+ )} + + else { + return props.children; + } + +} + + +export default function AuthProfile() { + return ( + + + + + + ); +} \ No newline at end of file diff --git a/pages/my-posts.js b/pages/my-posts.js deleted file mode 100644 index 1e7efb8..0000000 --- a/pages/my-posts.js +++ /dev/null @@ -1,47 +0,0 @@ -// pages/my-posts.js -import { useState, useEffect } from 'react' -import Link from 'next/link' -import supabase from "../utils/initSupabase"; - -export default function MyPosts() { - const [posts, setPosts] = useState([]) - useEffect(() => { - fetchPosts() - }, []) - - async function fetchPosts() { - const user = supabase.auth.user() - const { data } = await supabase - .from('posts') - .select('*') - .filter('user_id', 'eq', user.id) - setPosts(data) - } - async function deletePost(id) { - await supabase - .from('posts') - .delete() - .match({ id }) - fetchPosts() - } - return ( -
-

My Posts

-
- { - posts.map((post, index) => ( -
-

{post.title}

- Edit - View - -
- )) - } -
-
- ) -} diff --git a/pages/new.js b/pages/new.js new file mode 100644 index 0000000..89e81ce --- /dev/null +++ b/pages/new.js @@ -0,0 +1,108 @@ +// pages/new.js +import { useState , useEffect} from 'react' +import {Select, Checkbox, Input} from '@supabase/ui' +import { v4 as uuid } from 'uuid' +import { useRouter } from 'next/router' +import dynamic from 'next/dynamic' +import "easymde/dist/easymde.min.css" +import supabase from "../utils/initSupabase"; +import {categoryList} from '../constants/categories' +import Header from '../components/Header' + +const SimpleMDE = dynamic(() => import('react-simplemde-editor'), { ssr: false }) +const initialState = { title: '', content: '',category:'technology'} + +function New() { + const [post, setPost] = useState(initialState) + const router = useRouter() + const [username, setUserName]=useState('') + const [checked, setChecked]=useState(false) + + function onChange(e) { + setPost(() => ({...post,[e.target.name]: e.target.value })) + } + + function handleOnChange() { + setChecked(!checked); + } + + useEffect(()=>{ +getUserName() + + async function getUserName(){ + const user = await supabase.auth.user() + const {data} = await supabase + .from('profiles') + .select('*') + .filter('id', 'eq', user.id) + if(data[0]===undefined){ + router.push('/profile') + } + else{ + setUserName(data[0].username) + } + } + + },[username,router]) + + + async function createNewPost() { + if (!post.title || !post.content) return null; + if (username===null) router.push('/profile'); + else{ + const {id} = await supabase.auth.user() + await supabase + .from('posts') + .insert([ + { title:post.title, content:post.content,category:post.category,isPrivate:checked,user_id:id} + ]) + router.push(`/${username}/${post.title.replaceAll(' ', '-')}`) + } + + } + + return ( +
+
+

Create

+ + +
+ +
+ setPost({ ...post, content: value })} + + /> + +
+ +
+ + +
+ ) +} + +export default New; \ No newline at end of file diff --git a/pages/notification.js b/pages/notification.js new file mode 100644 index 0000000..b9b54ac --- /dev/null +++ b/pages/notification.js @@ -0,0 +1,3 @@ +export default function Notification(){ + return null +} \ No newline at end of file diff --git a/pages/posts/[id].js b/pages/posts/[id].js deleted file mode 100644 index 8009680..0000000 --- a/pages/posts/[id].js +++ /dev/null @@ -1,47 +0,0 @@ -// pages/posts/[id].js -import { useRouter } from 'next/router' -import ReactMarkdown from 'react-markdown' -import supabase from "../../utils/initSupabase"; - -export default function Post({ post }) { - - const router = useRouter() - if (router.isFallback) { - return
Loading...
- } - return ( -
-

{post.title}

-

by {post.user_email}

-
- {// eslint-disable-next-line react/no-children-prop - - }
-
- ) -} - -export async function getStaticPaths() { - const { data, error } = await supabase - .from('posts') - .select('id') - const paths = data.map(post => ({ params: { id: JSON.stringify(post.id) }})) - return { - paths, - fallback: true - } -} - -export async function getStaticProps ({ params }) { - const { id } = params - const { data } = await supabase - .from('posts') - .select() - .filter('id', 'eq', id) - .single() - return { - props: { - post: data - } - } -} \ No newline at end of file diff --git a/pages/profile.js b/pages/profile.js index cfd6cb9..57497bc 100644 --- a/pages/profile.js +++ b/pages/profile.js @@ -1,31 +1,585 @@ // pages/profile.js -import { Auth, Typography, Button } from "@supabase/ui"; -const { Text } = Typography +import { useState, useEffect, useRef } from "react"; +import { Auth, Button, Modal, IconCamera, Input } from "@supabase/ui"; import supabase from "../utils/initSupabase"; +import dynamic from "next/dynamic"; +import Loader from "react-loader-spinner"; +import { useRouter } from "next/router"; +import Header from "../components/Header"; -function Profile(props){ - const {user} = Auth.useUser(); - if (user) - return( - <> -
- Signed in: {user.email} - + + + + -
- +
+ {/* button end */} +
+ // profile ends ); - + else { return props.children; + } } export default function AuthProfile() { - return ( - - - - - - ) -} \ No newline at end of file + return ( + + + + + + ); +} diff --git a/pages/search.js b/pages/search.js new file mode 100644 index 0000000..99fcf2c --- /dev/null +++ b/pages/search.js @@ -0,0 +1,241 @@ +import { useState, useEffect, useRef, useCallback } from "react"; +import { + Auth, + Input, + Button, + IconSearch, + IconMoreHorizontal, +} from "@supabase/ui"; +import supabase from "../utils/initSupabase"; +import { useRouter } from "next/router"; +import Loader from "react-loader-spinner"; +import UserCard from "../components/UserCard"; +import ContentCard from "../components/ContentCard"; +import { categoryList } from "../constants/categories"; +import Header from "../components/Header"; + +export default function Search(props) { + const { user } = Auth.useUser(); + const [loading, setLoading] = useState(true); + const loadMore = useRef(null); + const router = useRouter(); + const [posts, setPosts] = useState([]); + const [formattedPosts, setFormattedPosts] = useState(); + const [currentRange, setRange] = useState(10); + const [liked, setLike] = useState(false); + const [search, setSearch] = useState(""); + + const { query } = router; + + const fetchPosts = useCallback(() => { + Get(); + async function Get() { + const { data } = await supabase + .from("posts") + .select( + `category,content,inserted_at,isPrivate,title,user_id,id,creator: user_id(username,fullname,avatar_url),featured` + ) + .textSearch("title", `${query.q ? query.q.replace("%20", "") : ""}`, { + type: "websearch", + }) + .range(0, currentRange); + if (!data) { + return null; + } else { + setPosts(data); + } + setSearch(query.q ? query.q.replace("%20", "") : ""); + } + }, [currentRange, query]); + + useEffect(() => { + fetchPosts(); + }, [fetchPosts]); + + // posts.forEach((value)=>{b.push({...posts,creator:getCreator(value.id)})}) + + useEffect(() => { + getProfile(); + async function getProfile() { + const { data } = await supabase + .from("profiles") + .select("*") + .filter( + "id", + "eq", + supabase.auth.user() === null ? " " : supabase.auth.user().id + ); + + if (!data) { + setLoading(false); + } else { + setLoading(false); + } + } + }, [user, loading]); + + async function LikeCount(id) { + const { count } = await supabase + .from("likes") + .select("post_id", { count: "exact" }) + .match(id); + return count; + } + + async function Search() { + if (search) { + await router.push(`/search?q=${search}`); + } + } + + while (loading) { + return ( +
+
+ +
+
+ ); + } + + if (posts) { + return ( +
+
+
+
+
Recommended
+
+ + + + + +
+ See more... +
+
+ +
+
+
Posts
+
+ { + setSearch(e.target.value); + }} + actions={[ +

+ + Search +

, + ]} + /> +
+
+ + {/* posts */} +
+ {!posts.length ? ( +
+
+ Nothing Here ... +
+
+ ) : ( + posts.map((post, index) => ( + + )) + )} +
+ +
+
+
+ Join Big Events 🎊 +
+
+ Browse +
+
+ +
+ + Be part of events & hackathons, building careers and leveraging + your skill by taking internships & browsing job openings from + top companies. + +
+
+ + {/* loading more */} + {/*
+
+ +
+
*/} + +
+
setRange((value) => value + 10)} + className="text-sm flex mx-auto font-medium hover:text-purple-600 text-gray-800 text-center" + > + Load More ... +
+
+
+ +
+
+
+
+ Join Big Events 🎊 +
+
+ Browse +
+
+ +
+ + Be part of events & hackathons, building careers and leveraging + your skill by taking internships & browsing job openings from + top companies. + +
+
+
+
+ ); + } +} diff --git a/pages/setting.js b/pages/setting.js new file mode 100644 index 0000000..02b7a54 --- /dev/null +++ b/pages/setting.js @@ -0,0 +1,3 @@ +export default function Setting(){ + return null +} \ No newline at end of file diff --git a/pages/subscribe/early-access.js b/pages/subscribe/early-access.js index d0c087e..beede19 100644 --- a/pages/subscribe/early-access.js +++ b/pages/subscribe/early-access.js @@ -3,8 +3,8 @@ export default function Subscribed (){ return (
-

Thanks for supporting this project and requesting early access on Scrawlo

-
I can't wait to show you what we've been working on. You're part of the team now!
+

Thanks for subscribing to our Newsletter

+
I can't wait to share you what we've been working on. You're part of the team!
) diff --git a/public/scrawler_with_bike.svg b/public/cstory_with_bike.svg similarity index 100% rename from public/scrawler_with_bike.svg rename to public/cstory_with_bike.svg diff --git a/public/scrawler_with_cup.svg b/public/cstory_with_cup.svg similarity index 100% rename from public/scrawler_with_cup.svg rename to public/cstory_with_cup.svg diff --git a/public/scrawler_with_pc.svg b/public/cstory_with_pc.svg similarity index 100% rename from public/scrawler_with_pc.svg rename to public/cstory_with_pc.svg diff --git a/public/profile.png b/public/profile.png new file mode 100644 index 0000000..46efd79 Binary files /dev/null and b/public/profile.png differ diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 0000000..8a8c114 --- /dev/null +++ b/public/robots.txt @@ -0,0 +1,11 @@ +# Allow all user agents. +User-agent: * +Allow: / +Disallow: /m/ +Disallow: /api/ +Disallow: /profile +Disallow: /500 +Disallow: /400 +Disallow: /subscribe/ +Disallow: /draft +Disallow: /connection \ No newline at end of file diff --git a/public/vercel.svg b/public/vercel.svg index fbf0e25..814fb63 100644 --- a/public/vercel.svg +++ b/public/vercel.svg @@ -1,4 +1,69 @@ - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/public/vercelox.svg b/public/vercelox.svg new file mode 100644 index 0000000..dbb29b9 --- /dev/null +++ b/public/vercelox.svg @@ -0,0 +1,67 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/styles/Home.module.css b/styles/Home.module.css deleted file mode 100644 index 35454bb..0000000 --- a/styles/Home.module.css +++ /dev/null @@ -1,121 +0,0 @@ -.container { - min-height: 100vh; - padding: 0 0.5rem; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; - height: 100vh; -} - -.main { - padding: 5rem 0; - flex: 1; - display: flex; - flex-direction: column; - justify-content: center; - align-items: center; -} - -.footer { - width: 100%; - height: 100px; - border-top: 1px solid #eaeaea; - display: flex; - justify-content: center; - align-items: center; -} - -.footer a { - display: flex; - justify-content: center; - align-items: center; - flex-grow: 1; -} - -.title a { - color: #0070f3; - text-decoration: none; -} - -.title a:hover, -.title a:focus, -.title a:active { - text-decoration: underline; -} - -.title { - margin: 0; - line-height: 1.15; - font-size: 4rem; -} - -.title, -.description { - text-align: center; -} - -.description { - line-height: 1.5; - font-size: 1.5rem; -} - -.code { - background: #fafafa; - border-radius: 5px; - padding: 0.75rem; - font-size: 1.1rem; - font-family: Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, - Bitstream Vera Sans Mono, Courier New, monospace; -} - -.grid { - display: flex; - align-items: center; - justify-content: center; - flex-wrap: wrap; - max-width: 800px; - margin-top: 3rem; -} - -.card { - margin: 1rem; - padding: 1.5rem; - text-align: left; - color: inherit; - text-decoration: none; - border: 1px solid #eaeaea; - border-radius: 10px; - transition: color 0.15s ease, border-color 0.15s ease; - width: 45%; -} - -.card:hover, -.card:focus, -.card:active { - color: #0070f3; - border-color: #0070f3; -} - -.card h2 { - margin: 0 0 1rem 0; - font-size: 1.5rem; -} - -.card p { - margin: 0; - font-size: 1.25rem; - line-height: 1.5; -} - -.logo { - height: 1em; - margin-left: 0.5rem; -} - -@media (max-width: 600px) { - .grid { - width: 100%; - flex-direction: column; - } -} diff --git a/tailwind.config.js b/tailwind.config.js index c0107f2..4b19a20 100644 --- a/tailwind.config.js +++ b/tailwind.config.js @@ -1,5 +1,5 @@ module.exports = { - purge: [], + purge: ['./pages/**/*.{js,ts,jsx,tsx}', './components/**/*.{js,ts,jsx,tsx}'], darkMode: false, // or 'media' or 'class' theme: { extend: {}, diff --git a/yarn.lock b/yarn.lock index f10e3e1..53eb600 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2570,6 +2570,11 @@ "resolved" "https://registry.npmjs.org/modern-normalize/-/modern-normalize-1.1.0.tgz" "version" "1.1.0" +"moment@^2.29.1": + "integrity" "sha512-kHmoybcPV8Sqy59DwNDY3Jefr64lK/by/da0ViFcuA4DH0vQg5Q6Ze5VimxkfQNSC+Mls/Kx53s7TjP1RhFEDQ==" + "resolved" "https://registry.npmjs.org/moment/-/moment-2.29.1.tgz" + "version" "2.29.1" + "ms@^2.1.1": "integrity" "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz" @@ -2585,6 +2590,11 @@ "resolved" "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz" "version" "2.1.2" +"multiselect-react-dropdown@^2.0.5": + "integrity" "sha512-KIkhycdCrzLSMxnI9l2Q77BMx+qF3RYQwegZ5H70g3tcSae6h6JvEnwNm4oQWRiP0EMjlbYFl0aqd6KJEJyo5A==" + "resolved" "https://registry.npmjs.org/multiselect-react-dropdown/-/multiselect-react-dropdown-2.0.5.tgz" + "version" "2.0.5" + "nanoid@^3.1.22", "nanoid@^3.1.23": "integrity" "sha512-FiB0kzdP0FFVGDKlRLEQ1BgDzU87dy5NnzjeW9YZNt+/c3+q82EQDUwniSAUxp/F0gFNI1ZhKU1FqYsMuqZVnw==" "resolved" "https://registry.npmjs.org/nanoid/-/nanoid-3.1.23.tgz" @@ -3244,7 +3254,7 @@ "iconv-lite" "0.4.24" "unpipe" "1.0.0" -"react-dom@^16 || ^17 || ^18", "react-dom@^16.13.1 || ^17.0.1", "react-dom@^17.0.2", "react-dom@>=16.8.2", "react-dom@17.0.2": +"react-dom@*", "react-dom@^16 || ^17 || ^18", "react-dom@^16.13.1 || ^17.0.1", "react-dom@^17.0.2", "react-dom@>=16.8.2", "react-dom@17.0.2": "integrity" "sha512-s4h96KtLDUQlsENhMn1ar8t2bEa+q/YAtj8pPPdIjPDGBDIVNsrD9aXNWqspUe6AzKCIG0C1HZZLqLV7qpOBGA==" "resolved" "https://registry.npmjs.org/react-dom/-/react-dom-17.0.2.tgz" "version" "17.0.2" @@ -3263,6 +3273,13 @@ "resolved" "https://registry.npmjs.org/react-is/-/react-is-17.0.2.tgz" "version" "17.0.2" +"react-loader-spinner@^4.0.0": + "integrity" "sha512-RU2vpEej6G4ECei0h3q6bgLU10of9Lw5O+4AwF/mtkrX5oY20Sh/AxoPJ7etbrs/7Q3u4jN5qwCwGLRKCHpk6g==" + "resolved" "https://registry.npmjs.org/react-loader-spinner/-/react-loader-spinner-4.0.0.tgz" + "version" "4.0.0" + dependencies: + "prop-types" "^15.7.2" + "react-markdown@^6.0.2": "integrity" "sha512-Et2AjXAsbmPP1nLQQRqmVgcqzfwcz8uQJ8VAdADs8Nk/aaUA0YeU9RDLuCtD+GwajCnm/+Iiu2KPmXzmD/M3vA==" "resolved" "https://registry.npmjs.org/react-markdown/-/react-markdown-6.0.2.tgz" @@ -3295,7 +3312,7 @@ "@types/codemirror" "0.0.109" "@types/marked" "^2.0.2" -"react@^16 || ^17 || ^18", "react@^16.13.1 || ^17.0.1", "react@^16.8.0 || ^17.0.0", "react@^17.0.2", "react@>=16", "react@>=16.8.2", "react@15.x.x || 16.x.x || 17.x.x", "react@17.0.2": +"react@*", "react@^16 || ^17 || ^18", "react@^16.13.1 || ^17.0.1", "react@^16.7.0 || ^17.0.0-0", "react@^16.8.0 || ^17.0.0", "react@^17.0.2", "react@>=16", "react@>=16.8.2", "react@15.x.x || 16.x.x || 17.x.x", "react@17.0.2": "integrity" "sha512-gnhPt75i/dq/z3/6q/0asP78D0u592D5L1pd7M8P+dck6Fu/jJeL6iVVK23fptSUZj8Vjf++7wXA8UNclGQcbA==" "resolved" "https://registry.npmjs.org/react/-/react-17.0.2.tgz" "version" "17.0.2"