add styles

This commit is contained in:
Sara Vieira committed 2022-06-15 16:34:34 +02:00
1 parent 8f4a8ef23b
commit 3ad34f2a59
18 files changed
+288 -36

No files matched your search

+2
View File
@@ -3,6 +3,8 @@ const config = {
canvasPath: "/canvas",
designerPath: "/designer",
dashboardPath: "/dashboard",
loginPath: "/login",
logoutPath: "/logout",
};
export default config;
export type Config = typeof config;
+1
View File
@@ -10,6 +10,7 @@ const getCssTextFunctions = {
[config.canvasPath]: getCanvasCssText,
[config.designerPath]: getDesignerCssText,
[config.dashboardPath]: getDesignerCssText,
[config.loginPath]: getDesignerCssText,
};
const getCssTextFunction = (url: string) => {
+6 -4
View File
@@ -1,8 +1,10 @@
import { ActionFunction, LoaderFunction, redirect } from "@remix-run/node";
import { ActionFunction } from "@remix-run/node";
import config from "~/config";
import { authenticator } from "~/services/auth.server";
export const loader: LoaderFunction = () => redirect("/login");
export const action: ActionFunction = ({ request }) => {
return authenticator.authenticate("github", request);
return authenticator.authenticate("github", request, {
successRedirect: config.dashboardPath,
failureRedirect: config.loginPath,
});
};
+3 -2
View File
@@ -1,9 +1,10 @@
import { LoaderFunction } from "@remix-run/node";
import config from "~/config";
import { authenticator } from "~/services/auth.server";
export const loader: LoaderFunction = ({ request }) => {
return authenticator.authenticate("github", request, {
successRedirect: "/dashboard",
failureRedirect: "/login",
successRedirect: config.dashboardPath,
failureRedirect: config.loginPath,
});
};
+8
View File
@@ -0,0 +1,8 @@
import { ActionFunction, LoaderFunction, redirect } from "@remix-run/node";
import { authenticator } from "~/services/auth.server";
export const loader: LoaderFunction = () => redirect("/login");
export const action: ActionFunction = ({ request }) => {
return authenticator.authenticate("google", request);
};
+10
View File
@@ -0,0 +1,10 @@
import { LoaderFunction } from "@remix-run/node";
import config from "~/config";
import { authenticator } from "~/services/auth.server";
export const loader: LoaderFunction = ({ request }) => {
return authenticator.authenticate("google", request, {
successRedirect: config.dashboardPath,
failureRedirect: config.loginPath,
});
};
+2 -2
View File
@@ -31,9 +31,9 @@ export const action: ActionFunction = async ({ request }) => {
export const loader: LoaderFunction = async ({ request }) => {
const user = await authenticator.isAuthenticated(request);
console.log(user);
console.log(user)
if (!user) {
return redirect("/login");
return redirect(config.loginPath);
}
const { userId, headers } = await ensureUserCookie(request);
const projects = await db.project.loadManyByUserId(userId);
+88 -5
View File
@@ -1,9 +1,92 @@
import { Links, LiveReload, Meta, Scripts } from "@remix-run/react";
import {
LinksFunction,
LoaderFunction,
MetaFunction,
redirect,
} from "@remix-run/node";
import { CriticalCss } from "@webstudio-is/sdk";
import { darkTheme } from "~/shared/design-system";
import { Form } from "@remix-run/react";
import { Button, Card, Flex, Heading } from "~/shared/design-system";
import interStyles from "~/shared/font-faces/inter.css";
export default function Login() {
import { GoogleIcon, GithubIcon } from "~/shared/icons";
import { authenticator } from "~/services/auth.server";
import config from "~/config";
export const links: LinksFunction = () => {
return [
{
rel: "stylesheet",
href: interStyles,
},
];
};
export const meta: MetaFunction = () => {
return { title: "Webstudio Login" };
};
const RootDesignerRoute = () => {
return (
<Form action="/auth/github" method="post">
<button>Login with GitHub</button>
</Form>
<html lang="en">
<head>
<meta charSet="utf-8" />
<meta name="viewport" content="width=device-width,initial-scale=1" />
<Meta />
<Links />
<CriticalCss />
</head>
<body className={darkTheme}>
<Flex
css={{ height: "100vh" }}
direction="column"
align="center"
justify="center"
>
<Card
css={{ width: "$10", padding: "$5", zoom: 1.4 }}
variant="active"
>
<Flex direction="column" gap="2" align="center">
<Heading>Login</Heading>
<Flex gap="2" direction="column" align="center">
<Form action="/auth/github" method="post">
<Button type="submit">
<Flex gap="1">
<GithubIcon width="16" />
Login with GitHub
</Flex>
</Button>
</Form>
<Form action="/auth/google" method="post">
<Button type="submit">
<Flex gap="1">
<GoogleIcon width="16" color="white" />
Login with Google
</Flex>
</Button>
</Form>
</Flex>
</Flex>
</Card>
</Flex>
<Scripts />
{process.env.NODE_ENV === "development" && <LiveReload />}
</body>
</html>
);
}
};
export const loader: LoaderFunction = async ({ request }) => {
const user = await authenticator.isAuthenticated(request);
if (user) {
return redirect(config.dashboardPath);
}
return {};
};
export default RootDesignerRoute;
+39 -18
View File
@@ -1,28 +1,49 @@
import { User } from "@prisma/client";
import { Authenticator } from "remix-auth";
import { GitHubStrategy } from "remix-auth-github";
import { GoogleStrategy } from "remix-auth-google";
import { sessionStorage } from "~/services/session.server";
import { createOrLoginWithGithub } from "~/shared/db/user.server";
import {
createOrLoginWithGithub,
createOrLoginWithGoogle,
} from "~/shared/db/user.server";
const url = `${
process.env.VERCEL_URL
? `https://${process.env.VERCEL_URL}`
: "http://localhost:3000"
}/auth`;
const github = new GitHubStrategy(
{
clientID: process.env.GH_CLIENT_ID as string,
clientSecret: process.env.GH_CLIENT_SECRET as string,
callbackURL: `${url}/github/callback`,
},
async ({ profile }) => {
const user = createOrLoginWithGithub(profile);
return user;
}
);
const google = new GoogleStrategy(
{
clientID: "YOUR_CLIENT_ID",
clientSecret: "YOUR_CLIENT_SECRET",
callbackURL: `${url}/google/callback`,
},
async ({ profile }) => {
const user = createOrLoginWithGoogle(profile);
return user;
}
);
// Create an instance of the authenticator, pass a generic with what
// strategies will return and will store in the session
export const authenticator = new Authenticator<User>(sessionStorage);
if (process.env.GH_CLIENT_ID && process.env.GH_CLIENT_SECRET) {
authenticator.use(
new GitHubStrategy(
{
clientID: process.env.GH_CLIENT_ID as string,
clientSecret: process.env.GH_CLIENT_SECRET as string,
callbackURL: `https://${
process.env.VERCEL_URL || "192.168.1.91:3000"
}/auth/github/callback`,
},
async ({ profile }) => {
const user = createOrLoginWithGithub(profile);
return user;
}
),
"github"
);
authenticator.use(github, "github");
authenticator.use(google, "google");
}
+25
View File
@@ -1,5 +1,7 @@
import { User } from "@prisma/client";
import { GitHubProfile } from "remix-auth-github";
import { GoogleProfile } from "remix-auth-google";
import { ensureUserCookie } from "../session";
import { prisma } from "./prisma.server";
export const createOrLoginWithGithub = async (
@@ -24,3 +26,26 @@ export const createOrLoginWithGithub = async (
return newUser;
};
export const createOrLoginWithGoogle = async (
profile: GoogleProfile
): Promise<User> => {
const user = await prisma.user.findUnique({
where: { email: profile._json.email },
});
if (user) {
return user;
}
const newUser = prisma.user.create({
data: {
email: profile._json.email,
username: profile.displayName,
image: profile._json.avatar_url,
provider: profile.provider,
},
});
return newUser;
};
+24
View File
@@ -0,0 +1,24 @@
import * as React from "react";
import { IconProps } from "./types";
export const GithubIcon = React.forwardRef<SVGSVGElement, IconProps>(
({ color = "currentColor", ...props }, forwardedRef) => {
return (
<svg
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
{...props}
ref={forwardedRef}
>
<title>GitHub</title>
<path
d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"
fill={color}
/>
</svg>
);
}
);
GithubIcon.displayName = "GithubIcon";
+24
View File
@@ -0,0 +1,24 @@
import * as React from "react";
import { IconProps } from "./types";
export const GoogleIcon = React.forwardRef<SVGSVGElement, IconProps>(
({ color = "currentColor", ...props }, forwardedRef) => {
return (
<svg
role="img"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
{...props}
ref={forwardedRef}
>
<title>Google</title>
<path
d="M12.48 10.92v3.28h7.84c-.24 1.84-.853 3.187-1.787 4.133-1.147 1.147-2.933 2.4-6.053 2.4-4.827 0-8.6-3.893-8.6-8.72s3.773-8.72 8.6-8.72c2.6 0 4.507 1.027 5.907 2.347l2.307-2.307C18.747 1.44 16.133 0 12.48 0 5.867 0 .307 5.387.307 12s5.56 12 12.173 12c3.573 0 6.267-1.173 8.373-3.36 2.16-2.16 2.84-5.213 2.84-7.667 0-.76-.053-1.467-.173-2.053H12.48z"
fill={color}
/>
</svg>
);
}
);
GoogleIcon.displayName = "GoogleIcon";
+2
View File
@@ -4,6 +4,8 @@ export * from "./brush";
export * from "./form";
export * from "./undo";
export * from "./redo";
export * from "./google";
export * from "./github";
export * from "./devices";
export * from "./tablet";
export * from "./types";
+1
View File
@@ -72,6 +72,7 @@
"react-use": "^17.3.2",
"remix-auth": "^3.2.2",
"remix-auth-github": "^1.1.1",
"remix-auth-google": "^1.1.0",
"slugify": "^1.6.5"
},
"devDependencies": {
@@ -0,0 +1,19 @@
/*
Warnings:
- You are about to drop the column `createdAt` on the `User` table. All the data in the column will be lost.
- You are about to drop the column `email` on the `User` table. All the data in the column will be lost.
- You are about to drop the column `image` on the `User` table. All the data in the column will be lost.
- You are about to drop the column `provider` on the `User` table. All the data in the column will be lost.
- You are about to drop the column `username` on the `User` table. All the data in the column will be lost.
*/
-- DropIndex
DROP INDEX "User_email_key";
-- AlterTable
ALTER TABLE "User" DROP COLUMN "createdAt",
DROP COLUMN "email",
DROP COLUMN "image",
DROP COLUMN "provider",
DROP COLUMN "username";
@@ -0,0 +1,15 @@
/*
Warnings:
- A unique constraint covering the columns `[email]` on the table `User` will be added. If there are existing duplicate values, this will fail.
*/
-- AlterTable
ALTER TABLE "User" ADD COLUMN "createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
ADD COLUMN "email" TEXT,
ADD COLUMN "image" TEXT,
ADD COLUMN "provider" TEXT,
ADD COLUMN "username" TEXT;
-- CreateIndex
CREATE UNIQUE INDEX "User_email_key" ON "User"("email");
+11 -4
View File
@@ -10,6 +10,16 @@ datasource db {
url = env("DATABASE_URL")
}
model User {
id String @id @default(uuid())
email String? @unique
provider String?
image String?
username String?
createdAt DateTime @default(now())
projects Project[]
}
model Project {
id String @id @default(uuid())
userId String
@@ -18,10 +28,7 @@ model Project {
prodTreeId String? // exists when published
devTreeId String
prodTreeIdHistory String @default("[]")
}
model User {
id String @id @default(uuid())
User User @relation(fields: [userId], references: [id])
}
model Tree {
+8 -1
View File
@@ -12144,7 +12144,14 @@ remix-auth-github@^1.1.1:
remix-auth "^3.0.0"
remix-auth-oauth2 "^1.0.0"
remix-auth-oauth2@^1.0.0:
remix-auth-google@^1.1.0:
version "1.1.0"
resolved "https://registry.yarnpkg.com/remix-auth-google/-/remix-auth-google-1.1.0.tgz#4ffdc41b180a7a622d9008e7a25b6e409dbf5f20"
integrity sha512-yzZ8JEiSoY/cvo5eJQBIzqpnaWOjQkYCgBklCP1QwT01sdR2F066uhV+jR9Wcx0bPCntdMG4PrytVBJzWTg+BA==
dependencies:
remix-auth-oauth2 "^1.1.0"
remix-auth-oauth2@^1.0.0, remix-auth-oauth2@^1.1.0:
version "1.2.2"
resolved "https://registry.yarnpkg.com/remix-auth-oauth2/-/remix-auth-oauth2-1.2.2.tgz#bebe0ac586744ed94885bd47f6bcb710d377fede"
integrity sha512-bbQw/SFAbilSE1zrZFaJN/NM7WUkC63CKJFVz2e/Y21qqMZo5eVQXooSV6d23mABfodeVk6wthngdLAjxak6fQ==