chore: update profile form

pull/3813/head
Arik Chakma 2 years ago
parent 9a145cb785
commit ecb9de8a40
  1. 53
      src/components/Setting/ChangePassword.astro
  2. 3
      src/components/Setting/ChangePasswordForm.tsx
  3. 83
      src/components/Setting/UpdateProfile.astro
  4. 92
      src/components/Setting/UpdateProfileForm.tsx
  5. 4
      src/pages/settings/profile.astro

@ -1,53 +0,0 @@
<form>
<h2 class='text-3xl font-bold sm:text-4xl'>Password</h2>
<p class='mt-2'>Manage settings for your account passwords</p>
<div class='mt-8 space-y-4'>
<div class='flex w-full flex-col'>
<label for='current-password' class='text-sm leading-none text-slate-500'
>Current Password</label
>
<input
type='password'
name='current-password'
id='current-password'
class='mt-2 block w-full appearance-none rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1'
required
placeholder='Current password'
/>
</div>
<div class='flex w-full flex-col'>
<label for='new-password' class='text-sm leading-none text-slate-500'
>New Password</label
>
<input
type='password'
name='new-password'
id='new-password'
class='mt-2 block w-full appearance-none rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1'
required
placeholder='New password'
/>
</div>
<div class='flex w-full flex-col'>
<label
for='new-password-confirmation'
class='text-sm leading-none text-slate-500'>New Password Confirm</label
>
<input
type='password'
name='new-password-confirmation'
id='new-password-confirmation'
class='mt-2 block w-full appearance-none rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1'
required
placeholder='New password confirm'
/>
</div>
<button
class='!mt-5 inline-flex h-10 items-center justify-center rounded-lg border border-slate-300 bg-black p-2 px-4 text-sm font-medium text-white outline-none transition duration-150 ease-in-out focus:ring-2 focus:ring-black focus:ring-offset-1 disabled:opacity-60'
type='button'
>
Change
</button>
</div>
</form>

@ -143,8 +143,9 @@ export default function ChangePasswordForm() {
)}
<button
className="!mt-5 inline-flex h-10 min-w-[120px] items-center justify-center rounded-lg border border-slate-300 bg-black p-2 px-4 text-sm font-medium text-white outline-none transition duration-150 ease-in-out focus:ring-2 focus:ring-black focus:ring-offset-1 disabled:opacity-60"
className="!mt-5 inline-flex h-10 min-w-[120px] items-center justify-center rounded-lg border border-slate-300 bg-black p-2 px-4 text-sm font-medium text-white outline-none transition duration-150 ease-in-out focus:ring-2 focus:ring-black focus:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-60"
type="submit"
disabled={isLoading}
>
{isLoading ? (
<svg

@ -1,83 +0,0 @@
<form>
<h2 class='text-3xl font-bold sm:text-4xl'>Update Profile</h2>
<p class='mt-2'>Manage settings for your roadmap.sh profile</p>
<div class='mt-8 space-y-4'>
<div class='flex w-full flex-col'>
<label
for='name'
class='text-sm leading-none text-slate-500 after:text-red-400 after:content-["*"]'
>Name</label
>
<input
type='text'
name='name'
id='name'
class='mt-2 block w-full appearance-none rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1'
required
placeholder='Arik Chakma'
/>
</div>
<div class='flex w-full flex-col'>
<label
for='email'
class='text-sm leading-none text-slate-500 after:text-red-400 after:content-["*"]'
>Email</label
>
<input
type='email'
name='email'
id='email'
class='mt-2 block w-full appearance-none rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1'
required
placeholder='arik@roadmap.sh'
/>
</div>
<!-- Github -->
<div class='flex w-full flex-col'>
<label for='github' class='text-sm leading-none text-slate-500'
>Github Username</label
>
<input
type='text'
name='github'
id='github'
class='mt-2 block w-full appearance-none rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1'
placeholder='arikchakma'
/>
</div>
<!-- LinkedIn -->
<div class='flex w-full flex-col'>
<label for='linkedin' class='text-sm leading-none text-slate-500'
>LinkedIn Url</label
>
<input
type='text'
name='linkedin'
id='linkedin'
class='mt-2 block w-full appearance-none rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1'
placeholder='https://www.linkedin.com/in/arikchakma/'
/>
</div>
<!-- Website -->
<div class='flex w-full flex-col'>
<label for='website' class='text-sm leading-none text-slate-500'
>Website</label
>
<input
type='text'
name='website'
id='website'
class='mt-2 block w-full appearance-none rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1'
placeholder='https://arikko.dev'
/>
</div>
<button
class='!mt-5 inline-flex h-10 items-center justify-center rounded-lg border border-slate-300 bg-black p-2 px-4 text-sm font-medium text-white outline-none transition duration-150 ease-in-out focus:ring-2 focus:ring-black focus:ring-offset-1 disabled:opacity-60'
type='button'
>
Update
</button>
</div>
</form>

@ -1,4 +1,6 @@
import { useState } from 'preact/hooks';
import { TOKEN_COOKIE_NAME } from '../../lib/utils';
import Cookies from 'js-cookie';
export default function UpdateProfileForm() {
const [name, setName] = useState('');
@ -13,23 +15,49 @@ export default function UpdateProfileForm() {
e.preventDefault();
setIsLoading(true);
const headers = new Headers();
headers.append('Content-Type', 'application/json');
headers.append(
'Cookie',
`${TOKEN_COOKIE_NAME}=${Cookies.get(TOKEN_COOKIE_NAME)}`
);
fetch('http://localhost:8080/v1-update-profile', {
method: 'POST',
credentials: 'include',
headers: {
'Content-Type': 'application/json',
},
headers,
body: JSON.stringify({
name,
github,
linkedin,
website,
}),
});
})
.then(async (res) => {
const json = await res.json();
if (res.ok) {
return json;
} else {
throw new Error(json.message);
}
})
.then((data) => {
setIsLoading(false);
setName('');
setGithub('');
setLinkedin('');
setWebsite('');
setError('');
setSuccessMessage('Profile updated successfully');
})
.catch((err) => {
setIsLoading(false);
setError(err.message);
});
};
return (
<form>
<form onSubmit={handleSubmit}>
<h2 className="text-3xl font-bold sm:text-4xl">Update Profile</h2>
<p className="mt-2">Manage settings for your roadmap.sh profile</p>
<div className="mt-8 space-y-4">
@ -47,6 +75,8 @@ export default function UpdateProfileForm() {
className="mt-2 block w-full appearance-none rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
required
placeholder="Arik Chakma"
value={name}
onChange={(e) => setName((e.target as HTMLInputElement).value)}
/>
</div>
<div className="flex w-full flex-col">
@ -69,19 +99,21 @@ export default function UpdateProfileForm() {
<div className="flex w-full flex-col">
<label for="github" className="text-sm leading-none text-slate-500">
Github Username
Github
</label>
<input
type="text"
name="github"
id="github"
className="mt-2 block w-full appearance-none rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
placeholder="arikchakma"
placeholder="https://github.com/arikchakma"
value={github}
onChange={(e) => setGithub((e.target as HTMLInputElement).value)}
/>
</div>
<div className="flex w-full flex-col">
<label for="linkedin" className="text-sm leading-none text-slate-500">
LinkedIn Url
LinkedIn
</label>
<input
type="text"
@ -89,6 +121,8 @@ export default function UpdateProfileForm() {
id="linkedin"
className="mt-2 block w-full appearance-none rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
placeholder="https://www.linkedin.com/in/arikchakma/"
value={linkedin}
onChange={(e) => setLinkedin((e.target as HTMLInputElement).value)}
/>
</div>
@ -102,14 +136,50 @@ export default function UpdateProfileForm() {
id="website"
className="mt-2 block w-full appearance-none rounded-lg border border-gray-300 px-3 py-2 shadow-sm outline-none transition duration-150 ease-in-out placeholder:text-gray-400 focus:ring-2 focus:ring-black focus:ring-offset-1"
placeholder="https://arikko.dev"
value={website}
onChange={(e) => setWebsite((e.target as HTMLInputElement).value)}
/>
</div>
{error && (
<div className="text-sm font-medium text-red-500">
<span className="text-red-500">{error}</span>
</div>
)}
{successMessage && (
<div className="text-sm font-medium text-green-500">
<span className="text-green-500">{successMessage}</span>
</div>
)}
<button
className="!mt-5 inline-flex h-10 items-center justify-center rounded-lg border border-slate-300 bg-black p-2 px-4 text-sm font-medium text-white outline-none transition duration-150 ease-in-out focus:ring-2 focus:ring-black focus:ring-offset-1 disabled:opacity-60"
type="button"
className="!mt-5 inline-flex h-10 min-w-[120px] items-center justify-center rounded-lg border border-slate-300 bg-black p-2 px-4 text-sm font-medium text-white outline-none transition duration-150 ease-in-out focus:ring-2 focus:ring-black focus:ring-offset-1 disabled:cursor-not-allowed disabled:opacity-60"
type="submit"
disabled={isLoading}
>
Update
{isLoading ? (
<svg
class={`h-5 w-5 animate-spin text-white`}
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
>
<circle
class="stroke-[4px] opacity-25"
cx="12"
cy="12"
r="10"
stroke="currentColor"
></circle>
<path
class="opacity-75"
fill="currentColor"
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
></path>
</svg>
) : (
'Update'
)}
</button>
</div>
</form>

@ -1,11 +1,11 @@
---
import SettingSidebar from '../../components/Setting/SettingSidebar.astro';
import UpdateProfile from '../../components/Setting/UpdateProfile.astro';
import UpdateProfileForm from '../../components/Setting/UpdateProfileForm';
import SettingLayout from '../../layouts/SettingLayout.astro';
---
<SettingLayout title='Update Profile'>
<SettingSidebar pageUrl='profile' name='Profile'>
<UpdateProfile />
<UpdateProfileForm client:load />
</SettingSidebar>
</SettingLayout>

Loading…
Cancel
Save