Update pages and UI
This commit is contained in:
parent
da8882b162
commit
087ab36bb0
9 changed files with 371 additions and 63 deletions
9
src/components/Head.astro
Normal file
9
src/components/Head.astro
Normal file
|
@ -0,0 +1,9 @@
|
|||
---
|
||||
const { Title } = Astro.props
|
||||
---
|
||||
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=2.2" />
|
||||
<title>{Title}</title>
|
||||
</head>
|
35
src/components/Header.astro
Normal file
35
src/components/Header.astro
Normal file
|
@ -0,0 +1,35 @@
|
|||
---
|
||||
if (Astro.cookies.get('sb-access-token') && Astro.cookies.get('sb-refresh-token')) {
|
||||
var IsLoggedIn = true
|
||||
} else {
|
||||
var IsLoggedIn = false
|
||||
}
|
||||
|
||||
// Supabase Data
|
||||
import { supabase } from "../library/supabase"
|
||||
const { data: { user } } = await supabase.auth.getUser()
|
||||
const avatar = user?.user_metadata.avatar_url
|
||||
const beta = user?.user_metadata.beta
|
||||
---
|
||||
|
||||
<header>
|
||||
<div class="header-start">
|
||||
<h2><a href="/">Supabase Demo</a> {beta ? <span>Beta</span> : null}</h2>
|
||||
</div>
|
||||
<div class="header-end">
|
||||
{IsLoggedIn
|
||||
?
|
||||
<img src={avatar}/>
|
||||
<a href="/account">Account</a>
|
||||
<a href="/api/auth/signout">Sign Out</a>
|
||||
:
|
||||
<a href="/register">Register</a>
|
||||
<a href="/signin">Sign in</a>
|
||||
}
|
||||
</div>
|
||||
</header>
|
||||
|
||||
|
||||
<script is:inline>
|
||||
|
||||
</script>
|
16
src/layouts/Base.astro
Normal file
16
src/layouts/Base.astro
Normal file
|
@ -0,0 +1,16 @@
|
|||
---
|
||||
const {Title} = Astro.props
|
||||
import Head from "@components/Head.astro"
|
||||
import Header from "@components/Header.astro"
|
||||
import '@styles/root.scss'
|
||||
---
|
||||
|
||||
<html>
|
||||
<Head Title={Title}/>
|
||||
<Header/>
|
||||
<body>
|
||||
<div class="content">
|
||||
<slot/>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
|
@ -1,45 +1,146 @@
|
|||
---
|
||||
const { user, users } = Astro.locals
|
||||
if (!user) {return Astro.redirect("/signin")}
|
||||
import { SESSION_COOKIE, createAdminClient } from "../server/appwrite";
|
||||
import Base from "@layouts/Base.astro"
|
||||
|
||||
if (user.emailVerification) {var EmailIsVerified = true}
|
||||
else {var EmailIsVerified = false}
|
||||
// Messages
|
||||
if (Astro.url.href.endsWith('CheckEmail')) {var MessageCheckEmail = true}
|
||||
else {var MessageCheckEmail = false}
|
||||
|
||||
if (Astro.cookies.get('anonymous')) {var AN = true}
|
||||
else {var AN = false}
|
||||
if (Astro.url.href.endsWith('AvatarUpdated')) {var MessageAvatarUpdated = true}
|
||||
else {var MessageAvatarUpdated = false}
|
||||
|
||||
const { account } = createAdminClient();
|
||||
// const session = await account.createMagicURLToken(user.$id,user.email);
|
||||
if (Astro.url.href.endsWith('NameUpdated')) {var MessageNameUpdated = true}
|
||||
else {var MessageNameUpdated = false}
|
||||
|
||||
if (Astro.url.href.endsWith('EmailConfirmed')) {var MessageEmailConfirmed = true}
|
||||
else {var MessageEmailConfirmed = false}
|
||||
|
||||
if (Astro.url.href.endsWith('PasswordReset')) {var MessagePasswordReset = true}
|
||||
else {var MessagePasswordReset = false}
|
||||
|
||||
// Supabase Data
|
||||
import { supabase } from "../library/supabase"
|
||||
const { data: { user } } = await supabase.auth.getUser()
|
||||
const avatarUrl = user?.user_metadata.avatar_url
|
||||
const displayName = user?.user_metadata.full_name
|
||||
const email = user?.email
|
||||
const id = user?.id
|
||||
|
||||
// Get User Preferences
|
||||
const user_plan = user?.user_metadata.plan
|
||||
const user_theme = user?.user_metadata.theme
|
||||
const user_color_scheme = user?.user_metadata.color_scheme
|
||||
const user_beta = user?.user_metadata.beta
|
||||
|
||||
// Date - Readable Format (MONTH DAY, YEAR at #:##:## AM/PM / December 9, 2023 at 5:12:43 PM)
|
||||
const dateFormat = { year: 'numeric', month: 'long', day: 'numeric', hour: 'numeric', minute: 'numeric', second: 'numeric' }
|
||||
|
||||
/// Created Date
|
||||
const createdDate = new Date(user?.created_at)
|
||||
const createDate = createdDate.toLocaleDateString('en-US', dateFormat)
|
||||
|
||||
/// Last Logged In
|
||||
const lastSignIn = new Date(user?.last_sign_in_at)
|
||||
const lastSignInDate = lastSignIn.toLocaleDateString('en-US', dateFormat)
|
||||
---
|
||||
|
||||
<p>Email: {AN ? <span>None</span> : <span>{user.email}</span>} <span><button><a style="color: white; text-decoration: none;" href="/settings/update-username">Change</a></button></span></p>
|
||||
<p>ID: {user.$id}</p>
|
||||
<!-- <p>Phone: {user.phone}</p> -->
|
||||
<p>Name: {AN ? <span>Anonymous</span> : <span>{user.name}</span>} <span><button><a style="color: white; text-decoration: none;" href="/settings/update-username">Change</a></button></span></p>
|
||||
<p>Created at: {user.$createdAt}</p>
|
||||
<p>Last login: {user.accessedAt}</p>
|
||||
<p>Last updated: {user.$updatedAt}</p>
|
||||
<p>Labels:
|
||||
{user.labels.map((data) =>
|
||||
<ul>
|
||||
<li>{data}</li>
|
||||
</ul>
|
||||
)}
|
||||
</p>
|
||||
<Base Title="Account">
|
||||
<!-- Dummy Sidebar -->
|
||||
<div>
|
||||
<span class="dummies" style="width:80%;"></span>
|
||||
<span class="dummies" style="width:80%;"></span>
|
||||
<span class="dummies" style="width:80%;"></span>
|
||||
<span class="dummies" style="width:80%;"></span>
|
||||
<br/>
|
||||
<br/>
|
||||
<br/>
|
||||
<span class="dummies" style="width:80%;"></span>
|
||||
</div>
|
||||
|
||||
Theme: {user.prefs.darkTheme}
|
||||
<!-- Account -->
|
||||
<div class="dashboard-content">
|
||||
<!-- Messages -->
|
||||
{MessageCheckEmail ? <p class="message-in">Check your email</p> : null}
|
||||
{MessageAvatarUpdated ? <p class="message-in">Your avatar has been updated</p> : null}
|
||||
{MessageNameUpdated ? <p class="message-in">Your display name has been updated</p> : null}
|
||||
{MessageEmailConfirmed ? <p class="message-in">Email confirmed</p> : null}
|
||||
{MessagePasswordReset ? <p class="message-in">Your new password has been updated</p> : null}
|
||||
<!-- Account Information -->
|
||||
<h2>Your Account</h2>
|
||||
<p>Plan: {user_plan}</p>
|
||||
<p>Display Name: {displayName}</p>
|
||||
<p>Email: <u>{email}</u></p>
|
||||
<hr/>
|
||||
<p>ID: {id}</p>
|
||||
<p>Created at: {createDate}</p>
|
||||
<p>Lasted login: {lastSignInDate}</p>
|
||||
<hr/>
|
||||
<!-- Account Preferences -->
|
||||
<h2>Preferences</h2>
|
||||
<p>Theme: {user_theme}</p>
|
||||
<p>Color Scheme: {user_color_scheme}</p>
|
||||
{user_beta ?
|
||||
<form method="post" action="/api/account/beta-off"><button type="submit">Leave Beta</button></form>
|
||||
:
|
||||
<form method="post" action="/api/account/beta-on"><button type="submit">Enter Beta</button></form>
|
||||
}
|
||||
</p>
|
||||
<hr/>
|
||||
<!-- Account Actions -->
|
||||
<form action="/api/account/update-avatar" method="post">
|
||||
<p>Change Avatar</p>
|
||||
<div class="form-field">
|
||||
<label style="font-size: 12px;" for="avatar_url">Avatar URL</label>
|
||||
<input id="avatar_url" type="url" name="avatar_url" value={avatarUrl} required />
|
||||
</div>
|
||||
<button type="submit">Update</button>
|
||||
</form>
|
||||
<form action="/api/account/update-name" method="post">
|
||||
<p>Update Display Name</p>
|
||||
<div class="form-field">
|
||||
<label style="font-size: 12px;" for="name">New Display Name</label>
|
||||
<input id="name" type="text" name="name" value={displayName} required />
|
||||
</div>
|
||||
<button type="submit">Update</button>
|
||||
</form>
|
||||
<form action="/api/account/update-email" method="post">
|
||||
<p>Change Email</p>
|
||||
<div class="form-field">
|
||||
<label style="font-size: 12px;" for="email">New Email</label>
|
||||
<input id="email" type="email" name="email" value={email} required />
|
||||
</div>
|
||||
<button type="submit">Update</button>
|
||||
</form>
|
||||
<form action="/api/account/update-password" method="post">
|
||||
<p>Change Password</p>
|
||||
<div class="form-field">
|
||||
<label style="font-size: 12px;" for="password">New Password</label>
|
||||
<input id="password" type="password" name="password" oninput="CheckPasswordConfirmation()" required />
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label style="font-size: 12px;" for="confirm_password">Confirm Password</label>
|
||||
<input id="confirm_password" type="password" name="confirm_password" oninput="CheckPasswordConfirmation()" required />
|
||||
</div>
|
||||
<button type="submit">Update</button>
|
||||
</form>
|
||||
<p>Do you want to delete your accout? <form action="/api/account/delete" method="post"><button style="color: rgb(255, 125, 125); text-decoration: none;">Delete account</a>.</button></form>
|
||||
</div>
|
||||
</Base>
|
||||
|
||||
{EmailIsVerified ?
|
||||
<p>Your account is verified</p>
|
||||
:
|
||||
<p style="color: rgb(255, 113, 113)">Your account is not verified<!-- [<a href="/api/email/send-verification">Send Verification Email</a>] --></p>
|
||||
<script is:inline>
|
||||
function CheckPasswordConfirmation() {
|
||||
const input = document.getElementById('confirm_password');
|
||||
if (input.value !== document.getElementById('password').value) {
|
||||
input.setCustomValidity('Password Must be Matching.');
|
||||
} else {
|
||||
// input is valid -- reset the error message
|
||||
input.setCustomValidity('');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{AN ?
|
||||
<p>This is an anonmyous account.</p>
|
||||
:
|
||||
<p style="color: rgb(255, 113, 113)">Not an anonmyous account.</p>
|
||||
<style is:inline>
|
||||
.content {
|
||||
display: grid !important;
|
||||
grid-template-columns: 160px auto !important;
|
||||
}
|
||||
|
||||
<a href="/signout">Sign Out</a>
|
||||
</style>
|
26
src/pages/creator/C6nSFpj9HTCZ5t-N3Rm3-HA.astro
Normal file
26
src/pages/creator/C6nSFpj9HTCZ5t-N3Rm3-HA.astro
Normal file
|
@ -0,0 +1,26 @@
|
|||
---
|
||||
import Base from "@layouts/Base.astro"
|
||||
const CreatorId = Astro.url.href.split("creator/").pop()
|
||||
import { supabase } from "@library/supabase"
|
||||
const { data: { user } } = await supabase.auth.getUser()
|
||||
const id = user?.id
|
||||
|
||||
let { data: subs } = await supabase
|
||||
.from('subs')
|
||||
.select("*")
|
||||
.eq('UserSubscribed', id)
|
||||
.eq('Id', CreatorId)
|
||||
---
|
||||
|
||||
<Base Title="Supabase Demo">
|
||||
<div style="display: flex; justify-content: space-between; align-items: center;">
|
||||
<p style="font-size: 18px; font-weight: bold;">Vsause</p>
|
||||
<div>
|
||||
{subs[0].Subscribed ?
|
||||
<a style="font-size: 14px;" href={"/api/account/remove?=" + 'C6nSFpj9HTCZ5t-N3Rm3-HA'}>Unsubscribe</a>
|
||||
:
|
||||
<a style="font-size: 14px;" href={"/api/account/add?=" + 'C6nSFpj9HTCZ5t-N3Rm3-HA'}>Subscribe</a>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</Base>
|
|
@ -1,8 +1,55 @@
|
|||
---
|
||||
const { user } = Astro.locals;
|
||||
if (user) {
|
||||
return Astro.redirect("/account");
|
||||
import Base from "@layouts/Base.astro"
|
||||
|
||||
// Check Cookies
|
||||
if (Astro.cookies.get('sb-access-token') && Astro.cookies.get('sb-refresh-token')) {
|
||||
var IsLoggedIn = true
|
||||
} else {
|
||||
var IsLoggedIn = false
|
||||
}
|
||||
|
||||
return Astro.redirect("/signin");
|
||||
// Supabase Data
|
||||
import { supabase } from "../library/supabase"
|
||||
const { data: { user } } = await supabase.auth.getUser()
|
||||
const avatar = user?.user_metadata.avatar_url
|
||||
const displayName = user?.user_metadata.full_name
|
||||
const id = user?.id
|
||||
|
||||
// Get Channels
|
||||
const { data: channels, error } = await supabase
|
||||
.from('channels')
|
||||
.select('*')
|
||||
|
||||
|
||||
|
||||
let { data: subs } = await supabase
|
||||
.from('subs')
|
||||
.select("*")
|
||||
.eq('UserSubscribed', id)
|
||||
|
||||
|
||||
console.log(subs)
|
||||
---
|
||||
|
||||
<Base Title="Supabase Demo">
|
||||
{IsLoggedIn
|
||||
?
|
||||
<div class="welcome">
|
||||
<img src={avatar}/>
|
||||
<h2>Welcome back, {displayName}</h2>
|
||||
</div>
|
||||
:
|
||||
<div class="welcome">
|
||||
<h2>Welcome!</h2>
|
||||
</div>
|
||||
}
|
||||
<hr/>
|
||||
<h3>Channels</h3>
|
||||
{channels.map((channel) =>
|
||||
<a href={'/creator/' + channel.id}>{channel.creator}</a>
|
||||
)}
|
||||
<hr/>
|
||||
{subs.map((data) =>
|
||||
<p><a href={'/creator/' + data.Id}>{data.Id}</a> | <a href={'/api/account/remove?=' + data.Id}>Unsubscribe</a></p>
|
||||
)}
|
||||
</Base>
|
39
src/pages/register.astro
Normal file
39
src/pages/register.astro
Normal file
|
@ -0,0 +1,39 @@
|
|||
---
|
||||
import Base from "@layouts/Base.astro"
|
||||
---
|
||||
|
||||
<Base Title="Supabase - Register">
|
||||
<h2>Register for Supabase Demo</h2>
|
||||
<p>Already have an account? <a href="/signin">Sign In</a>.</p>
|
||||
<form action="/api/auth/register" method="post">
|
||||
<div class="form-field">
|
||||
<label for="name">Avatar URL</label>
|
||||
<input id="avatar_url" type="url" name="avatar_url" placeholder="https://example.com/profile.png" />
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label for="name">Name</label>
|
||||
<input id="name" type="text" name="name" placeholder="John Smith" />
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label for="email">Email</label>
|
||||
<input id="email" type="email" name="email" placeholder="john@example.com" />
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label for="password">Password</label>
|
||||
<input id="password" type="password" name="password" />
|
||||
</div>
|
||||
<button type="submit">Register</button>
|
||||
</form>
|
||||
<hr/>
|
||||
<p>
|
||||
<span>Or with</span>
|
||||
</p>
|
||||
<form action="/api/auth/signin" method="post">
|
||||
<div class="oauth-grid">
|
||||
<button value="github" name="provider" type="submit">Sign Up with GitHub</button>
|
||||
<button value="gitlab" name="provider" type="submit">Sign Up with GitLab</button>
|
||||
<button value="spotify" name="provider" type="submit">Sign Up with Spotify</button>
|
||||
<button value="discord" name="provider" type="submit">Sign Up with Discord</button>
|
||||
</div>
|
||||
</form>
|
||||
</Base>
|
32
src/pages/reset-password.astro
Normal file
32
src/pages/reset-password.astro
Normal file
|
@ -0,0 +1,32 @@
|
|||
---
|
||||
import Base from "@layouts/Base.astro"
|
||||
---
|
||||
|
||||
<Base Title="Account">
|
||||
<div class="content">
|
||||
<form action="/api/account/reset-password" method="post">
|
||||
<p>Change Password</p>
|
||||
<div class="form-field">
|
||||
<label style="font-size: 12px;" for="password">New Password</label>
|
||||
<input id="password" type="password" name="password" oninput="CheckPasswordConfirmation()" required />
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label style="font-size: 12px;" for="confirm_password">Confirm Password</label>
|
||||
<input id="confirm_password" type="password" name="confirm_password" oninput="CheckPasswordConfirmation()" required />
|
||||
</div>
|
||||
<button type="submit">Update</button>
|
||||
</form>
|
||||
</div>
|
||||
</Base>
|
||||
|
||||
<script is:inline>
|
||||
function CheckPasswordConfirmation() {
|
||||
const input = document.getElementById('confirm_password');
|
||||
if (input.value !== document.getElementById('password').value) {
|
||||
input.setCustomValidity('Password Must be Matching.');
|
||||
} else {
|
||||
// input is valid -- reset the error message
|
||||
input.setCustomValidity('');
|
||||
}
|
||||
}
|
||||
</script>
|
|
@ -1,28 +1,31 @@
|
|||
---
|
||||
import SignInUp from "../layouts/SignInUp.astro";
|
||||
|
||||
import { ID } from "node-appwrite";
|
||||
import { SESSION_COOKIE, createAdminClient } from "../server/appwrite";
|
||||
|
||||
if (Astro.request.method === "POST") {
|
||||
const data = await Astro.request.formData();
|
||||
|
||||
const email = data.get("email") as string;
|
||||
const password = data.get("password") as string;
|
||||
|
||||
const { account } = createAdminClient();
|
||||
const session = await account.createEmailPasswordSession(email, password);
|
||||
|
||||
Astro.cookies.set(SESSION_COOKIE, session.secret, {
|
||||
path: "/",
|
||||
expires: new Date(session.expire),
|
||||
sameSite: "strict",
|
||||
secure: true,
|
||||
httpOnly: true,
|
||||
});
|
||||
|
||||
return Astro.redirect("/account");
|
||||
}
|
||||
import Base from "@layouts/Base.astro"
|
||||
---
|
||||
|
||||
<SignInUp Title="Demo Login" Type="SignIn"/>
|
||||
<Base Title="Supabase - Sign In">
|
||||
<h2>Sign In</h2>
|
||||
<p>Don't have an account? <a href="/register">Sign Up</a>.</p>
|
||||
<form action="/api/auth/signin" method="post">
|
||||
<div class="form-field">
|
||||
<label for="email">Email</label>
|
||||
<input id="email" type="email" name="email" />
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<label for="password">Password</label>
|
||||
<input id="password" type="password" name="password" />
|
||||
</div>
|
||||
<button type="submit">Sign In</button>
|
||||
<hr />
|
||||
<p>
|
||||
<span>Or with</span>
|
||||
</p>
|
||||
<form action="/api/auth/signin" method="post">
|
||||
<div class="oauth-grid">
|
||||
<button value="github" name="provider" type="submit">Sign In with GitHub</button>
|
||||
<button value="gitlab" name="provider" type="submit">Sign In with GitLab</button>
|
||||
<button value="spotify" name="provider" type="submit">Sign In with Spotify</button>
|
||||
<button value="discord" name="provider" type="submit">Sign In with Discord</button>
|
||||
</div>
|
||||
</form>
|
||||
</form>
|
||||
</Base>
|
||||
|
|
Loading…
Reference in a new issue