mirror of
https://github.com/kamranahmedse/developer-roadmap.git
synced 2025-08-26 10:34:40 +02:00
Refactor account pages
This commit is contained in:
85
src/components/AccountSidebar.astro
Normal file
85
src/components/AccountSidebar.astro
Normal file
@@ -0,0 +1,85 @@
|
|||||||
|
---
|
||||||
|
import Icon from './AstroIcon.astro';
|
||||||
|
|
||||||
|
const { activePageId, activePageTitle } = Astro.props;
|
||||||
|
|
||||||
|
export interface Props {
|
||||||
|
activePageId: string;
|
||||||
|
activePageTitle: string;
|
||||||
|
}
|
||||||
|
---
|
||||||
|
|
||||||
|
<div class='relative block mb-5 md:hidden p-4 border-b shadow-inner'>
|
||||||
|
<button
|
||||||
|
class='flex h-10 w-full items-center justify-between rounded-md border bg-white px-2 text-center font-medium text-gray-900'
|
||||||
|
id='settings-menu'
|
||||||
|
>
|
||||||
|
{activePageTitle}
|
||||||
|
<Icon icon='dropdown' />
|
||||||
|
</button>
|
||||||
|
<ul
|
||||||
|
id='settings-menu-dropdown'
|
||||||
|
class='absolute mt-1 hidden left-0 right-0 space-y-1.5 bg-white p-2 shadow-lg z-10'
|
||||||
|
>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href='/account/update-profile'
|
||||||
|
class=`block w-full rounded px-2 py-1.5 font-medium text-slate-900 hover:bg-slate-200 ${activePageId === 'profile' ? 'bg-slate-100' : ''}`
|
||||||
|
>Profile</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href='/account/update-password'
|
||||||
|
class=`block w-full rounded px-2 py-1.5 font-medium text-slate-900 hover:bg-slate-200 ${activePageId === 'change-password' ? 'bg-slate-100' : ''}`
|
||||||
|
>Change password</a
|
||||||
|
>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class='container flex min-h-screen items-stretch'>
|
||||||
|
<!-- Start Desktop Sidebar -->
|
||||||
|
<aside class='hidden w-56 border-r border-slate-200 py-10 pr-5 md:block'>
|
||||||
|
<nav>
|
||||||
|
<ul class='space-y-1'>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href='/account/update-profile'
|
||||||
|
class=`block w-full rounded px-2 py-1.5 font-regular text-slate-900 hover:bg-slate-100 ${activePageId === 'profile' ? 'bg-slate-100' : ''}`
|
||||||
|
>
|
||||||
|
Profile
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<a
|
||||||
|
href='/account/update-password'
|
||||||
|
class=`block w-full rounded px-2 py-1.5 font-regular text-slate-900 hover:bg-slate-100 ${activePageId === 'change-password' ? 'bg-slate-100' : ''}`
|
||||||
|
>
|
||||||
|
Security
|
||||||
|
</a>
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</nav>
|
||||||
|
</aside>
|
||||||
|
<!-- /End Desktop Sidebar -->
|
||||||
|
|
||||||
|
<div class='grow px-0 py-0 md:px-10 md:py-10'>
|
||||||
|
<slot />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const menuButton = document.getElementById('settings-menu');
|
||||||
|
const menuDropdown = document.getElementById('settings-menu-dropdown');
|
||||||
|
|
||||||
|
menuButton?.addEventListener('click', () => {
|
||||||
|
menuDropdown?.classList.toggle('hidden');
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('click', (e) => {
|
||||||
|
if (!menuButton?.contains(e.target as Node)) {
|
||||||
|
menuDropdown?.classList.add('hidden');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
</script>
|
@@ -32,8 +32,8 @@ function showHideGuestElements(hideOrShow: 'hide' | 'show' = 'hide') {
|
|||||||
// Prepares the UI for the user who is logged in
|
// Prepares the UI for the user who is logged in
|
||||||
function handleGuest() {
|
function handleGuest() {
|
||||||
const authenticatedRoutes = [
|
const authenticatedRoutes = [
|
||||||
'/settings/update-profile',
|
'/account/update-profile',
|
||||||
'/settings/update-password',
|
'/account/update-password',
|
||||||
];
|
];
|
||||||
|
|
||||||
showHideAuthElements('hide');
|
showHideAuthElements('hide');
|
||||||
|
@@ -1,5 +0,0 @@
|
|||||||
---
|
|
||||||
---
|
|
||||||
|
|
||||||
<div class='recaptcha-field mb-2'></div>
|
|
||||||
<input type='hidden' name='g-recaptcha-response' class='recaptcha-response' />
|
|
@@ -1,36 +0,0 @@
|
|||||||
---
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
<script src='./captcha.js'></script>
|
|
||||||
|
|
||||||
<script is:inline>
|
|
||||||
window.onCaptchaLoad = function () {
|
|
||||||
if (!window.grecaptcha) {
|
|
||||||
console.warn('window.grecaptcha is not defined');
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const recaptchaFields = document.querySelectorAll('.recaptcha-field');
|
|
||||||
|
|
||||||
// render recaptcha on fields
|
|
||||||
recaptchaFields.forEach((field) => {
|
|
||||||
// If captcha already rendered for this field
|
|
||||||
if (field.hasAttribute('data-recaptcha-id')) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
const renderedId = window.grecaptcha.render(field, {
|
|
||||||
sitekey: '6Ldn2YsjAAAAABlUxNxukAuDAUIuZIhO0hRVxzJW',
|
|
||||||
});
|
|
||||||
|
|
||||||
field.setAttribute('data-recaptcha-id', renderedId);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<script
|
|
||||||
src='https://www.google.com/recaptcha/api.js?onload=onCaptchaLoad&render=explicit'
|
|
||||||
async
|
|
||||||
defer
|
|
||||||
></script>
|
|
@@ -1,49 +0,0 @@
|
|||||||
class Captcha {
|
|
||||||
constructor() {
|
|
||||||
this.onDOMLoaded = this.onDOMLoaded.bind(this);
|
|
||||||
this.bindValidation = this.bindValidation.bind(this);
|
|
||||||
this.validateCaptchaBeforeSubmit =
|
|
||||||
this.validateCaptchaBeforeSubmit.bind(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
validateCaptchaBeforeSubmit(e) {
|
|
||||||
const target = e.target;
|
|
||||||
const captchaField = target.querySelector('.recaptcha-field');
|
|
||||||
|
|
||||||
if (captchaField) {
|
|
||||||
const captchaId = captchaField.dataset.recaptchaId;
|
|
||||||
const captchaResponse = window.grecaptcha.getResponse(captchaId);
|
|
||||||
|
|
||||||
// If valid captcha is not present, prevent form submission
|
|
||||||
if (!captchaResponse) {
|
|
||||||
e.preventDefault();
|
|
||||||
alert('Please verify that you are human first');
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
target.querySelector('.recaptcha-response').value = captchaResponse;
|
|
||||||
}
|
|
||||||
|
|
||||||
target.closest('.popup').classList.add('hidden');
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
bindValidation() {
|
|
||||||
const forms = document.querySelectorAll('[captcha-form]');
|
|
||||||
|
|
||||||
forms.forEach((form) => {
|
|
||||||
form.addEventListener('submit', this.validateCaptchaBeforeSubmit);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
onDOMLoaded() {
|
|
||||||
this.bindValidation();
|
|
||||||
}
|
|
||||||
|
|
||||||
init() {
|
|
||||||
window.addEventListener('DOMContentLoaded', this.onDOMLoaded);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const captcha = new Captcha();
|
|
||||||
captcha.init();
|
|
@@ -1,14 +1,14 @@
|
|||||||
import { useEffect, useRef, useState } from 'preact/hooks';
|
import { useEffect, useRef, useState } from 'preact/hooks';
|
||||||
|
import { useKeydown } from '../../hooks/use-keydown';
|
||||||
|
import { useOutsideClick } from '../../hooks/use-outside-click';
|
||||||
import BestPracticesIcon from '../../icons/best-practices.svg';
|
import BestPracticesIcon from '../../icons/best-practices.svg';
|
||||||
import HomeIcon from '../../icons/home.svg';
|
|
||||||
import UserIcon from '../../icons/user.svg';
|
|
||||||
import RoadmapIcon from '../../icons/roadmap.svg';
|
|
||||||
import GuideIcon from '../../icons/guide.svg';
|
import GuideIcon from '../../icons/guide.svg';
|
||||||
|
import HomeIcon from '../../icons/home.svg';
|
||||||
|
import RoadmapIcon from '../../icons/roadmap.svg';
|
||||||
|
import UserIcon from '../../icons/user.svg';
|
||||||
import VideoIcon from '../../icons/video.svg';
|
import VideoIcon from '../../icons/video.svg';
|
||||||
import { httpGet } from '../../lib/http';
|
import { httpGet } from '../../lib/http';
|
||||||
import { useKeydown } from '../../hooks/use-keydown';
|
|
||||||
import { isLoggedIn } from '../../lib/jwt';
|
import { isLoggedIn } from '../../lib/jwt';
|
||||||
import { useOutsideClick } from '../../hooks/use-outside-click';
|
|
||||||
|
|
||||||
type PageType = {
|
type PageType = {
|
||||||
url: string;
|
url: string;
|
||||||
@@ -21,7 +21,7 @@ type PageType = {
|
|||||||
const defaultPages: PageType[] = [
|
const defaultPages: PageType[] = [
|
||||||
{ url: '/', title: 'Home', group: 'Pages', icon: HomeIcon },
|
{ url: '/', title: 'Home', group: 'Pages', icon: HomeIcon },
|
||||||
{
|
{
|
||||||
url: '/settings/update-profile',
|
url: '/account/update-profile',
|
||||||
title: 'Account',
|
title: 'Account',
|
||||||
group: 'Pages',
|
group: 'Pages',
|
||||||
icon: UserIcon,
|
icon: UserIcon,
|
||||||
|
@@ -24,7 +24,7 @@ import Icon from '../AstroIcon.astro';
|
|||||||
<ul>
|
<ul>
|
||||||
<li class='px-1'>
|
<li class='px-1'>
|
||||||
<a
|
<a
|
||||||
href='/settings/update-profile'
|
href='/account/update-profile'
|
||||||
class='block rounded px-4 py-2 text-sm font-medium text-slate-100 hover:bg-slate-700'
|
class='block rounded px-4 py-2 text-sm font-medium text-slate-100 hover:bg-slate-700'
|
||||||
>
|
>
|
||||||
Settings
|
Settings
|
||||||
|
@@ -98,7 +98,7 @@ import AccountDropdown from './AccountDropdown.astro';
|
|||||||
<!-- Links for logged in users -->
|
<!-- Links for logged in users -->
|
||||||
<li data-auth-required class='hidden'>
|
<li data-auth-required class='hidden'>
|
||||||
<a
|
<a
|
||||||
href='/settings/update-profile'
|
href='/account/update-profile'
|
||||||
class='text-xl hover:text-blue-300 md:text-lg'
|
class='text-xl hover:text-blue-300 md:text-lg'
|
||||||
>
|
>
|
||||||
Settings
|
Settings
|
||||||
|
@@ -1,81 +0,0 @@
|
|||||||
---
|
|
||||||
import Icon from '../AstroIcon.astro';
|
|
||||||
const { pageUrl, name } = Astro.props;
|
|
||||||
|
|
||||||
export interface Props {
|
|
||||||
pageUrl: string;
|
|
||||||
name: string;
|
|
||||||
}
|
|
||||||
---
|
|
||||||
|
|
||||||
<div
|
|
||||||
class='container flex min-h-[calc(100vh-37px-70px)] items-stretch sm:min-h-[calc(100vh-37px-96px)]'
|
|
||||||
>
|
|
||||||
<aside class='hidden w-56 border-r border-slate-200 py-10 pr-5 md:block'>
|
|
||||||
<nav>
|
|
||||||
<ul class='space-y-1'>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
href='/settings/update-profile'
|
|
||||||
class=`block w-full rounded px-2 py-1.5 font-regular text-slate-900 hover:bg-slate-100 ${pageUrl === 'profile' ? 'bg-slate-100' : ''}`
|
|
||||||
>Profile</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
href='/settings/update-password'
|
|
||||||
class=`block w-full rounded px-2 py-1.5 font-regular text-slate-900 hover:bg-slate-100 ${pageUrl === 'change-password' ? 'bg-slate-100' : ''}`
|
|
||||||
>Security</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</nav>
|
|
||||||
</aside>
|
|
||||||
<div class='grow py-10 pl-0 md:p-10 md:pr-0'>
|
|
||||||
<div class='relative mb-5 md:hidden'>
|
|
||||||
<button
|
|
||||||
class='flex h-10 w-full items-center justify-between rounded-md bg-slate-800 px-2 text-center font-medium text-slate-100'
|
|
||||||
id='settings-menu'
|
|
||||||
>
|
|
||||||
{name}
|
|
||||||
<Icon icon='dropdown' />
|
|
||||||
</button>
|
|
||||||
<ul
|
|
||||||
id='settings-menu-dropdown'
|
|
||||||
class='absolute mt-1 hidden w-full space-y-1.5 rounded-md bg-white p-2 shadow-lg'
|
|
||||||
>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
href='/settings/update-profile'
|
|
||||||
class=`block w-full rounded px-2 py-1.5 font-medium text-slate-900 hover:bg-slate-200 ${pageUrl === 'profile' ? 'bg-slate-100' : ''}`
|
|
||||||
>Profile</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<a
|
|
||||||
href='/settings/update-password'
|
|
||||||
class=`block w-full rounded px-2 py-1.5 font-medium text-slate-900 hover:bg-slate-200 ${pageUrl === 'change-password' ? 'bg-slate-100' : ''}`
|
|
||||||
>Change password</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<slot />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
const menuButton = document.getElementById('settings-menu');
|
|
||||||
const menuDropdown = document.getElementById('settings-menu-dropdown');
|
|
||||||
|
|
||||||
menuButton?.addEventListener('click', () => {
|
|
||||||
menuDropdown?.classList.toggle('hidden');
|
|
||||||
});
|
|
||||||
|
|
||||||
document.addEventListener('click', (e) => {
|
|
||||||
if (!menuButton?.contains(e.target as Node)) {
|
|
||||||
menuDropdown?.classList.add('hidden');
|
|
||||||
}
|
|
||||||
});
|
|
||||||
</script>
|
|
@@ -78,9 +78,11 @@ export default function UpdatePasswordForm() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit}>
|
<form onSubmit={handleSubmit}>
|
||||||
|
<div class="hidden md:block mb-8">
|
||||||
<h2 className="text-3xl font-bold sm:text-4xl">Password</h2>
|
<h2 className="text-3xl font-bold sm:text-4xl">Password</h2>
|
||||||
<p className="mt-2">Use the form below to update your password.</p>
|
<p className="mt-2">Use the form below to update your password.</p>
|
||||||
<div className="mt-8 space-y-4">
|
</div>
|
||||||
|
<div className="space-y-4">
|
||||||
{authProvider === 'email' && (
|
{authProvider === 'email' && (
|
||||||
<div className="flex w-full flex-col">
|
<div className="flex w-full flex-col">
|
||||||
<label
|
<label
|
||||||
@@ -132,7 +134,7 @@ export default function UpdatePasswordForm() {
|
|||||||
for="new-password-confirmation"
|
for="new-password-confirmation"
|
||||||
className="text-sm leading-none text-slate-500"
|
className="text-sm leading-none text-slate-500"
|
||||||
>
|
>
|
||||||
New Password Confirm
|
Confirm New Password
|
||||||
</label>
|
</label>
|
||||||
<input
|
<input
|
||||||
type="password"
|
type="password"
|
||||||
@@ -141,7 +143,7 @@ export default function UpdatePasswordForm() {
|
|||||||
className="mt-2 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
className="mt-2 block w-full rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
|
||||||
required
|
required
|
||||||
minLength={6}
|
minLength={6}
|
||||||
placeholder="New password confirm"
|
placeholder="Confirm New Password"
|
||||||
value={newPasswordConfirmation}
|
value={newPasswordConfirmation}
|
||||||
onInput={(e) =>
|
onInput={(e) =>
|
||||||
setNewPasswordConfirmation((e.target as HTMLInputElement).value)
|
setNewPasswordConfirmation((e.target as HTMLInputElement).value)
|
@@ -1,7 +1,7 @@
|
|||||||
import { useEffect, useState } from 'preact/hooks';
|
import { useEffect, useState } from 'preact/hooks';
|
||||||
import { httpGet, httpPost } from '../../lib/http';
|
import { httpGet, httpPost } from '../../lib/http';
|
||||||
import { pageLoadingMessage } from '../../stores/page';
|
import { pageLoadingMessage } from '../../stores/page';
|
||||||
import UploadProfilePicture from '../Profile/UploadProfilePicture';
|
import UploadProfilePicture from './UploadProfilePicture';
|
||||||
|
|
||||||
export function UpdateProfileForm() {
|
export function UpdateProfileForm() {
|
||||||
const [name, setName] = useState('');
|
const [name, setName] = useState('');
|
||||||
@@ -81,8 +81,10 @@ export function UpdateProfileForm() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
|
<div className="mb-8 hidden md:block">
|
||||||
<h2 className="text-3xl font-bold sm:text-4xl">Profile</h2>
|
<h2 className="text-3xl font-bold sm:text-4xl">Profile</h2>
|
||||||
<p className="mt-2">Update your profile details below.</p>
|
<p className="mt-2">Update your profile details below.</p>
|
||||||
|
</div>
|
||||||
<UploadProfilePicture
|
<UploadProfilePicture
|
||||||
avatarUrl={
|
avatarUrl={
|
||||||
avatar
|
avatar
|
@@ -1,7 +1,6 @@
|
|||||||
import { useEffect, useRef, useState } from 'preact/hooks';
|
|
||||||
import Cookies from 'js-cookie';
|
import Cookies from 'js-cookie';
|
||||||
|
import { useEffect, useRef, useState } from 'preact/hooks';
|
||||||
import { TOKEN_COOKIE_NAME } from '../../lib/jwt';
|
import { TOKEN_COOKIE_NAME } from '../../lib/jwt';
|
||||||
import { httpCall, httpPost } from '../../lib/http';
|
|
||||||
|
|
||||||
interface PreviewFile extends File {
|
interface PreviewFile extends File {
|
||||||
preview: string;
|
preview: string;
|
||||||
@@ -131,7 +130,7 @@ export default function UploadProfilePicture(props: UploadProfilePictureProps) {
|
|||||||
<form
|
<form
|
||||||
onSubmit={handleSubmit}
|
onSubmit={handleSubmit}
|
||||||
encType="multipart/form-data"
|
encType="multipart/form-data"
|
||||||
className="mt-8 flex flex-col gap-2"
|
className="flex flex-col gap-2"
|
||||||
>
|
>
|
||||||
<label htmlFor="avatar" className="text-sm leading-none text-slate-500">
|
<label htmlFor="avatar" className="text-sm leading-none text-slate-500">
|
||||||
Profile Picture
|
Profile Picture
|
16
src/pages/account/update-password.astro
Normal file
16
src/pages/account/update-password.astro
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
---
|
||||||
|
import AccountSidebar from '../../components/AccountSidebar.astro';
|
||||||
|
import UpdatePasswordForm from '../../components/UpdatePassword/UpdatePasswordForm';
|
||||||
|
import AccountLayout from '../../layouts/AccountLayout.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<AccountLayout
|
||||||
|
title='Change Password'
|
||||||
|
description=''
|
||||||
|
noIndex={true}
|
||||||
|
initialLoadingMessage={'Loading profile'}
|
||||||
|
>
|
||||||
|
<AccountSidebar activePageId='change-password' activePageTitle='Change Password'>
|
||||||
|
<UpdatePasswordForm client:load />
|
||||||
|
</AccountSidebar>
|
||||||
|
</AccountLayout>
|
15
src/pages/account/update-profile.astro
Normal file
15
src/pages/account/update-profile.astro
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
import AccountSidebar from '../../components/AccountSidebar.astro';
|
||||||
|
import { UpdateProfileForm } from '../../components/UpdateProfile/UpdateProfileForm';
|
||||||
|
import AccountLayout from '../../layouts/AccountLayout.astro';
|
||||||
|
---
|
||||||
|
|
||||||
|
<AccountLayout
|
||||||
|
title='Update Profile'
|
||||||
|
noIndex={true}
|
||||||
|
initialLoadingMessage={'Loading profile'}
|
||||||
|
>
|
||||||
|
<AccountSidebar activePageId='profile' activePageTitle='Profile'>
|
||||||
|
<UpdateProfileForm client:load />
|
||||||
|
</AccountSidebar>
|
||||||
|
</AccountLayout>
|
@@ -1,9 +1,9 @@
|
|||||||
---
|
---
|
||||||
import { ForgotPasswordForm } from '../components/AuthenticationFlow/ForgotPasswordForm';
|
import { ForgotPasswordForm } from '../components/AuthenticationFlow/ForgotPasswordForm';
|
||||||
import SettingLayout from '../layouts/SettingLayout.astro';
|
import AccountLayout from '../layouts/AccountLayout.astro';
|
||||||
---
|
---
|
||||||
|
|
||||||
<SettingLayout title='Forgot Password' noIndex={true}>
|
<AccountLayout title='Forgot Password' noIndex={true}>
|
||||||
<div class='container'>
|
<div class='container'>
|
||||||
<div
|
<div
|
||||||
class='mx-auto flex flex-col items-start justify-start pb-28 pt-10 sm:max-w-[400px] sm:items-center sm:justify-center sm:pt-20'
|
class='mx-auto flex flex-col items-start justify-start pb-28 pt-10 sm:max-w-[400px] sm:items-center sm:justify-center sm:pt-20'
|
||||||
@@ -29,4 +29,4 @@ import SettingLayout from '../layouts/SettingLayout.astro';
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</SettingLayout>
|
</AccountLayout>
|
||||||
|
@@ -1,12 +1,12 @@
|
|||||||
---
|
---
|
||||||
import Divider from '../components/AuthenticationFlow/Divider.astro';
|
import Divider from '../components/AuthenticationFlow/Divider.astro';
|
||||||
|
import EmailLoginForm from '../components/AuthenticationFlow/EmailLoginForm';
|
||||||
import { GitHubButton } from '../components/AuthenticationFlow/GitHubButton';
|
import { GitHubButton } from '../components/AuthenticationFlow/GitHubButton';
|
||||||
import { GoogleButton } from '../components/AuthenticationFlow/GoogleButton';
|
import { GoogleButton } from '../components/AuthenticationFlow/GoogleButton';
|
||||||
import EmailLoginForm from '../components/AuthenticationFlow/EmailLoginForm';
|
import AccountLayout from '../layouts/AccountLayout.astro';
|
||||||
import SettingLayout from '../layouts/SettingLayout.astro';
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<SettingLayout
|
<AccountLayout
|
||||||
title='Login - roadmap.sh'
|
title='Login - roadmap.sh'
|
||||||
description='Register yourself to receive occasional emails about new roadmaps, updates, guides and videos'
|
description='Register yourself to receive occasional emails about new roadmaps, updates, guides and videos'
|
||||||
permalink={'/signup'}
|
permalink={'/signup'}
|
||||||
@@ -38,4 +38,4 @@ import SettingLayout from '../layouts/SettingLayout.astro';
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</SettingLayout>
|
</AccountLayout>
|
||||||
|
@@ -1,9 +1,9 @@
|
|||||||
---
|
---
|
||||||
import ResetPasswordForm from '../components/AuthenticationFlow/ResetPasswordForm';
|
import ResetPasswordForm from '../components/AuthenticationFlow/ResetPasswordForm';
|
||||||
import SettingLayout from '../layouts/SettingLayout.astro';
|
import AccountLayout from '../layouts/AccountLayout.astro';
|
||||||
---
|
---
|
||||||
|
|
||||||
<SettingLayout title='Reset Password' noIndex={true}>
|
<AccountLayout title='Reset Password' noIndex={true}>
|
||||||
<div class='container'>
|
<div class='container'>
|
||||||
<div
|
<div
|
||||||
class='mx-auto flex flex-col items-start justify-start pb-28 pt-10 sm:max-w-[400px] sm:items-center sm:justify-center sm:pt-20'
|
class='mx-auto flex flex-col items-start justify-start pb-28 pt-10 sm:max-w-[400px] sm:items-center sm:justify-center sm:pt-20'
|
||||||
@@ -20,4 +20,4 @@ import SettingLayout from '../layouts/SettingLayout.astro';
|
|||||||
<ResetPasswordForm client:load />
|
<ResetPasswordForm client:load />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</SettingLayout>
|
</AccountLayout>
|
||||||
|
@@ -1,16 +0,0 @@
|
|||||||
---
|
|
||||||
import SettingSidebar from '../../components/Setting/SettingSidebar.astro';
|
|
||||||
import UpdatePasswordForm from '../../components/Setting/UpdatePasswordForm';
|
|
||||||
import SettingLayout from '../../layouts/SettingLayout.astro';
|
|
||||||
---
|
|
||||||
|
|
||||||
<SettingLayout
|
|
||||||
title='Change Password'
|
|
||||||
description=''
|
|
||||||
noIndex={true}
|
|
||||||
initialLoadingMessage={'Loading profile'}
|
|
||||||
>
|
|
||||||
<SettingSidebar pageUrl='change-password' name='Change Password'>
|
|
||||||
<UpdatePasswordForm client:load />
|
|
||||||
</SettingSidebar>
|
|
||||||
</SettingLayout>
|
|
@@ -1,15 +0,0 @@
|
|||||||
---
|
|
||||||
import SettingSidebar from '../../components/Setting/SettingSidebar.astro';
|
|
||||||
import { UpdateProfileForm } from '../../components/Setting/UpdateProfileForm';
|
|
||||||
import SettingLayout from '../../layouts/SettingLayout.astro';
|
|
||||||
---
|
|
||||||
|
|
||||||
<SettingLayout
|
|
||||||
title='Update Profile'
|
|
||||||
noIndex={true}
|
|
||||||
initialLoadingMessage={'Loading profile'}
|
|
||||||
>
|
|
||||||
<SettingSidebar pageUrl='profile' name='Profile'>
|
|
||||||
<UpdateProfileForm client:load />
|
|
||||||
</SettingSidebar>
|
|
||||||
</SettingLayout>
|
|
@@ -1,13 +1,12 @@
|
|||||||
---
|
---
|
||||||
import Divider from '../components/AuthenticationFlow/Divider.astro';
|
import Divider from '../components/AuthenticationFlow/Divider.astro';
|
||||||
import GoogleLogin from '../components/Login/GoogleLogin.astro';
|
|
||||||
import EmailSignupForm from '../components/AuthenticationFlow/EmailSignupForm';
|
import EmailSignupForm from '../components/AuthenticationFlow/EmailSignupForm';
|
||||||
import SettingLayout from '../layouts/SettingLayout.astro';
|
|
||||||
import { GitHubButton } from '../components/AuthenticationFlow/GitHubButton';
|
import { GitHubButton } from '../components/AuthenticationFlow/GitHubButton';
|
||||||
import { GoogleButton } from '../components/AuthenticationFlow/GoogleButton';
|
import { GoogleButton } from '../components/AuthenticationFlow/GoogleButton';
|
||||||
|
import AccountLayout from '../layouts/AccountLayout.astro';
|
||||||
---
|
---
|
||||||
|
|
||||||
<SettingLayout
|
<AccountLayout
|
||||||
title='Signup - roadmap.sh'
|
title='Signup - roadmap.sh'
|
||||||
description='Create an account to track your progress, showcase your skillset'
|
description='Create an account to track your progress, showcase your skillset'
|
||||||
permalink={'/signup'}
|
permalink={'/signup'}
|
||||||
@@ -46,4 +45,4 @@ import { GoogleButton } from '../components/AuthenticationFlow/GoogleButton';
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</SettingLayout>
|
</AccountLayout>
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
import { VerificationEmailMessage } from '../components/AuthenticationFlow/VerificationEmailMessage';
|
import { VerificationEmailMessage } from '../components/AuthenticationFlow/VerificationEmailMessage';
|
||||||
import SettingLayout from '../layouts/SettingLayout.astro';
|
import AccountLayout from '../layouts/AccountLayout.astro';
|
||||||
---
|
---
|
||||||
|
|
||||||
<SettingLayout title='Verify Email' noIndex={true}>
|
<AccountLayout title='Verify Email' noIndex={true}>
|
||||||
<section class='container py-8 sm:py-20'>
|
<section class='container py-8 sm:py-20'>
|
||||||
<VerificationEmailMessage client:load />
|
<VerificationEmailMessage client:load />
|
||||||
</section>
|
</section>
|
||||||
</SettingLayout>
|
</AccountLayout>
|
||||||
|
@@ -1,10 +1,10 @@
|
|||||||
---
|
---
|
||||||
import { TriggerVerifyAccount } from '../components/AuthenticationFlow/TriggerVerifyAccount';
|
import { TriggerVerifyAccount } from '../components/AuthenticationFlow/TriggerVerifyAccount';
|
||||||
import SettingLayout from '../layouts/SettingLayout.astro';
|
import AccountLayout from '../layouts/AccountLayout.astro';
|
||||||
---
|
---
|
||||||
|
|
||||||
<SettingLayout title='Verify account' noIndex={true}>
|
<AccountLayout title='Verify account' noIndex={true}>
|
||||||
<div class='container py-16'>
|
<div class='container py-16'>
|
||||||
<TriggerVerifyAccount client:load />
|
<TriggerVerifyAccount client:load />
|
||||||
</div>
|
</div>
|
||||||
</SettingLayout>
|
</AccountLayout>
|
||||||
|
Reference in New Issue
Block a user