Skip to content

Commit

Permalink
add login and profile page
Browse files Browse the repository at this point in the history
  • Loading branch information
vincanger committed Oct 26, 2023
1 parent a89ecb2 commit 03106d3
Show file tree
Hide file tree
Showing 8 changed files with 272 additions and 76 deletions.
12 changes: 12 additions & 0 deletions wasp-ai/main.wasp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,12 @@ page ResultPage {
component: import { ResultPage } from "@client/pages/ResultPage.jsx"
}

route UserRoute { path: "/user", to: UserPage }
page UserPage {
component: import { UserPage } from "@client/pages/UserPage.jsx",
authRequired: true
}

route StatsRoute { path: "/stats", to: StatsPage }
page StatsPage {
component: import { Stats } from "@client/pages/StatsPage.jsx",
Expand Down Expand Up @@ -105,6 +111,11 @@ query getFeedback {
entities: [Feedback]
}

query getProjectsByUser {
fn: import { getProjectsByUser } from "@server/operations.js",
entities: [Project]
}


query getAppGenerationResult {
fn: import { getAppGenerationResult } from "@server/operations.js",
Expand All @@ -131,6 +142,7 @@ entity User {=psl
id Int @id @default(autoincrement())

email String @unique
username String?
externalAuthAssociations SocialLogin[]
projects Project[]
psl=}
Expand Down
2 changes: 2 additions & 0 deletions wasp-ai/migrations/20231026125258_username/migration.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
-- AlterTable
ALTER TABLE "User" ADD COLUMN "username" TEXT;
49 changes: 35 additions & 14 deletions wasp-ai/src/client/components/Header.jsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,42 @@
import { StatusPill } from './StatusPill';
import { Title } from './Title';
import { signInUrl as gitHubSignInUrl } from '@wasp/auth/helpers/GitHub';
import { AiFillGithub } from 'react-icons/ai';
import useAuth from '@wasp/auth/useAuth';
import { StatusPill } from "./StatusPill";
import { Title } from "./Title";
import { signInUrl as gitHubSignInUrl } from "@wasp/auth/helpers/GitHub";
import { AiFillGithub } from "react-icons/ai";
import { BiSolidUser } from "react-icons/bi";
import { RxQuestionMarkCircled } from "react-icons/rx";
import useAuth from "@wasp/auth/useAuth";
import { Link } from "@wasp/router";


export function Header({ currentStatus, isStatusVisible }) {
const { data: user } = useAuth();

return (
<div className='mb-4 bg-slate-50 p-8 rounded-xl md:flex justify-between items-center'>
<div className="mb-4 bg-slate-50 p-8 rounded-xl md:flex justify-between items-center">
<Title />
{!!user && isStatusVisible ? (
<StatusPill status={currentStatus.status} className='hidden md:flex'>
{currentStatus.message}
</StatusPill>
) : (
<GithubLoginButton />
{!!user?.username && isStatusVisible && (
<div className="flex flex-col items-end gap-1">
<div className="flex items-center gap-3 mb-2 mr-1">
{/* <p className="hidden md:block text-gray-700 ">
hey, <span className="font-semibold">{user.username} </span>{" "}
</p> */}
<a href="#faq" className="flex items-center justify-center space-x-1 text-slate-500 hover:text-slate-600">
<span className="text-sm font-normal">Help</span>
<RxQuestionMarkCircled className="text-base text-slate-600" />
</a>
<div className="relative group">
<Link to="/user">
<BiSolidUser className="w-5 h-5 text-slate-600" />
<div className="absolute text-center whitespace-nowrap bg-slate-600 text-white text-xs rounded py-1 px-4 bottom-100 left-1/2 transform -translate-x-1/2 opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all ease-in-out duration-275">
My Apps
</div>
</Link>
</div>
</div>
<StatusPill status={currentStatus.status} className="hidden md:flex">
{currentStatus.message}
</StatusPill>
</div>
)}
</div>
);
Expand All @@ -24,10 +45,10 @@ export function Header({ currentStatus, isStatusVisible }) {
function GithubLoginButton() {
return (
<button
className='button gray flex !text-gray-800 hover:bg-slate-300 shadow-md'
className="button gray flex !text-gray-800 hover:bg-slate-300 shadow-md"
onClick={() => (window.location.href = gitHubSignInUrl)}
>
<AiFillGithub className='w-6 h-6 mr-2' /> Sign in with GitHub
<AiFillGithub className="w-6 h-6 mr-2" /> Sign in with GitHub
</button>
);
}
5 changes: 0 additions & 5 deletions wasp-ai/src/client/components/Title.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import magicLogo from "../magic-app-gen-logo.png";
import { Link } from "react-router-dom";
import { RxQuestionMarkCircled } from "react-icons/rx";

export function Title() {
return (
Expand All @@ -14,10 +13,6 @@ export function Title() {
<p className="md:text-base text-sm leading-relaxed text-gray-500">
Generate your full-stack web app in Wasp, React, Node.js and Prisma
</p>
<a href="#faq" className="flex items-center mt-2 space-x-1 text-gray-500 hover:text-gray-400">
<span className="text-sm font-normal">Learn more</span>
<RxQuestionMarkCircled className="text-base" />
</a>
</div>
</div>
</div>
Expand Down
106 changes: 66 additions & 40 deletions wasp-ai/src/client/pages/MainPage.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,39 +10,46 @@ import { exampleIdeas } from "../examples";
import { PiMagicWandDuotone, PiGithubLogoDuotone, PiStarDuotone } from "react-icons/pi";
import { readReferrerFromLocalStorage } from "../storage";
import { MyDialog } from "../components/Dialog";
import useAuth from "@wasp/auth/useAuth";
import { SignInButton as GitHubSignInButton } from "@wasp/auth/helpers/GitHub";

const MainPage = () => {
const [appName, setAppName] = useState("");
const [appDesc, setAppDesc] = useState("");
const [isPowerUserModalOpen, setIsPowerUserModalOpen] = useState(false);
const [isLoginModalOpen, setIsLoginModalOpen] = useState(false);
const [currentStatus, setCurrentStatus] = useState({
status: "idle",
message: "Waiting for instructions",
});
const history = useHistory();
const { data: user } = useAuth();

const [appPrimaryColor, setAppPrimaryColor] = useState(
availableColors.find((color) => color.name === "sky")
);
const [appPrimaryColor, setAppPrimaryColor] = useState(availableColors.find((color) => color.name === "sky"));

const availableCreativityLevels = useMemo(
() => [{
value: "conventional",
name: "Conventional",
description: "Generates sensible code with minimal amount of mistakes.",
disabled: false
}, {
value: "balanced",
name: "Balanced",
description: "Optimal trade-off between creativity and possible mistakes.",
disabled: false
}, {
value: "creative",
name: "Creative",
description: "Generates more creative code, but mistakes are more likely.",
disabled: false
}]
, []);
() => [
{
value: "conventional",
name: "Conventional",
description: "Generates sensible code with minimal amount of mistakes.",
disabled: false,
},
{
value: "balanced",
name: "Balanced",
description: "Optimal trade-off between creativity and possible mistakes.",
disabled: false,
},
{
value: "creative",
name: "Creative",
description: "Generates more creative code, but mistakes are more likely.",
disabled: false,
},
],
[]
);
const [creativityLevel, setCreativityLevel] = useState(
availableCreativityLevels.find((lvl) => lvl.value === "balanced")
);
Expand Down Expand Up @@ -73,11 +80,7 @@ const MainPage = () => {
useEffect(() => {
try {
const appDetails = JSON.parse(localStorage.getItem("appDetails"));
const appNum = JSON.parse(localStorage.getItem("appNum"));
if (!appNum) {
localStorage.setItem("appNum", 0);
}
if (appNum === 2) {
if (user?.projects.length >= 2) {
setIsPowerUserModalOpen(true);
}
if (appDetails) {
Expand All @@ -95,19 +98,23 @@ const MainPage = () => {

async function startGenerating(event) {
event.preventDefault();

try {
const appNum = JSON.parse(localStorage.getItem("appNum"))
localStorage.setItem("appNum", appNum + 1)
localStorage.setItem("appDetails", JSON.stringify({
appName,
appDesc,
appPrimaryColor: appPrimaryColor.name,
appAuthMethod: appAuthMethod.value,
appCreativityLevel: creativityLevel.value,
}));
localStorage.setItem(
"appDetails",
JSON.stringify({
appName,
appDesc,
appPrimaryColor: appPrimaryColor.name,
appAuthMethod: appAuthMethod.value,
appCreativityLevel: creativityLevel.value,
})
);
if (!user) {
setIsLoginModalOpen(true);
return;
}
} catch (error) {
console.error(error)
console.error(error);
}

setCurrentStatus({
Expand All @@ -116,7 +123,7 @@ const MainPage = () => {
});

try {
const referrer = readReferrerFromLocalStorage();
const referrer = readReferrerFromLocalStorage();
const appId = await startGeneratingNewApp({
referrer,
appName,
Expand Down Expand Up @@ -151,6 +158,7 @@ const MainPage = () => {
<div className="container">
<Header currentStatus={currentStatus} isStatusVisible={true} />

<LoginModal isOpen={isLoginModalOpen} setIsOpen={setIsLoginModalOpen} />
<PowerUserModal isOpen={isPowerUserModalOpen} setIsOpen={setIsPowerUserModalOpen} />

<form onSubmit={startGenerating} className="bg-slate-50 p-8 rounded-xl">
Expand Down Expand Up @@ -229,7 +237,11 @@ export default MainPage;

export function PowerUserModal({ isOpen, setIsOpen }) {
return (
<MyDialog isOpen={isOpen} onClose={() => setIsOpen(false)} title={<span>With Great Power Comes Great Responsibility! 🧙</span>}>
<MyDialog
isOpen={isOpen}
onClose={() => setIsOpen(false)}
title={<span>With Great Power Comes Great Responsibility! 🧙</span>}
>
<div className="mt-6 space-y-5">
<p className="text-base leading-relaxed text-gray-500">
We've made this tool completely <span className="font-semibold">free</span> and cover all the costs 😇
Expand All @@ -254,5 +266,19 @@ export function PowerUserModal({ isOpen, setIsOpen }) {
<p className="text-base leading-relaxed text-gray-500">We'd very much appreciate it! 🧙</p>
</div>
</MyDialog>
)
}
);
}

export function LoginModal({ isOpen, setIsOpen }) {
return (
<MyDialog isOpen={isOpen} onClose={() => setIsOpen(false)} title={<span>Sign in to your GitHub account</span>}>
<div className="mt-6 space-y-5">
<p className="text-base leading-relaxed text-gray-500">
We're offering this tool completely <span className="font-semibold">free</span>. All you have to do is login
with your GitHub Account.
</p>
<GitHubSignInButton />
</div>
</MyDialog>
);
}
Loading

0 comments on commit 03106d3

Please sign in to comment.