dropdown menu on user profile

This commit is contained in:
slawk0
2024-10-19 17:53:34 +02:00
parent f20b020549
commit dfd065adee
7 changed files with 76 additions and 35 deletions

View File

@@ -1 +1 @@
{} { "singleQuote": true}

View File

@@ -18,6 +18,7 @@
</head> </head>
<body> <body>
<div id="root"></div> <div id="root"></div>
<script type="module" src="/src/main.tsx"></script> <script type="module" src="./src/main.tsx"></script>
<script src="./node_modules/preline/dist/preline.js"></script>
</body> </body>
</html> </html>

View File

@@ -13,6 +13,7 @@
"@types/socket.io-client": "^1.4.36", "@types/socket.io-client": "^1.4.36",
"axios": "^1.7.7", "axios": "^1.7.7",
"js-cookie": "^3.0.5", "js-cookie": "^3.0.5",
"preline": "^2.5.1",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-hook-form": "^7.53.0", "react-hook-form": "^7.53.0",
@@ -1065,6 +1066,16 @@
"node": ">=14" "node": ">=14"
} }
}, },
"node_modules/@popperjs/core": {
"version": "2.11.8",
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
"license": "MIT",
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/popperjs"
}
},
"node_modules/@remix-run/router": { "node_modules/@remix-run/router": {
"version": "1.19.2", "version": "1.19.2",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.2.tgz", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.19.2.tgz",
@@ -3575,6 +3586,15 @@
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==", "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/preline": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/preline/-/preline-2.5.1.tgz",
"integrity": "sha512-fEXOsz0xLfTm5sJmNanourrMjwjcgGtaVNg8Pt6GzUbZ/oXHIdcR94LBdeE0Ea0pBPFOOHzEL5LQwSbAvCJEfw==",
"license": "Licensed under MIT and Preline UI Fair Use License",
"dependencies": {
"@popperjs/core": "^2.11.2"
}
},
"node_modules/prelude-ls": { "node_modules/prelude-ls": {
"version": "1.2.1", "version": "1.2.1",
"resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz",

View File

@@ -15,6 +15,7 @@
"@types/socket.io-client": "^1.4.36", "@types/socket.io-client": "^1.4.36",
"axios": "^1.7.7", "axios": "^1.7.7",
"js-cookie": "^3.0.5", "js-cookie": "^3.0.5",
"preline": "^2.5.1",
"react": "^18.3.1", "react": "^18.3.1",
"react-dom": "^18.3.1", "react-dom": "^18.3.1",
"react-hook-form": "^7.53.0", "react-hook-form": "^7.53.0",

View File

@@ -1,6 +1,6 @@
import { useForm, SubmitHandler } from "react-hook-form"; import { useForm, SubmitHandler } from 'react-hook-form';
import { sendContact, sendRequestHistorical } from "../../socket/socket.tsx"; import { sendContact, sendRequestHistorical } from '../../socket/socket.tsx';
import { Dispatch, SetStateAction, useEffect } from "react"; import { Dispatch, SetStateAction, useEffect } from 'react';
type Input = { type Input = {
contact: string; contact: string;
@@ -21,9 +21,9 @@ interface ContactInputProps {
function ContactForm({ contact, setContact, setMessages }: ContactInputProps) { function ContactForm({ contact, setContact, setMessages }: ContactInputProps) {
const { register, handleSubmit, reset } = useForm<Input>(); const { register, handleSubmit, reset } = useForm<Input>();
let storedContact: string | null = ""; let storedContact: string | null = '';
useEffect(() => { useEffect(() => {
storedContact = storedContact = localStorage.getItem("contact"); storedContact = storedContact = localStorage.getItem('contact');
if (storedContact) { if (storedContact) {
setContact(storedContact); setContact(storedContact);
sendRequestHistorical(storedContact); sendRequestHistorical(storedContact);
@@ -33,11 +33,11 @@ function ContactForm({ contact, setContact, setMessages }: ContactInputProps) {
const submitContact: SubmitHandler<Input> = (data) => { const submitContact: SubmitHandler<Input> = (data) => {
setMessages([]); setMessages([]);
sendRequestHistorical(data.contact); sendRequestHistorical(data.contact);
localStorage.setItem("contact", data.contact); localStorage.setItem('contact', data.contact);
setContact(data.contact); setContact(data.contact);
sendContact(data.contact); //TODO zapisz w bazie danych te kontakty sendContact(data.contact); //TODO zapisz w bazie danych te kontakty
console.log("Contact submitted:", data.contact); console.log('Contact submitted:', data.contact);
reset({ contact: "" }); reset({ contact: '' });
}; };
return ( return (
@@ -45,11 +45,11 @@ function ContactForm({ contact, setContact, setMessages }: ContactInputProps) {
<div className="text-center"> <div className="text-center">
<form onSubmit={handleSubmit(submitContact)}> <form onSubmit={handleSubmit(submitContact)}>
<input <input
className="text-black bg-green-100 pl-2 shadow-lg rounded-md h-8 mb-2 mt-2" className="text-black bg-green-50 pl-2 shadow-lg rounded-md h-8 mb-2 mt-2"
type="text" type="text"
autoFocus={!!contact} autoFocus={!!contact}
placeholder="Enter contact" placeholder="Enter contact"
{...register("contact", { {...register('contact', {
// valid username length (validated on signup) // valid username length (validated on signup)
minLength: 4, minLength: 4,
maxLength: 20, maxLength: 20,

View File

@@ -1,34 +1,49 @@
import zdjecie from "../../../assets/walter.png"; import zdjecie from '../../../assets/walter.png';
import Cookies from "js-cookie"; import logoutIcon from '../../../assets/logout.svg';
import { useOutletContext } from "react-router-dom"; import Cookies from 'js-cookie';
import { UsernameType } from "../../utils/ProtectedRoutes.tsx"; import { useOutletContext } from 'react-router-dom';
import { UsernameType } from '../../utils/ProtectedRoutes.tsx';
function UserProfile() { function UserProfile() {
const { username }: UsernameType = useOutletContext(); const { username }: UsernameType = useOutletContext();
return ( return (
<> <>
<div className="flex items-center"> <div className="flex items-center">
<div className="m-3 rounded-full w-12 h-12 overflow-hidden "> <div className="hs-dropdown relative inline-flex">
<img <div className="m-3 rounded-full w-12 h-12 overflow-hidden hs-dropdown-toggle cursor-pointer">
className="w-full h-full object-cover" <img
src={zdjecie} className="w-full h-full object-cover"
alt="user profile" src={zdjecie}
draggable={false} alt="user profile"
/> draggable={false}
aria-haspopup="menu"
aria-expanded="false"
/>
</div>
<div
className="hs-dropdown-menu transition-[opacity,margin] duration-100 hs-dropdown-open:opacity-100 opacity-0 hidden min-w-60 bg-green-50 shadow-md rounded-md mt-2 after:h-4 after:absolute after:-bottom-4 after:start-0 after:w-full before:h-4 before:absolute before:-top-4 before:start-0 before:w-full"
role="menu"
aria-orientation="vertical"
>
<div className="p-1 space-y-0.5 flex">
<a
className="flex items-center gap-x-3.5 py-2 px-3 rounded-md text-sm text-black hover:bg-gray-100 focus:outline-none focus:bg-gray-100"
onClick={() => {
Cookies.remove('token');
window.location.reload();
}}
>
Log out
</a>
<img className="w-5" src={logoutIcon} alt="Logout" />
</div>
</div>
</div> </div>
<div className="text-center text-gray-200"> <div className="text-center text-gray-200">
<p>{username}</p> <p>{username}</p>
</div> </div>
</div> </div>
<div>
<button
onClick={() => {
Cookies.remove("token");
window.location.reload();
}}
>
remove cookies
</button>
</div>
</> </>
); );
} }

View File

@@ -1,8 +1,12 @@
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
export default { export default {
content: ["./index.html", "./src/**/*.{js,ts,jsx,tsx}"], content: [
"./index.html",
"./src/**/*.{js,ts,jsx,tsx}",
"node_modules/preline/dist/*.js",
],
theme: { theme: {
extend: {}, extend: {},
}, },
plugins: [require("@tailwindcss/forms")], plugins: [require("@tailwindcss/forms"), require("preline/plugin")],
}; };