Refactor login button

pull/3813/head
Kamran Ahmed 2 years ago
parent 983476eb37
commit 6b4be3f0ab
  1. 1
      .env.example
  2. 6
      astro.config.mjs
  3. 2
      package.json
  4. 3
      src/components/AstroIcon.astro
  5. 2
      src/components/BestPracticeHeader.astro
  6. 2
      src/components/FAQs/Question.astro
  7. 2
      src/components/Footer.astro
  8. 2
      src/components/Loader.astro
  9. 8
      src/components/Login/GithubLogin.astro
  10. 2
      src/components/Login/GoogleLogin.astro
  11. 2
      src/components/Navigation/AccountDropdown.astro
  12. 2
      src/components/Navigation/Navigation.astro
  13. 2
      src/components/OpenSourceBanner.astro
  14. 2
      src/components/Popup/Popup.astro
  15. 2
      src/components/RoadmapHeader.astro
  16. 2
      src/components/RoadmapHint.astro
  17. 2
      src/components/Setting/SettingSidebar.astro
  18. 2
      src/components/ShareIcons/ShareIcons.astro
  19. 92
      src/components/SocialAuth/GitHubButton.tsx
  20. 2
      src/components/Sponsor/Sponsor.astro
  21. 2
      src/components/TopicOverlay/TopicOverlay.astro
  22. 2
      src/components/TopicSearch/TopicSearch.astro
  23. 2
      src/components/UpcomingForm.astro
  24. 2
      src/components/YouTubeBanner.astro
  25. 1
      src/env.d.ts
  26. 6
      src/icons/spinner.svg
  27. 2
      src/pages/404.astro
  28. 3
      src/pages/signup.astro
  29. 2
      src/pages/verify.astro

@ -0,0 +1 @@
PUBLIC_API_URL=http://api.roadmap.sh

@ -1,8 +1,8 @@
// https://astro.build/config // https://astro.build/config
import sitemap from '@astrojs/sitemap'; import sitemap from '@astrojs/sitemap';
import tailwind from '@astrojs/tailwind'; import tailwind from '@astrojs/tailwind';
import compress from 'astro-compress';
import { defineConfig } from 'astro/config'; import { defineConfig } from 'astro/config';
import compress from 'astro-compress';
import rehypeExternalLinks from 'rehype-external-links'; import rehypeExternalLinks from 'rehype-external-links';
import { serializeSitemap, shouldIndexPage } from './sitemap.mjs'; import { serializeSitemap, shouldIndexPage } from './sitemap.mjs';
import preact from '@astrojs/preact'; import preact from '@astrojs/preact';
@ -28,7 +28,7 @@ export default defineConfig({
'https://github.com/kamranahmedse', 'https://github.com/kamranahmedse',
'https://thenewstack.io', 'https://thenewstack.io',
'https://cs.fyi', 'https://cs.fyi',
'https://roadmap.sh' 'https://roadmap.sh',
]; ];
if (whiteListedStarts.some((start) => href.startsWith(start))) { if (whiteListedStarts.some((start) => href.startsWith(start))) {
@ -58,6 +58,6 @@ export default defineConfig({
css: false, css: false,
js: false, js: false,
}), }),
preact(), preact(),
], ],
}); });

@ -28,8 +28,8 @@
"jose": "^4.13.1", "jose": "^4.13.1",
"js-cookie": "^3.0.1", "js-cookie": "^3.0.1",
"node-html-parser": "^6.1.5", "node-html-parser": "^6.1.5",
"preact": "^10.13.2",
"npm-check-updates": "^16.10.7", "npm-check-updates": "^16.10.7",
"preact": "^10.13.2",
"rehype-external-links": "^2.0.1", "rehype-external-links": "^2.0.1",
"roadmap-renderer": "^1.0.4", "roadmap-renderer": "^1.0.4",
"tailwindcss": "^3.3.1" "tailwindcss": "^3.3.1"

@ -35,5 +35,4 @@ const { attributes: baseAttributes, innerHTML } = await getSVG(icon);
const svgAttributes = { ...baseAttributes, ...attributes }; const svgAttributes = { ...baseAttributes, ...attributes };
--- ---
<svg {...svgAttributes} set:html={innerHTML}></svg>
<svg {...svgAttributes} set:html={innerHTML}></svg>

@ -1,7 +1,7 @@
--- ---
import BestPracticeHint from './BestPracticeHint.astro'; import BestPracticeHint from './BestPracticeHint.astro';
import DownloadPopup from './DownloadPopup.astro'; import DownloadPopup from './DownloadPopup.astro';
import Icon from './Icon.astro'; import Icon from './AstroIcon.astro';
import LoginPopup from './Login/LoginPopup.astro'; import LoginPopup from './Login/LoginPopup.astro';
import SubscribePopup from './SubscribePopup.astro'; import SubscribePopup from './SubscribePopup.astro';

@ -1,5 +1,5 @@
--- ---
import Icon from '../Icon.astro'; import Icon from '../AstroIcon.astro';
export interface Props { export interface Props {
question: string; question: string;

@ -1,5 +1,5 @@
--- ---
import Icon from './Icon.astro'; import Icon from './AstroIcon.astro';
--- ---
<div class='py-6 sm:py-16 pb-10 bg-slate-900 text-white'> <div class='py-6 sm:py-16 pb-10 bg-slate-900 text-white'>

@ -1,5 +1,5 @@
--- ---
import Icon from './Icon.astro'; import Icon from './AstroIcon.astro';
--- ---
<div class='flex justify-center w-full'> <div class='flex justify-center w-full'>

@ -1,5 +1,5 @@
--- ---
import Icon from '../Icon.astro'; import Icon from '../AstroIcon.astro';
import Spinner from '../Spinner.astro'; import Spinner from '../Spinner.astro';
--- ---
@ -8,10 +8,10 @@ import Spinner from '../Spinner.astro';
id='github-login-button' id='github-login-button'
> >
<Spinner class='hidden text-black' id='github-login-spinner' /> <Spinner class='hidden text-black' id='github-login-spinner' />
<div class='flex items-center' data-github-text> <span class='flex items-center' data-github-text>
<Icon icon='github' /> <Icon icon='github' />
<span class='ml-2'>Continue with Github</span> <span class='ml-2'>Continue with Github</span>
</div> </span>
</button> </button>
<p class='hidden text-sm font-medium text-red-600' data-github-error></p> <p class='hidden text-sm font-medium text-red-600' data-github-error></p>
@ -49,7 +49,7 @@ import Spinner from '../Spinner.astro';
githubLoginButton?.addEventListener('click', () => { githubLoginButton?.addEventListener('click', () => {
addSpinner(); addSpinner();
fetch('http://localhost:8080/v1-github-login', { fetch(`${import.meta.env.PUBLIC_API_URL}/v1-github-login`, {
credentials: 'include', credentials: 'include',
}) })
.then((res) => { .then((res) => {

@ -1,5 +1,5 @@
--- ---
import Icon from '../Icon.astro'; import Icon from '../AstroIcon.astro';
import Spinner from '../Spinner.astro'; import Spinner from '../Spinner.astro';
--- ---

@ -1,5 +1,5 @@
--- ---
import Icon from '../Icon.astro'; import Icon from '../AstroIcon.astro';
--- ---
<div class='relative hidden' data-auth-required> <div class='relative hidden' data-auth-required>

@ -1,5 +1,5 @@
--- ---
import Icon from '../Icon.astro'; import Icon from '../AstroIcon.astro';
import AccountDropdown from './AccountDropdown.astro'; import AccountDropdown from './AccountDropdown.astro';
--- ---

@ -1,6 +1,6 @@
--- ---
import { getFormattedStars } from '../lib/github'; import { getFormattedStars } from '../lib/github';
import Icon from './Icon.astro'; import Icon from './AstroIcon.astro';
const starCount = await getFormattedStars('kamranahmedse/developer-roadmap'); const starCount = await getFormattedStars('kamranahmedse/developer-roadmap');
--- ---

@ -1,5 +1,5 @@
--- ---
import Icon from '../Icon.astro'; import Icon from '../AstroIcon.astro';
export interface Props { export interface Props {
id: string; id: string;

@ -1,6 +1,6 @@
--- ---
import DownloadPopup from './DownloadPopup.astro'; import DownloadPopup from './DownloadPopup.astro';
import Icon from './Icon.astro'; import Icon from './AstroIcon.astro';
import LoginPopup from './Login/LoginPopup.astro'; import LoginPopup from './Login/LoginPopup.astro';
import RoadmapHint from './RoadmapHint.astro'; import RoadmapHint from './RoadmapHint.astro';
import RoadmapNote from './RoadmapNote.astro'; import RoadmapNote from './RoadmapNote.astro';

@ -1,5 +1,5 @@
--- ---
import Icon from './Icon.astro'; import Icon from './AstroIcon.astro';
export interface Props { export interface Props {
roadmapId: string; roadmapId: string;

@ -1,5 +1,5 @@
--- ---
import Icon from '../Icon.astro'; import Icon from '../AstroIcon.astro';
const { pageUrl, name } = Astro.props; const { pageUrl, name } = Astro.props;
export interface Props { export interface Props {

@ -1,5 +1,5 @@
--- ---
import Icon from '../Icon.astro'; import Icon from '../AstroIcon.astro';
export interface Props { export interface Props {
pageUrl: string; pageUrl: string;

@ -0,0 +1,92 @@
import { useEffect, useState } from 'preact/hooks';
import GitHubIcon from '../../icons/github.svg';
import SpinnerIcon from '../../icons/spinner.svg';
import { TOKEN_COOKIE_NAME } from '../../lib/constants';
import Cookies from 'js-cookie';
type GitHubButtonProps = {};
export function GitHubButton(props: GitHubButtonProps) {
const [isLoading, setIsLoading] = useState(false);
const [error, setError] = useState('');
const icon = isLoading ? SpinnerIcon : GitHubIcon;
useEffect(() => {
const urlParams = new URLSearchParams(window.location.search);
const code = urlParams.get('code');
const state = urlParams.get('state');
const provider = urlParams.get('provider');
if (!code || !state || provider !== 'github') {
return;
}
setIsLoading(true);
fetch(
`${import.meta.env.PUBLIC_API_URL}/v1-github-callback${
window.location.search
}`,
{
method: 'GET',
credentials: 'include',
}
)
.then((res) => res.json())
.then((data: any) => {
if (!data.token) {
setError('Something went wrong. Please try again later.');
setIsLoading(false);
} else {
Cookies.set(TOKEN_COOKIE_NAME, data.token);
window.location.href = '/';
}
})
.catch((err) => {
setError('Something went wrong. Please try again later.');
setIsLoading(false);
});
}, []);
const handleClick = () => {
setIsLoading(true);
fetch(`${import.meta.env.PUBLIC_API_URL}/v1-github-login`, {
credentials: 'include',
redirect: 'follow',
})
.then((res) => res.json())
.then((data: any) => {
// @todo proper typing for API response
if (data.loginUrl) {
window.location.href = data.loginUrl;
} else {
setError('Something went wrong. Please try again later.');
setIsLoading(false);
}
})
.catch((err) => {
setError('Something went wrong. Please try again later.');
setIsLoading(false);
});
};
return (
<>
<button
class="inline-flex h-10 w-full items-center justify-center gap-2 rounded border border-slate-300 bg-white p-2 text-sm font-medium text-black outline-none transition duration-150 ease-in-out focus:ring-2 focus:ring-[#333] focus:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-60"
disabled={isLoading}
onClick={handleClick}
>
<img
src={icon}
alt="GitHub"
class={`h-[18px] w-[18px] ${isLoading ? 'animate-spin' : ''}`}
/>
Continue with GitHub
</button>
{error && (
<p className="mb-2 mt-1 text-sm font-medium text-red-600">{error}</p>
)}
</>
);
}

@ -1,6 +1,6 @@
--- ---
import type { GAEventType } from '../Analytics/analytics'; import type { GAEventType } from '../Analytics/analytics';
import Icon from '../Icon.astro'; import Icon from '../AstroIcon.astro';
export type SponsorType = { export type SponsorType = {
url: string; url: string;

@ -1,5 +1,5 @@
--- ---
import Icon from '../Icon.astro'; import Icon from '../AstroIcon.astro';
import Loader from '../Loader.astro'; import Loader from '../Loader.astro';
export interface Props { export interface Props {

@ -1,5 +1,5 @@
--- ---
import Icon from '../Icon.astro'; import Icon from '../AstroIcon.astro';
--- ---
<script src='./topics.js'></script> <script src='./topics.js'></script>

@ -1,6 +1,6 @@
--- ---
import CaptchaFields from './Captcha/CaptchaFields.astro'; import CaptchaFields from './Captcha/CaptchaFields.astro';
import Icon from './Icon.astro'; import Icon from './AstroIcon.astro';
--- ---
<div class='my-0 px-5 rounded-lg text-left sm:text-center sm:pb-10 pb-8'> <div class='my-0 px-5 rounded-lg text-left sm:text-center sm:pb-10 pb-8'>

@ -1,5 +1,5 @@
--- ---
import Icon from './Icon.astro'; import Icon from './AstroIcon.astro';
--- ---
<!-- sticky top-0 --> <!-- sticky top-0 -->

1
src/env.d.ts vendored

@ -2,6 +2,7 @@
interface ImportMetaEnv { interface ImportMetaEnv {
GITHUB_SHA: string; GITHUB_SHA: string;
PUBLIC_API_URL: string;
} }
interface ImportMeta { interface ImportMeta {

@ -1,4 +1,4 @@
<svg class='h-6 w-6 sm:w-12 sm:h-12 text-gray-200 animate-spin fill-blue-600' viewBox="0 0 93 93" fill="none" xmlns="http://www.w3.org/2000/svg"> <svg class='h-6 w-6 sm:w-12 sm:h-12 text-gray-200 animate-spin fill-blue-600' viewBox="0 0 93 93" fill="none" xmlns="http://www.w3.org/2000/svg">
<path fill-rule="evenodd" clip-rule="evenodd" d="M46.5 93C72.1812 93 93 72.1812 93 46.5C93 20.8188 72.1812 0 46.5 0C20.8188 0 0 20.8188 0 46.5C0 72.1812 20.8188 93 46.5 93ZM46.5 77C63.3447 77 77 63.3447 77 46.5C77 29.6553 63.3447 16 46.5 16C29.6553 16 16 29.6553 16 46.5C16 63.3447 29.6553 77 46.5 77Z" fill="currentColor"/> <path fill-rule="evenodd" clip-rule="evenodd" d="M46.5 93C72.1812 93 93 72.1812 93 46.5C93 20.8188 72.1812 0 46.5 0C20.8188 0 0 20.8188 0 46.5C0 72.1812 20.8188 93 46.5 93ZM46.5 77C63.3447 77 77 63.3447 77 46.5C77 29.6553 63.3447 16 46.5 16C29.6553 16 16 29.6553 16 46.5C16 63.3447 29.6553 77 46.5 77Z" fill="#e5e7eb"/>
<path d="M84.9746 49.5667C89.3257 49.9135 93.2042 46.6479 92.81 42.3008C92.3588 37.3251 91.1071 32.437 89.0872 27.8298C86.0053 20.7998 81.2311 14.6422 75.1905 9.90623C69.15 5.17027 62.031 2.00329 54.4687 0.687889C49.5126 -0.174203 44.467 -0.223422 39.5274 0.525737C35.2118 1.18024 32.966 5.72596 34.3411 9.86865V9.86865C35.7161 14.0113 40.2118 16.1424 44.5681 15.8677C46.9635 15.7166 49.3773 15.8465 51.7599 16.2609C56.7515 17.1291 61.4505 19.2196 65.4377 22.3456C69.4249 25.4717 72.5762 29.5362 74.6105 34.1764C75.5815 36.3912 76.2835 38.7044 76.7084 41.0666C77.4811 45.3626 80.6234 49.2199 84.9746 49.5667V49.5667Z" fill="currentFill"/> <path d="M84.9746 49.5667C89.3257 49.9135 93.2042 46.6479 92.81 42.3008C92.3588 37.3251 91.1071 32.437 89.0872 27.8298C86.0053 20.7998 81.2311 14.6422 75.1905 9.90623C69.15 5.17027 62.031 2.00329 54.4687 0.687889C49.5126 -0.174203 44.467 -0.223422 39.5274 0.525737C35.2118 1.18024 32.966 5.72596 34.3411 9.86865V9.86865C35.7161 14.0113 40.2118 16.1424 44.5681 15.8677C46.9635 15.7166 49.3773 15.8465 51.7599 16.2609C56.7515 17.1291 61.4505 19.2196 65.4377 22.3456C69.4249 25.4717 72.5762 29.5362 74.6105 34.1764C75.5815 36.3912 76.2835 38.7044 76.7084 41.0666C77.4811 45.3626 80.6234 49.2199 84.9746 49.5667V49.5667Z" fill="#2463eb" />
</svg> </svg>

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

@ -1,5 +1,5 @@
--- ---
import Icon from '../components/Icon.astro'; import Icon from '../components/AstroIcon.astro';
import BaseLayout from '../layouts/BaseLayout.astro'; import BaseLayout from '../layouts/BaseLayout.astro';
import { getRoadmapIds } from '../lib/roadmap'; import { getRoadmapIds } from '../lib/roadmap';

@ -6,6 +6,7 @@ import GithubLogin from '../components/Login/GithubLogin.astro';
import GoogleLogin from '../components/Login/GoogleLogin.astro'; import GoogleLogin from '../components/Login/GoogleLogin.astro';
import EmailSignupForm from '../components/Login/EmailSignupForm'; import EmailSignupForm from '../components/Login/EmailSignupForm';
import BaseLayout from '../layouts/BaseLayout.astro'; import BaseLayout from '../layouts/BaseLayout.astro';
import { GitHubButton } from '../components/SocialAuth/GitHubButton';
--- ---
<BaseLayout <BaseLayout
@ -31,7 +32,7 @@ import BaseLayout from '../layouts/BaseLayout.astro';
</div> </div>
<div class='flex w-full flex-col items-stretch space-y-2'> <div class='flex w-full flex-col items-stretch space-y-2'>
<GithubLogin /> <GitHubButton client:load />
<GoogleLogin /> <GoogleLogin />
</div> </div>

@ -1,5 +1,5 @@
--- ---
import Icon from '../components/Icon.astro'; import Icon from '../components/AstroIcon.astro';
import SettingLayout from '../layouts/SettingLayout.astro'; import SettingLayout from '../layouts/SettingLayout.astro';
--- ---

Loading…
Cancel
Save