auth media

This commit is contained in:
2026-03-14 22:24:46 +01:00
parent f661ef8918
commit efcdc75171
4 changed files with 81 additions and 3 deletions

View File

@@ -2,6 +2,7 @@ export {
logoutUser,
clearError,
clearDeleteStatus,
setOAuthTokens,
//addLoadedFiles,
default,
} from "./userDetailsSlice";

View File

@@ -1,6 +1,7 @@
import { JWT_TOKEN, JWT_REFRESH_TOKEN } from "../../constants";
import { initialState } from "./initialState";
import { updateTokens } from "./tokenHelpers";
export const reducers = {
logoutUser(state) {
@@ -20,6 +21,11 @@ export const reducers = {
state.deletedCount = 0;
},
setOAuthTokens(state, action) {
const { token, refreshToken } = action.payload;
updateTokens(state, token, refreshToken);
},
// addLoadedFiles(state, action) {
// state.loadedFiles = [...state.loadedFiles, ...action.payload];
// },

View File

@@ -18,7 +18,7 @@ const userDetailsSlice = createSlice({
});
//export const { logoutUser, clearError, clearDeleteStatus, addLoadedFiles } =
export const { logoutUser, clearError, clearDeleteStatus } =
export const { logoutUser, clearError, clearDeleteStatus, setOAuthTokens } =
userDetailsSlice.actions;
export default userDetailsSlice.reducer;

View File

@@ -1,17 +1,55 @@
import { useState, useEffect } from "react";
import { useDispatch, useSelector } from "react-redux";
import { useNavigate, Link } from "react-router-dom";
import { clearError } from "../features/slices/details-slice";
import { useNavigate, Link, useSearchParams } from "react-router-dom";
import { clearError, setOAuthTokens } from "../features/slices/details-slice";
import fetchLoginUser from "../features/fetch-async/fetchLoginUser";
function GoogleIcon() {
return (
<svg width="18" height="18" viewBox="0 0 48 48" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M47.532 24.552c0-1.636-.148-3.21-.422-4.728H24.48v8.95h12.954c-.558 3.012-2.254 5.564-4.8 7.278v6.048h7.774c4.548-4.19 7.124-10.364 7.124-17.548z" fill="#4285F4"/>
<path d="M24.48 48c6.504 0 11.958-2.156 15.944-5.9l-7.774-6.048c-2.156 1.444-4.912 2.298-8.17 2.298-6.282 0-11.606-4.244-13.51-9.946H2.918v6.244C6.886 42.692 15.1 48 24.48 48z" fill="#34A853"/>
<path d="M10.97 28.404A14.443 14.443 0 0 1 9.938 24c0-1.528.262-3.014.73-4.404V13.352H2.918A23.963 23.963 0 0 0 .48 24c0 3.868.926 7.526 2.438 10.648l8.052-6.244z" fill="#FBBC05"/>
<path d="M24.48 9.548c3.54 0 6.718 1.216 9.216 3.604l6.908-6.908C36.43 2.392 30.978 0 24.48 0 15.1 0 6.886 5.308 2.918 13.352l8.052 6.244c1.904-5.702 7.228-9.946 13.51-9.946-.002 0-.002-.002 0-.002z" fill="#EA4335"/>
</svg>
);
}
function GitHubIcon() {
return (
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path d="M12 0C5.374 0 0 5.373 0 12c0 5.302 3.438 9.8 8.207 11.387.6.113.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23A11.509 11.509 0 0 1 12 5.803c1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576C20.566 21.797 24 17.3 24 12c0-6.627-5.373-12-12-12z"/>
</svg>
);
}
function FacebookIcon() {
return (
<svg width="18" height="18" viewBox="0 0 24 24" fill="currentColor" xmlns="http://www.w3.org/2000/svg">
<path d="M24 12.073C24 5.405 18.627 0 12 0S0 5.405 0 12.073C0 18.1 4.388 23.094 10.125 24v-8.437H7.078v-3.49h3.047V9.41c0-3.025 1.792-4.697 4.533-4.697 1.312 0 2.686.236 2.686.236v2.97h-1.513c-1.491 0-1.956.93-1.956 1.886v2.268h3.328l-.532 3.49h-2.796V24C19.612 23.094 24 18.1 24 12.073z"/>
</svg>
);
}
function LoginPage() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const dispatch = useDispatch();
const navigate = useNavigate();
const [searchParams] = useSearchParams();
const { loading, error, token } = useSelector((state) => state.userDetails);
// Handle OAuth2 callback: ?token=...&refreshToken=...
useEffect(() => {
const urlToken = searchParams.get("token");
const urlRefreshToken = searchParams.get("refreshToken");
if (urlToken) {
dispatch(setOAuthTokens({ token: urlToken, refreshToken: urlRefreshToken }));
navigate("/", { replace: true });
}
}, [searchParams, dispatch, navigate]);
// Redirect if already logged in
useEffect(() => {
if (token) {
@@ -119,6 +157,39 @@ function LoginPage() {
</button>
</form>
{/* OAuth2 section */}
<div className="mt-6 flex items-center gap-3">
<div className="flex-1 h-px bg-slate-700" />
<span className="text-xs text-slate-500 font-medium">or</span>
<div className="flex-1 h-px bg-slate-700" />
</div>
<div className="mt-4 space-y-3">
<a
href="/oauth2/authorization/google"
className="w-full inline-flex items-center justify-center gap-3 rounded-xl bg-slate-800 hover:bg-slate-700 active:bg-slate-900 border border-slate-600 hover:border-slate-500 transition-colors px-4 py-2.5 text-sm font-medium text-slate-200"
>
<GoogleIcon />
Login with Google
</a>
<a
href="/oauth2/authorization/github"
className="w-full inline-flex items-center justify-center gap-3 rounded-xl bg-slate-800 hover:bg-slate-700 active:bg-slate-900 border border-slate-600 hover:border-slate-500 transition-colors px-4 py-2.5 text-sm font-medium text-slate-200"
>
<GitHubIcon />
Login with GitHub
</a>
<a
href="/oauth2/authorization/facebook"
className="w-full inline-flex items-center justify-center gap-3 rounded-xl bg-slate-800 hover:bg-slate-700 active:bg-slate-900 border border-slate-600 hover:border-slate-500 transition-colors px-4 py-2.5 text-sm font-medium text-slate-200"
>
<FacebookIcon />
Login with Facebook
</a>
</div>
<p className="mt-6 text-center text-sm text-slate-400">
Don't have an account?{" "}
<Link