diff --git a/back/src/auth/auth.service.ts b/back/src/auth/auth.service.ts
index 43567e8..16ee860 100644
--- a/back/src/auth/auth.service.ts
+++ b/back/src/auth/auth.service.ts
@@ -25,6 +25,7 @@ export class AuthService {
sub: user.id,
username: user.username,
roles: user.roles,
+ picture: user.picture,
};
return { access_token: await this.jwtService.signAsync(payload) };
diff --git a/back/src/users/entities/user.entity.ts b/back/src/users/entities/user.entity.ts
index 2dd3592..41ab670 100644
--- a/back/src/users/entities/user.entity.ts
+++ b/back/src/users/entities/user.entity.ts
@@ -16,4 +16,7 @@ export class User {
@Column()
roles: string;
+
+ @Column()
+ picture: string;
}
diff --git a/back/src/users/roles/role.enum.ts b/back/src/users/roles/role.enum.ts
index f62dd38..91c2ed3 100644
--- a/back/src/users/roles/role.enum.ts
+++ b/back/src/users/roles/role.enum.ts
@@ -1,5 +1,6 @@
export enum Role {
Public = 'public',
User = 'user',
+ Manager = 'manager',
Admin = 'admin',
}
diff --git a/back/src/users/users.service.ts b/back/src/users/users.service.ts
index a3c4ca8..8340765 100644
--- a/back/src/users/users.service.ts
+++ b/back/src/users/users.service.ts
@@ -9,6 +9,7 @@ export type UserType = {
username: string;
password: string;
roles: Role[];
+ picture: string;
};
@Injectable()
@@ -29,6 +30,7 @@ export class UsersService {
username: db_user.username,
password: db_user.password,
roles: db_user.roles.split(';') as Role[],
+ picture: db_user.picture,
};
console.log(user);
return user;
diff --git a/docker-compose.yml b/docker-compose.yml
index a40474e..d686910 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -1,4 +1,4 @@
-version: "1.1"
+version: "1.2"
services:
mysql:
diff --git a/front/.env b/front/.env
index d7e5fe9..75ef813 100644
--- a/front/.env
+++ b/front/.env
@@ -1,3 +1,6 @@
-NEXTAUTH_URL=http://localhost:3016
+NEXT_PUBLIC_URL=http://localhost:3016
+NEXT_PUBLIC_API_URL=http://localhost:3016
+
# GEN AUTH_SECRET: $ openssl rand -base64 32
NEXTAUTH_SECRET=6lHRWUvCBtqlgTWc6aFn6s6PudYjuN6oUY+RrcEntTU=
+NEXTAUTH_URL=http://localhost:3016
diff --git a/front/src/app/(home)/page.tsx b/front/src/app/(home)/page.tsx
index 7f16d18..0f918c7 100644
--- a/front/src/app/(home)/page.tsx
+++ b/front/src/app/(home)/page.tsx
@@ -1,5 +1,3 @@
-import ThemeSwitcher from "@/modules/common/theme-switcher";
-
export default function Home() {
return (
Main page
-
);
}
diff --git a/front/src/modules/auth/components/log-in/log-in.module.scss b/front/src/modules/auth/components/log-in/log-in.module.scss
index 27fd6af..95be06c 100644
--- a/front/src/modules/auth/components/log-in/log-in.module.scss
+++ b/front/src/modules/auth/components/log-in/log-in.module.scss
@@ -12,8 +12,8 @@
border-radius: 0.4rem;
background-image: linear-gradient(
16deg,
- rgba($color-primary-light-rgb, 0.3),
- rgba($color-primary-light-rgb, 0.2)
+ rgba($color-primary-90-rgb, 0.3),
+ rgba($color-primary-90-rgb, 0.2)
);
.heading {
@@ -21,7 +21,7 @@
text-align: center;
background-color: #e5e5f7;
opacity: 0.8;
- text-shadow: rgba($color-grey-dark, 0.3);
+ text-shadow: rgba($color-grey-10, 0.3);
padding: 2rem 4rem 2rem;
@@ -35,8 +35,8 @@
calc(0.5 * var(--s)) calc(0.5 * var(--s) * 0.577),
repeating-conic-gradient(
from 30deg,
- $color-grey-medium 0 60deg,
- $color-grey-light 0 120deg,
+ $color-grey-30 0 60deg,
+ $color-grey-90 0 120deg,
$color-white 0 180deg
);
background-size: var(--s) calc(var(--s) * 0.577);
@@ -61,7 +61,7 @@
font-size: inherit;
margin-left: 0.8em;
- color: $color-grey-dark;
+ color: $color-grey-10;
transition: all 0.3s;
}
@@ -71,7 +71,7 @@
color: $color-foreground;
- background: rgba($color-primary-light-rgb, 0.5);
+ background: rgba($color-primary-90-rgb, 0.5);
border: none;
border-bottom: 2px solid transparent;
border-radius: 2px;
@@ -79,7 +79,7 @@
transition: all 0.2s;
&::placeholder {
- color: $color-grey-dark;
+ color: $color-grey-10;
}
&:focus {
diff --git a/front/src/modules/auth/components/sign-in-button/index.ts b/front/src/modules/auth/components/sign-in-button/index.ts
new file mode 100644
index 0000000..005ef10
--- /dev/null
+++ b/front/src/modules/auth/components/sign-in-button/index.ts
@@ -0,0 +1,3 @@
+"use client";
+
+export { SignInButton as default } from "./sign-in-button.component";
diff --git a/front/src/modules/auth/components/sign-in-button/sign-in-button.component.tsx b/front/src/modules/auth/components/sign-in-button/sign-in-button.component.tsx
new file mode 100644
index 0000000..ffc1f3b
--- /dev/null
+++ b/front/src/modules/auth/components/sign-in-button/sign-in-button.component.tsx
@@ -0,0 +1,10 @@
+import { signIn } from "next-auth/react";
+import styles from "./sign-in-button.module.scss";
+
+export const SignInButton = () => {
+ return (
+
+ );
+};
diff --git a/front/src/modules/auth/components/sign-in-button/sign-in-button.module.scss b/front/src/modules/auth/components/sign-in-button/sign-in-button.module.scss
new file mode 100644
index 0000000..f54e640
--- /dev/null
+++ b/front/src/modules/auth/components/sign-in-button/sign-in-button.module.scss
@@ -0,0 +1,2 @@
+.button {
+}
diff --git a/front/src/modules/auth/components/sign-out-button/index.ts b/front/src/modules/auth/components/sign-out-button/index.ts
new file mode 100644
index 0000000..504616a
--- /dev/null
+++ b/front/src/modules/auth/components/sign-out-button/index.ts
@@ -0,0 +1,3 @@
+"use client";
+
+export { SignOutButton as default } from "./sign-out-button.component";
diff --git a/front/src/modules/auth/components/sign-out-button/sign-out-button.component.tsx b/front/src/modules/auth/components/sign-out-button/sign-out-button.component.tsx
new file mode 100644
index 0000000..103cc0a
--- /dev/null
+++ b/front/src/modules/auth/components/sign-out-button/sign-out-button.component.tsx
@@ -0,0 +1,10 @@
+import { signOut } from "next-auth/react";
+import styles from "./sign-out-button.module.scss";
+
+export const SignOutButton = () => {
+ return (
+
+ );
+};
diff --git a/front/src/modules/auth/components/sign-out-button/sign-out-button.module.scss b/front/src/modules/auth/components/sign-out-button/sign-out-button.module.scss
new file mode 100644
index 0000000..f54e640
--- /dev/null
+++ b/front/src/modules/auth/components/sign-out-button/sign-out-button.module.scss
@@ -0,0 +1,2 @@
+.button {
+}
diff --git a/front/src/modules/auth/components/user-dropdown/index.ts b/front/src/modules/auth/components/user-dropdown/index.ts
index b255352..1114380 100644
--- a/front/src/modules/auth/components/user-dropdown/index.ts
+++ b/front/src/modules/auth/components/user-dropdown/index.ts
@@ -1 +1 @@
-export { UserDropdown } from "./user-dropdown.component";
+export { UserDropdown as default } from "./user-dropdown.component";
diff --git a/front/src/modules/auth/components/user-dropdown/user-dropdown.component.tsx b/front/src/modules/auth/components/user-dropdown/user-dropdown.component.tsx
index 98e5334..802ffab 100644
--- a/front/src/modules/auth/components/user-dropdown/user-dropdown.component.tsx
+++ b/front/src/modules/auth/components/user-dropdown/user-dropdown.component.tsx
@@ -1,14 +1,16 @@
-import { UserFrame } from "../user-frame";
import styles from "./user-dropdown.module.scss";
+import UserPanel from "../user-panel";
+import { UserFrame } from "../user-frame";
-export const UserDropdown = () => {
+export const UserDropdown = async () => {
return (
);
};
diff --git a/front/src/modules/auth/components/user-dropdown/user-dropdown.module.scss b/front/src/modules/auth/components/user-dropdown/user-dropdown.module.scss
index 20b6c83..772baae 100644
--- a/front/src/modules/auth/components/user-dropdown/user-dropdown.module.scss
+++ b/front/src/modules/auth/components/user-dropdown/user-dropdown.module.scss
@@ -1,8 +1,27 @@
.container {
+ position: relative;
+ overflow: visible;
+
.avatar__container {
width: 6rem;
height: 6rem;
- font-size: 3rem;
+ font-size: 3.4rem;
+ padding: 0.5rem;
+ }
+
+ .dropdown__container {
+ position: absolute;
+ right: 0;
+
+ opacity: 0;
+ visibility: hidden;
+
+ transition: all 0.2s;
+ }
+
+ &:hover > .dropdown__container {
+ opacity: 1;
+ visibility: visible;
}
}
diff --git a/front/src/modules/auth/components/user-frame/user-frame.component.tsx b/front/src/modules/auth/components/user-frame/user-frame.component.tsx
index 963a107..b2e9ad8 100644
--- a/front/src/modules/auth/components/user-frame/user-frame.component.tsx
+++ b/front/src/modules/auth/components/user-frame/user-frame.component.tsx
@@ -1,16 +1,20 @@
-import { getServerSession } from "next-auth/next";
-import { authOptions } from "../../configs/auth.options";
import Image from "next/image";
import styles from "./user-frame.module.scss";
+import { getServerSession } from "next-auth";
+import SignInButton from "../sign-in-button";
export async function UserFrame() {
- const session = await getServerSession(authOptions);
+ const session = await getServerSession();
+
+ if (!session) {
+ return ;
+ }
return (
- {getInitialsFromName(session?.user?.name || "")}
+ {getInitialsFromName(session?.user?.name || "00")}
span {
@@ -18,6 +18,6 @@
font-size: inherit;
text-transform: uppercase;
- color: $color-grey-medium;
+ color: $color-grey-30;
}
}
diff --git a/front/src/modules/auth/components/user-panel/index.ts b/front/src/modules/auth/components/user-panel/index.ts
new file mode 100644
index 0000000..2af2a2e
--- /dev/null
+++ b/front/src/modules/auth/components/user-panel/index.ts
@@ -0,0 +1,3 @@
+"use client";
+
+export { UserPanel as default } from "./user-panel.component";
diff --git a/front/src/modules/auth/components/user-panel/user-panel.component.tsx b/front/src/modules/auth/components/user-panel/user-panel.component.tsx
new file mode 100644
index 0000000..7f8d06f
--- /dev/null
+++ b/front/src/modules/auth/components/user-panel/user-panel.component.tsx
@@ -0,0 +1,21 @@
+import styles from "./user-panel.module.scss";
+import SignOutButton from "../sign-out-button";
+import { useSession } from "next-auth/react";
+import ThemeSwitcher from "@/modules/common/components/theme-switcher";
+
+export function UserPanel() {
+ const session = useSession();
+
+ return (
+
+ - {session.data?.user?.name}
+
+ {session.data?.user?.roles.map((role) => (
+ - {role}
+ ))}
+
+
+
+
+ );
+}
diff --git a/front/src/modules/auth/components/user-panel/user-panel.module.scss b/front/src/modules/auth/components/user-panel/user-panel.module.scss
new file mode 100644
index 0000000..045ef8b
--- /dev/null
+++ b/front/src/modules/auth/components/user-panel/user-panel.module.scss
@@ -0,0 +1,36 @@
+.frame {
+ list-style: none;
+ min-width: 15rem;
+ display: flex;
+ flex-direction: column;
+ gap: 1.8rem 0.6rem;
+
+ padding: 1.2rem 1.8rem;
+
+ border-radius: 6px;
+ background-color: $color-foreground;
+ color: $color-background;
+
+ & .user {
+ font-size: 1.6rem;
+
+ &__name {
+ }
+
+ &__roles {
+ list-style: none;
+
+ display: flex;
+ flex-wrap: wrap;
+ gap: 0.4rem;
+
+ & .role__chip {
+ padding: 0.4rem 0.6rem;
+
+ border-radius: 4px;
+ background-color: $color-grey-90;
+ color: $color-grey-10;
+ }
+ }
+ }
+}
diff --git a/front/src/modules/auth/configs/auth.options.ts b/front/src/modules/auth/configs/auth.options.ts
index d62439f..4a1fbf4 100644
--- a/front/src/modules/auth/configs/auth.options.ts
+++ b/front/src/modules/auth/configs/auth.options.ts
@@ -7,6 +7,7 @@ export const authOptions: AuthOptions = {
},
pages: {
signIn: "/auth/log-in",
+ signOut: "/",
},
providers: [
CredentialsProvider({
@@ -39,6 +40,7 @@ export const authOptions: AuthOptions = {
sub: string;
username: string;
roles: Role[];
+ picture: string;
iat: number;
exp: number;
};
@@ -50,7 +52,7 @@ export const authOptions: AuthOptions = {
const user: User = {
id: token_payload.username,
roles: token_payload.roles,
- image: "https://picsum.photos/200/300",
+ image: token_payload.picture,
name: token_payload.username,
apiSession: {
accessToken: response_body.access_token,
diff --git a/front/src/modules/auth/types/next-auth.d.ts b/front/src/modules/auth/types/next-auth.d.ts
index 04df79e..7e8d5fb 100644
--- a/front/src/modules/auth/types/next-auth.d.ts
+++ b/front/src/modules/auth/types/next-auth.d.ts
@@ -2,7 +2,7 @@ import NextAuth, { DefaultSession } from "next-auth";
import { JWT, DefaultJWT } from "next-auth/jwt";
declare module "next-auth" {
- type Role = "user" | "admin";
+ type Role = "user" | "manager" | "admin";
interface ApiSession {
accessToken: string;
refreshToken?: string;
@@ -16,6 +16,7 @@ declare module "next-auth" {
}
interface Session extends DefaultSession {
+ user?: Omit;
apiSession?: ApiSession;
}
}
diff --git a/front/src/modules/common/components/header/header.component.tsx b/front/src/modules/common/components/header/header.component.tsx
deleted file mode 100644
index e6bf004..0000000
--- a/front/src/modules/common/components/header/header.component.tsx
+++ /dev/null
@@ -1,5 +0,0 @@
-import { UserDropdown } from "@/modules/auth/components/user-dropdown";
-
-export const Header = () => {
- return ;
-};
diff --git a/front/src/modules/common/components/header/header.module.scss b/front/src/modules/common/components/header/header.module.scss
deleted file mode 100644
index e69de29..0000000
diff --git a/front/src/modules/common/components/header/index.ts b/front/src/modules/common/components/header/index.ts
deleted file mode 100644
index 67c8585..0000000
--- a/front/src/modules/common/components/header/index.ts
+++ /dev/null
@@ -1 +0,0 @@
-export { Header } from "./header.component";
diff --git a/front/src/modules/common/components/navbar-header/index.ts b/front/src/modules/common/components/navbar-header/index.ts
new file mode 100644
index 0000000..49c0471
--- /dev/null
+++ b/front/src/modules/common/components/navbar-header/index.ts
@@ -0,0 +1,3 @@
+"use client";
+
+export { NavbarHeader as default } from "./navbar-header.component";
diff --git a/front/src/modules/common/components/navbar-header/navbar-header.component.tsx b/front/src/modules/common/components/navbar-header/navbar-header.component.tsx
new file mode 100644
index 0000000..af0e8b4
--- /dev/null
+++ b/front/src/modules/common/components/navbar-header/navbar-header.component.tsx
@@ -0,0 +1,18 @@
+import Link from "next/link";
+import styles from "./navbar-header.module.scss";
+
+import { PropsWithChildren } from "react";
+
+/*
+ * Receives the user component as a children in order to fetch it from the server and allow quick session information fetch
+ * */
+export const NavbarHeader = (props: PropsWithChildren) => {
+ return (
+
+
+ LoGo
+
+
+
+ );
+};
diff --git a/front/src/modules/common/components/navbar-header/navbar-header.module.scss b/front/src/modules/common/components/navbar-header/navbar-header.module.scss
new file mode 100644
index 0000000..b39432a
--- /dev/null
+++ b/front/src/modules/common/components/navbar-header/navbar-header.module.scss
@@ -0,0 +1,25 @@
+.header {
+ position: sticky;
+ top: 1.2rem;
+ left: 0;
+
+ display: flex;
+ justify-content: space-between;
+
+ margin: 1.2rem;
+ box-sizing: border-box;
+ border-radius: 8px;
+
+ padding: 0.4rem 1.8rem;
+ background-color: $color-white;
+ box-shadow: 0 1px 3px rgba($color-grey-10-rgb, 0.3);
+ color: $color-background;
+
+ .logo {
+ display: flex;
+ align-items: center;
+
+ font-size: 2.6rem;
+ font-weight: bold;
+ }
+}
diff --git a/front/src/modules/common/theme-switcher/index.ts b/front/src/modules/common/components/theme-switcher/index.ts
similarity index 100%
rename from front/src/modules/common/theme-switcher/index.ts
rename to front/src/modules/common/components/theme-switcher/index.ts
diff --git a/front/src/modules/common/theme-switcher/theme-switcher.component.tsx b/front/src/modules/common/components/theme-switcher/theme-switcher.component.tsx
similarity index 100%
rename from front/src/modules/common/theme-switcher/theme-switcher.component.tsx
rename to front/src/modules/common/components/theme-switcher/theme-switcher.component.tsx
diff --git a/front/src/modules/common/theme-switcher/theme-switcher.module.scss b/front/src/modules/common/components/theme-switcher/theme-switcher.module.scss
similarity index 100%
rename from front/src/modules/common/theme-switcher/theme-switcher.module.scss
rename to front/src/modules/common/components/theme-switcher/theme-switcher.module.scss
diff --git a/front/src/modules/common/layouts/home/home.layout.tsx b/front/src/modules/common/layouts/home/home.layout.tsx
index d6fa389..0df89b7 100644
--- a/front/src/modules/common/layouts/home/home.layout.tsx
+++ b/front/src/modules/common/layouts/home/home.layout.tsx
@@ -1,12 +1,15 @@
import { PropsWithChildren } from "react";
import styles from "./home.module.scss";
-import { Header } from "../../components/header";
+import NavbarHeader from "../../components/navbar-header";
+import UserDropdown from "@/modules/auth/components/user-dropdown";
export const HomeLayout: React.FC = ({ children }) => {
return (
-
+
+
+
{children}
);
diff --git a/front/src/modules/common/layouts/home/home.module.scss b/front/src/modules/common/layouts/home/home.module.scss
index 8b13789..0aa9b1b 100644
--- a/front/src/modules/common/layouts/home/home.module.scss
+++ b/front/src/modules/common/layouts/home/home.module.scss
@@ -1 +1,3 @@
-
+.container {
+ background-color: $color-background;
+}
diff --git a/front/src/styles/_variables.scss b/front/src/styles/_variables.scss
index 95bd6b3..5197fa4 100644
--- a/front/src/styles/_variables.scss
+++ b/front/src/styles/_variables.scss
@@ -8,11 +8,13 @@ $color-primary-light-rgb: var(--color-primary-light-rgb);
$color-primary-dark-rgb: var(--color-primary-dark-rgb);
$color-secondary: #ff7730;
-$color-background: var(--color-white);
+$color-background: var(--color-grey-90);
$color-foreground: var(--color-black);
$color-white: var(--color-white);
-$color-grey-light: var(--color-grey-light);
-$color-grey-medium: var(--color-grey-medium);
-$color-grey-dark: var(--color-grey-dark);
+$color-grey-90: var(--color-grey-90);
+$color-grey-60: var(--color-grey-60);
+$color-grey-30: var(--color-grey-30);
+$color-grey-10: var(--color-grey-10);
+$color-grey-10-rgb: var(--color-grey-10-rgb);
diff --git a/front/src/styles/main.scss b/front/src/styles/main.scss
index b53bf52..1eecbbb 100644
--- a/front/src/styles/main.scss
+++ b/front/src/styles/main.scss
@@ -5,9 +5,12 @@
--color-white: #fafafa;
--color-black: #101010;
- --color-grey-dark: #495057;
- --color-grey-medium: #adb5bd;
- --color-grey-light: #dee2e6;
+ --color-grey-10: #171717;
+ --color-grey-30: #242424;
+ --color-grey-60: #363636;
+ --color-grey-90: #bbbbbb;
+ --color-grey-90-rgb: 153, 153, 153;
+ --color-grey-10-rgb: 23, 23, 23;
--color-primary: #9c89b8;
--color-primary-light: #b8bedd;
@@ -24,13 +27,14 @@
--color-grey-dark: #dee2e6;
--color-grey-medium: #adb5bd;
--color-grey-light: #495057;
+ --color-grey-dark-rgb: 222, 226, 230;
- --color-primary: #56577d;
- --color-primary-light: #b8bedd;
- --color-primary-dark: #9c89b8;
- --color-primary-rgb: 86, 87, 125;
- --color-primary-light-rgb: 184, 190, 221;
- --color-primary-dark-rgb: 156, 137, 184;
+ --color-grey-10: #bbbbbb;
+ --color-grey-30: #363636;
+ --color-grey-60: #242424;
+ --color-grey-90: #171717;
+ --color-grey-90-rgb: 23, 23, 23;
+ --color-grey-10-rgb: 153, 153, 153;
}
*,
diff --git a/mysql/dump/dump.sql b/mysql/dump/dump.sql
index b9e486f..083d425 100755
--- a/mysql/dump/dump.sql
+++ b/mysql/dump/dump.sql
@@ -4,6 +4,7 @@ CREATE TABLE user (
username VARCHAR(50) NOT NULL,
password VARCHAR(255) NOT NULL,
roles VARCHAR(255) NOT NULL,
+ picture VARCHAR(255),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
@@ -15,9 +16,9 @@ CREATE TABLE example (
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-INSERT INTO user (username, password, roles) VALUES
-('dqnid', '$2b$10$DDGh9u4yiTY9FJx2faFPlucBbTB6Y3i8YkH7AEztcpeaKv08AjdrW', 'admin'),
-('albi', '$2b$10$DDGh9u4yiTY9FJx2faFPlucBbTB6Y3i8YkH7AEztcpeaKv08AjdrW', 'admin');
+INSERT INTO user (username, password, roles, picture) VALUES
+('dqnid', '$2b$10$DDGh9u4yiTY9FJx2faFPlucBbTB6Y3i8YkH7AEztcpeaKv08AjdrW', 'user;manager;admin', 'https://picsum.photos/200/300'),
+('albi', '$2b$10$DDGh9u4yiTY9FJx2faFPlucBbTB6Y3i8YkH7AEztcpeaKv08AjdrW', 'admin', NULL);
INSERT INTO example (name, description, image) VALUES
('dqnid', 'This is a short text stored in a mysql database', 'https://picsum.photos/200/300'),