feat: add new fancy index + add org slugs

This commit is contained in:
swve 2022-09-25 10:57:54 +02:00
parent 1b3df392b7
commit 86fdd89b23
11 changed files with 376 additions and 21 deletions

View file

@ -1,7 +1,10 @@
import React from "react";
import styled from "styled-components";
import { HeaderProfileBox } from "../../auth/HeaderProfileBox";
import learnhouseIcon from 'public/learnhouse_icon.png'
import learnhouseLogo from 'public/learnhouse_logo.png'
import Link from "next/link";
import Image from "next/image";
export const Menu = () => {
return (
@ -9,10 +12,10 @@ export const Menu = () => {
<LogoArea>
<Logo>
<img style={{ width: "30px", opacity: "0.9", margin: "10px", paddingRight: "4px" }} src="./learnhouse_icon.png" alt="" />
<Image width={25} height={25} src={learnhouseIcon} alt="" />
<Link href={"/"}>
<a>
<img src="./learnhouse_logo.png" alt="" />
<Image width={108} height={28} src={learnhouseLogo} alt="" />
</a>
</Link>
</Logo>
@ -54,10 +57,10 @@ const Logo = styled.div`
padding-left: 20px;
a{
margin: 0;
padding-left: 10px;
padding-top: 2px;
}
img {
width: 100px;
}
`;
const SearchArea = styled.div`

View file

@ -43,7 +43,7 @@ const Footer = styled.footer`
}
`;
const PreAlphaLabel = styled.div`
export const PreAlphaLabel = styled.div`
position: fixed;
bottom: 0;
right: 0;

249
front/package-lock.json generated
View file

@ -8,6 +8,7 @@
"name": "learnhouse",
"version": "0.1.0",
"dependencies": {
"framer-motion": "^7.3.6",
"next": "12.3.1",
"react": "18.2.0",
"react-dom": "18.2.0",
@ -427,6 +428,64 @@
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
"node_modules/@motionone/animation": {
"version": "10.14.0",
"resolved": "https://registry.npmjs.org/@motionone/animation/-/animation-10.14.0.tgz",
"integrity": "sha512-h+1sdyBP8vbxEBW5gPFDnj+m2DCqdlAuf2g6Iafb1lcMnqjsRXWlPw1AXgvUMXmreyhqmPbJqoNfIKdytampRQ==",
"dependencies": {
"@motionone/easing": "^10.14.0",
"@motionone/types": "^10.14.0",
"@motionone/utils": "^10.14.0",
"tslib": "^2.3.1"
}
},
"node_modules/@motionone/dom": {
"version": "10.13.1",
"resolved": "https://registry.npmjs.org/@motionone/dom/-/dom-10.13.1.tgz",
"integrity": "sha512-zjfX+AGMIt/fIqd/SL1Lj93S6AiJsEA3oc5M9VkUr+Gz+juRmYN1vfvZd6MvEkSqEjwPQgcjN7rGZHrDB9APfQ==",
"dependencies": {
"@motionone/animation": "^10.13.1",
"@motionone/generators": "^10.13.1",
"@motionone/types": "^10.13.0",
"@motionone/utils": "^10.13.1",
"hey-listen": "^1.0.8",
"tslib": "^2.3.1"
}
},
"node_modules/@motionone/easing": {
"version": "10.14.0",
"resolved": "https://registry.npmjs.org/@motionone/easing/-/easing-10.14.0.tgz",
"integrity": "sha512-2vUBdH9uWTlRbuErhcsMmt1jvMTTqvGmn9fHq8FleFDXBlHFs5jZzHJT9iw+4kR1h6a4SZQuCf72b9ji92qNYA==",
"dependencies": {
"@motionone/utils": "^10.14.0",
"tslib": "^2.3.1"
}
},
"node_modules/@motionone/generators": {
"version": "10.14.0",
"resolved": "https://registry.npmjs.org/@motionone/generators/-/generators-10.14.0.tgz",
"integrity": "sha512-6kRHezoFfIjFN7pPpaxmkdZXD36tQNcyJe3nwVqwJ+ZfC0e3rFmszR8kp9DEVFs9QL/akWjuGPSLBI1tvz+Vjg==",
"dependencies": {
"@motionone/types": "^10.14.0",
"@motionone/utils": "^10.14.0",
"tslib": "^2.3.1"
}
},
"node_modules/@motionone/types": {
"version": "10.14.0",
"resolved": "https://registry.npmjs.org/@motionone/types/-/types-10.14.0.tgz",
"integrity": "sha512-3bNWyYBHtVd27KncnJLhksMFQ5o2MSdk1cA/IZqsHtA9DnRM1SYgN01CTcJ8Iw8pCXF5Ocp34tyAjY7WRpOJJQ=="
},
"node_modules/@motionone/utils": {
"version": "10.14.0",
"resolved": "https://registry.npmjs.org/@motionone/utils/-/utils-10.14.0.tgz",
"integrity": "sha512-sLWBLPzRqkxmOTRzSaD3LFQXCPHvDzyHJ1a3VP9PRzBxyVd2pv51/gMOsdAcxQ9n+MIeGJnxzXBYplUHKj4jkw==",
"dependencies": {
"@motionone/types": "^10.14.0",
"hey-listen": "^1.0.8",
"tslib": "^2.3.1"
}
},
"node_modules/@next/env": {
"version": "12.3.1",
"resolved": "https://registry.npmjs.org/@next/env/-/env-12.3.1.tgz",
@ -1990,6 +2049,49 @@
"url": "https://www.patreon.com/infusion"
}
},
"node_modules/framer-motion": {
"version": "7.3.6",
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-7.3.6.tgz",
"integrity": "sha512-en8mLpDv6IcieZo54acHg56HSLpOSryRLZtMOd1Sj1s7hBbUTWnJsv68CWaHI2ysPKcbH/olGfAhRh4yrJn5tw==",
"dependencies": {
"@motionone/dom": "10.13.1",
"framesync": "6.1.2",
"hey-listen": "^1.0.8",
"popmotion": "11.0.5",
"style-value-types": "5.1.2",
"tslib": "2.4.0"
},
"optionalDependencies": {
"@emotion/is-prop-valid": "^0.8.2"
},
"peerDependencies": {
"react": "^18.0.0",
"react-dom": "^18.0.0"
}
},
"node_modules/framer-motion/node_modules/@emotion/is-prop-valid": {
"version": "0.8.8",
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
"integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==",
"optional": true,
"dependencies": {
"@emotion/memoize": "0.7.4"
}
},
"node_modules/framer-motion/node_modules/@emotion/memoize": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
"integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==",
"optional": true
},
"node_modules/framesync": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/framesync/-/framesync-6.1.2.tgz",
"integrity": "sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g==",
"dependencies": {
"tslib": "2.4.0"
}
},
"node_modules/fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@ -2201,6 +2303,11 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/hey-listen": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz",
"integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q=="
},
"node_modules/hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
@ -3005,6 +3112,17 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/popmotion": {
"version": "11.0.5",
"resolved": "https://registry.npmjs.org/popmotion/-/popmotion-11.0.5.tgz",
"integrity": "sha512-la8gPM1WYeFznb/JqF4GiTkRRPZsfaj2+kCxqQgr2MJylMmIKUwBfWW8Wa5fml/8gmtlD5yI01MP1QCZPWmppA==",
"dependencies": {
"framesync": "6.1.2",
"hey-listen": "^1.0.8",
"style-value-types": "5.1.2",
"tslib": "2.4.0"
}
},
"node_modules/postcss": {
"version": "8.4.16",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz",
@ -3381,6 +3499,15 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/style-value-types": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-5.1.2.tgz",
"integrity": "sha512-Vs9fNreYF9j6W2VvuDTP7kepALi7sk0xtk2Tu8Yxi9UoajJdEVpNpCov0HsLTqXvNGKX+Uv09pkozVITi1jf3Q==",
"dependencies": {
"hey-listen": "^1.0.8",
"tslib": "2.4.0"
}
},
"node_modules/styled-components": {
"version": "5.3.5",
"resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.5.tgz",
@ -4004,6 +4131,64 @@
"@jridgewell/sourcemap-codec": "^1.4.10"
}
},
"@motionone/animation": {
"version": "10.14.0",
"resolved": "https://registry.npmjs.org/@motionone/animation/-/animation-10.14.0.tgz",
"integrity": "sha512-h+1sdyBP8vbxEBW5gPFDnj+m2DCqdlAuf2g6Iafb1lcMnqjsRXWlPw1AXgvUMXmreyhqmPbJqoNfIKdytampRQ==",
"requires": {
"@motionone/easing": "^10.14.0",
"@motionone/types": "^10.14.0",
"@motionone/utils": "^10.14.0",
"tslib": "^2.3.1"
}
},
"@motionone/dom": {
"version": "10.13.1",
"resolved": "https://registry.npmjs.org/@motionone/dom/-/dom-10.13.1.tgz",
"integrity": "sha512-zjfX+AGMIt/fIqd/SL1Lj93S6AiJsEA3oc5M9VkUr+Gz+juRmYN1vfvZd6MvEkSqEjwPQgcjN7rGZHrDB9APfQ==",
"requires": {
"@motionone/animation": "^10.13.1",
"@motionone/generators": "^10.13.1",
"@motionone/types": "^10.13.0",
"@motionone/utils": "^10.13.1",
"hey-listen": "^1.0.8",
"tslib": "^2.3.1"
}
},
"@motionone/easing": {
"version": "10.14.0",
"resolved": "https://registry.npmjs.org/@motionone/easing/-/easing-10.14.0.tgz",
"integrity": "sha512-2vUBdH9uWTlRbuErhcsMmt1jvMTTqvGmn9fHq8FleFDXBlHFs5jZzHJT9iw+4kR1h6a4SZQuCf72b9ji92qNYA==",
"requires": {
"@motionone/utils": "^10.14.0",
"tslib": "^2.3.1"
}
},
"@motionone/generators": {
"version": "10.14.0",
"resolved": "https://registry.npmjs.org/@motionone/generators/-/generators-10.14.0.tgz",
"integrity": "sha512-6kRHezoFfIjFN7pPpaxmkdZXD36tQNcyJe3nwVqwJ+ZfC0e3rFmszR8kp9DEVFs9QL/akWjuGPSLBI1tvz+Vjg==",
"requires": {
"@motionone/types": "^10.14.0",
"@motionone/utils": "^10.14.0",
"tslib": "^2.3.1"
}
},
"@motionone/types": {
"version": "10.14.0",
"resolved": "https://registry.npmjs.org/@motionone/types/-/types-10.14.0.tgz",
"integrity": "sha512-3bNWyYBHtVd27KncnJLhksMFQ5o2MSdk1cA/IZqsHtA9DnRM1SYgN01CTcJ8Iw8pCXF5Ocp34tyAjY7WRpOJJQ=="
},
"@motionone/utils": {
"version": "10.14.0",
"resolved": "https://registry.npmjs.org/@motionone/utils/-/utils-10.14.0.tgz",
"integrity": "sha512-sLWBLPzRqkxmOTRzSaD3LFQXCPHvDzyHJ1a3VP9PRzBxyVd2pv51/gMOsdAcxQ9n+MIeGJnxzXBYplUHKj4jkw==",
"requires": {
"@motionone/types": "^10.14.0",
"hey-listen": "^1.0.8",
"tslib": "^2.3.1"
}
},
"@next/env": {
"version": "12.3.1",
"resolved": "https://registry.npmjs.org/@next/env/-/env-12.3.1.tgz",
@ -5099,6 +5284,45 @@
"integrity": "sha512-MhLuK+2gUcnZe8ZHlaaINnQLl0xRIGRfcGk2yl8xoQAfHrSsL3rYu6FCmBdkdbhc9EPlwyGHewaRsvwRMJtAlA==",
"dev": true
},
"framer-motion": {
"version": "7.3.6",
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-7.3.6.tgz",
"integrity": "sha512-en8mLpDv6IcieZo54acHg56HSLpOSryRLZtMOd1Sj1s7hBbUTWnJsv68CWaHI2ysPKcbH/olGfAhRh4yrJn5tw==",
"requires": {
"@emotion/is-prop-valid": "^0.8.2",
"@motionone/dom": "10.13.1",
"framesync": "6.1.2",
"hey-listen": "^1.0.8",
"popmotion": "11.0.5",
"style-value-types": "5.1.2",
"tslib": "2.4.0"
},
"dependencies": {
"@emotion/is-prop-valid": {
"version": "0.8.8",
"resolved": "https://registry.npmjs.org/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz",
"integrity": "sha512-u5WtneEAr5IDG2Wv65yhunPSMLIpuKsbuOktRojfrEiEvRyC85LgPMZI63cr7NUqT8ZIGdSVg8ZKGxIug4lXcA==",
"optional": true,
"requires": {
"@emotion/memoize": "0.7.4"
}
},
"@emotion/memoize": {
"version": "0.7.4",
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.7.4.tgz",
"integrity": "sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw==",
"optional": true
}
}
},
"framesync": {
"version": "6.1.2",
"resolved": "https://registry.npmjs.org/framesync/-/framesync-6.1.2.tgz",
"integrity": "sha512-jBTqhX6KaQVDyus8muwZbBeGGP0XgujBRbQ7gM7BRdS3CadCZIHiawyzYLnafYcvZIh5j8WE7cxZKFn7dXhu9g==",
"requires": {
"tslib": "2.4.0"
}
},
"fs.realpath": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
@ -5247,6 +5471,11 @@
"has-symbols": "^1.0.2"
}
},
"hey-listen": {
"version": "1.0.8",
"resolved": "https://registry.npmjs.org/hey-listen/-/hey-listen-1.0.8.tgz",
"integrity": "sha512-COpmrF2NOg4TBWUJ5UVyaCU2A88wEMkUPK4hNqyCkqHbxT92BbvfjoSozkAIIm6XhicGlJHhFdullInrdhwU8Q=="
},
"hoist-non-react-statics": {
"version": "3.3.2",
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
@ -5813,6 +6042,17 @@
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
"integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA=="
},
"popmotion": {
"version": "11.0.5",
"resolved": "https://registry.npmjs.org/popmotion/-/popmotion-11.0.5.tgz",
"integrity": "sha512-la8gPM1WYeFznb/JqF4GiTkRRPZsfaj2+kCxqQgr2MJylMmIKUwBfWW8Wa5fml/8gmtlD5yI01MP1QCZPWmppA==",
"requires": {
"framesync": "6.1.2",
"hey-listen": "^1.0.8",
"style-value-types": "5.1.2",
"tslib": "2.4.0"
}
},
"postcss": {
"version": "8.4.16",
"resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.16.tgz",
@ -6063,6 +6303,15 @@
"integrity": "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig==",
"dev": true
},
"style-value-types": {
"version": "5.1.2",
"resolved": "https://registry.npmjs.org/style-value-types/-/style-value-types-5.1.2.tgz",
"integrity": "sha512-Vs9fNreYF9j6W2VvuDTP7kepALi7sk0xtk2Tu8Yxi9UoajJdEVpNpCov0HsLTqXvNGKX+Uv09pkozVITi1jf3Q==",
"requires": {
"hey-listen": "^1.0.8",
"tslib": "2.4.0"
}
},
"styled-components": {
"version": "5.3.5",
"resolved": "https://registry.npmjs.org/styled-components/-/styled-components-5.3.5.tgz",

View file

@ -9,6 +9,7 @@
"lint": "next lint"
},
"dependencies": {
"framer-motion": "^7.3.6",
"next": "12.3.1",
"react": "18.2.0",
"react-dom": "18.2.0",

View file

@ -1,17 +1,90 @@
import type { NextPage } from "next";
import { Title } from "../components/ui/styles/title";
import Layout from "../components/ui/layout";
import { Header } from "../components/ui/header";
import { motion } from "framer-motion";
import styled from "styled-components";
import learnhouseBigIcon from "public/learnhouse_bigicon.png";
import Image from "next/image";
import Link from "next/link";
import { PreAlphaLabel } from "../components/ui/layout";
const Home: NextPage = () => {
return (
<div>
<Layout title="Index">
<Header></Header>
<Title>Home</Title>
</Layout>
</div>
<HomePage>
<PreAlphaLabel>🚧 Pre-Alpha</PreAlphaLabel>
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{
type: "spring",
stiffness: 260,
damping: 70,
delay: 0.2,
}}
exit={{ opacity: 1 }}
>
<Image alt="Learnhouse Icon" height={295} width={295} quality={100} src={learnhouseBigIcon}></Image>
</motion.div>
<br />
<br />
<br />
<br />
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
transition={{
type: "spring",
stiffness: 260,
damping: 70,
delay: 0.8,
}}
exit={{ opacity: 1 }}
>
<div>
<Link href={"/organizations"}>
<a>
<OrgsButton>See Organizations</OrgsButton>
</a>
</Link>
</div>
</motion.div>
</HomePage>
);
};
const OrgsButton = styled.button`
background: #151515;
border: 1px solid #e5e5e50a;
box-sizing: border-box;
border-radius: 4px;
padding: 10px 20px;
color: white;
font-size: 16px;
line-height: 24px;
margin: 0 10px;
margin: auto;
cursor: pointer;
font-family: "DM Sans";
font-weight: 500;
border-radius: 12px;
-webkit-transition: all 0.2s ease-in-out;
transition: all 0.2s ease-in-out;
&:hover {
background: #191919;
}
`;
const HomePage = styled.div`
display: flex;
flex-direction: column;
background: linear-gradient(131.61deg, #202020 7.15%, #000000 90.96%);
justify-content: center;
align-items: center;
height: 100vh;
width: 100vw;
min-height: 100vh;
text-align: center;
img {
width: 60px;
}
`;
export default Home;

View file

@ -0,0 +1,22 @@
import React from 'react'
import { useRouter } from 'next/router'
import Layout from '../../components/ui/layout'
import { Title } from '../../components/ui/styles/title'
import { Header } from '../../components/ui/header'
const OrgHome = () => {
const router = useRouter()
const { orgslug } = router.query
return (
<div>
<Layout title="Index">
<Header></Header>
<Title>Welcome {orgslug} 👋🏻</Title>
</Layout>
</div>
)
}
export default OrgHome;

View file

@ -49,7 +49,7 @@ const Organizations = () => {
<div>
{userOrganizations.map((org: any) => (
<div key={org.org_id}>
<Link href={`/organizations/${org.org_id}`}>
<Link href={`/org/${org.slug}`}>
<a>
<h3>{org.name}</h3>
</a>

View file

@ -7,6 +7,7 @@ const Organizations = () => {
const [name, setName] = React.useState("");
const [description, setDescription] = React.useState("");
const [email, setEmail] = React.useState("");
const [slug, setSlug] = React.useState("");
const handleNameChange = (e: any) => {
setName(e.target.value);
@ -20,12 +21,15 @@ const Organizations = () => {
setEmail(e.target.value);
};
const handleSlugChange = (e: any) => {
setSlug(e.target.value);
};
const handleSubmit = async (e: any) => {
e.preventDefault();
console.log({ name, description, email });
const status = await createNewOrganization({ name, description, email });
alert(JSON.stringify(status));
const status = await createNewOrganization({ name, description, email, slug });
alert(JSON.stringify(status));
};
return (
@ -35,6 +39,8 @@ const Organizations = () => {
<br />
Description: <input onChange={handleDescriptionChange} type="text" />
<br />
Slug: <input onChange={handleSlugChange} type="text" />
<br />
Email Address: <input onChange={handleEmailChange} type="text" />
<br />
<button onClick={handleSubmit}>Create</button>

Binary file not shown.

After

Width:  |  Height:  |  Size: 772 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 435 KiB

View file

@ -15,6 +15,7 @@ class Organization(BaseModel):
name: str
description: str
email: str
slug :str
class OrganizationInDB(Organization):
@ -45,11 +46,11 @@ async def create_org(org_object: Organization, current_user: User):
orgs = learnhouseDB["organizations"]
# find if org already exists using name
isOrgAvailable = orgs.find_one({"name": org_object.name})
isOrgAvailable = orgs.find_one({"slug": org_object.slug})
if isOrgAvailable:
raise HTTPException(
status_code=status.HTTP_409_CONFLICT, detail="Organization name already exists")
status_code=status.HTTP_409_CONFLICT, detail="Organization slug already exists")
# generate org_id with uuid4
org_id = str(f"org_{uuid4()}")