Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
53 commits
Select commit Hold shift + click to select a range
7df0452
AI limit v1
Sckibb Nov 24, 2025
9d0cfc0
AI limit v2
Sckibb Nov 24, 2025
5a3caf8
AI limit v3
Sckibb Nov 24, 2025
5a7db5d
AI limit v4
Sckibb Nov 24, 2025
1fc1e2a
Buddy CSS manual v1
Sckibb Nov 26, 2025
d7a76c4
Profile CSS manual v1
Sckibb Nov 26, 2025
17107c3
Profile CSS manual v2
Sckibb Nov 26, 2025
c7ee2a0
Profile CSS manual v3
Sckibb Nov 26, 2025
40ff98c
Profile CSS manual v4
Sckibb Nov 26, 2025
c7efc68
Profile CSS manual v5
Sckibb Nov 26, 2025
09e7e65
Nicks changes v1
Sckibb Nov 26, 2025
e57d396
Nicks changes v2
Sckibb Nov 26, 2025
2b5e740
Nicks changes v3
Sckibb Nov 26, 2025
056e0cb
Nicks changes v4
Sckibb Nov 26, 2025
aff6fdd
Nicks changes v5
Sckibb Nov 26, 2025
d52fe85
Nicks changes v6
Sckibb Nov 26, 2025
59c14ce
Nicks changes v7
Sckibb Nov 26, 2025
aa1ef38
Bears changes man v1
Sckibb Nov 26, 2025
dbae98b
Bears changes man v2
Sckibb Nov 26, 2025
2cb3dab
Bears changes man v3
Sckibb Nov 26, 2025
9c50eb3
Bears changes man v4
Sckibb Nov 26, 2025
20c6d1d
Bears changes man v5
Sckibb Nov 26, 2025
869181d
Bears changes man v6
Sckibb Nov 26, 2025
a631c8d
Bears changes man v7
Sckibb Nov 26, 2025
0d3a649
Bears changes man v8
Sckibb Nov 26, 2025
c741538
Bears changes man v9
Sckibb Nov 26, 2025
b2530a0
Bears changes man v10
Sckibb Nov 27, 2025
0bf0ec9
Bears changes man v11
Sckibb Nov 27, 2025
d031e58
Bears changes man v12
Sckibb Nov 27, 2025
86bcfd5
Bears changes man v13
Sckibb Nov 27, 2025
4e20afc
login fix v1
Sckibb Nov 28, 2025
c3d51ae
login fix v2
Sckibb Nov 28, 2025
2f8ff17
testing
Smibers Nov 29, 2025
1c03b52
testing
Smibers Nov 29, 2025
5136dbd
testing
Smibers Nov 29, 2025
ae6b6e1
testing
Smibers Nov 29, 2025
2748920
new
Smibers Nov 29, 2025
798a14a
new
Smibers Nov 29, 2025
2ef455b
final fixes
Smibers Nov 29, 2025
2c4ec6e
final fixes
Smibers Nov 29, 2025
81d6b44
final fixes
Smibers Nov 29, 2025
e962db3
profile deployment errors
Smibers Nov 29, 2025
059aa52
profile deployment errors
Smibers Nov 29, 2025
1a97373
profile deployment errors
Smibers Nov 29, 2025
47c07c1
profile deployment errors
Smibers Nov 30, 2025
a486b27
deploy test
Smibers Dec 1, 2025
dbd9469
Noah change v1
Sckibb Dec 11, 2025
bafbf28
Noah change v2
Sckibb Dec 11, 2025
74904c3
Noah change v3
Sckibb Dec 11, 2025
5445b4d
Noah change v4
Sckibb Dec 11, 2025
8f55740
Noah change v5
Sckibb Dec 11, 2025
64757c6
Noah change v6
Sckibb Dec 11, 2025
a882e83
Noah change v7
Sckibb Dec 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions bookbuddy/frontend/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import Library from "./Library";
import WishList from "./WishBook";
import Buddy from "./Buddy_Recommendation";
import Profile from "./Profile";
import ProtectedRoutes from "./ProtectedRoutes";

export default function App() {
const location = useLocation();
Expand All @@ -20,19 +21,22 @@ export default function App() {
{/* Public routes */}
<Route path="/" element={<Signup />} />
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<Signup />} />
{/*<Route path="/signup" element={<Signup />} />*/}

{/* Routes inside ProtectedRoutes */}
<Route element={<ProtectedRoutes />}>
{/* Routes inside Layout */}
<Route element={<Layout />}>
<Route path="/profile" element={<Profile />} />
<Route path="/search" element={<Search />} />
<Route path="/library" element={<Library />} />
<Route path="/WishList" element={<WishList />} />
<Route path="/WishBook" element={<WishList />} />
<Route path="/Buddy_Recommendation" element={<Buddy />} />
</Route>
</Route>

{/* Catch-all redirect */}
<Route path="*" element={<Navigate to="/login" replace />} />
<Route path="*" element={<Navigate to="/" replace />} />
</Routes>
</div>
);
Expand Down
2 changes: 1 addition & 1 deletion bookbuddy/frontend/src/Buddy_Recommendation.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -416,4 +416,4 @@ function Buddy() {
);
}

export default Buddy;
export default Buddy;
53 changes: 32 additions & 21 deletions bookbuddy/frontend/src/Profile.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import {useEffect, useState} from "react";
import {AccountDto} from "./types/AccountDto";
import {getCurrentUser, getMyLibrary} from "./api";
import {BookDto} from "./types/BookDto";
import {useNavigate} from "react-router-dom";
import { useEffect, useState } from "react";
import { AccountDto } from "./types/AccountDto";
import { getCurrentUser, getMyLibrary } from "./api";
import { BookDto } from "./types/BookDto";
import { useNavigate } from "react-router-dom";
import "./Styling/Profile.css";


export default function Profile() {
const navigate = useNavigate();

const [account, setAccount] = useState<AccountDto | null>(null);
const [books, setBooks] = useState<BookDto[]>([]);
const [loading, setLoading] = useState(true);
Expand All @@ -16,26 +16,33 @@ export default function Profile() {
const totalPages = books.reduce((sum, b) => sum + (b.pagecount || 0), 0);

useEffect(() => {
(async () => {
async function loadData() {
try {
const acct = await getCurrentUser();
setAccount(acct);

const lib = await getMyLibrary();
setBooks(lib);
} catch (e: any) {
console.error(e);
navigate("/login");
const userData = await getCurrentUser();
const libraryData = await getMyLibrary();
setAccount(userData);
setBooks(libraryData);
} catch (err) {
setError("Failed to load profile");
} finally {
setLoading(false);
}
})();
}, [navigate]);
}
loadData();
}, []);

if (loading) {
return (
<div className="wrap">
<h1>Loading profile...</h1>
<div className="profile-page">
<div className="wrap">Loading...</div>
</div>
);
}

if (error) {
return (
<div className="profile-page">
<div className="wrap">{error}</div>
</div>
);
}
Expand All @@ -52,10 +59,14 @@ export default function Profile() {
<p><strong>AI Uses Remaining:</strong> {account?.aiLimit ?? 0}</p>
</div>

<button className="bb-btn" onClick={() => navigate("/library")}>
<button
className="bb-btn"
onClick={() => navigate("/library")}
>
Go to My Library
</button>

</div>
</div>
);}
);
}
14 changes: 14 additions & 0 deletions bookbuddy/frontend/src/ProtectedRoutes.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import {
Outlet,
Navigate
} from 'react-router-dom'

const ProtectedRoutes = () => {
return (
localStorage.getItem("accountId") ?
<Outlet /> :
<Navigate to="/" />
)
}

export default ProtectedRoutes
208 changes: 208 additions & 0 deletions bookbuddy/frontend/src/Styling/AboutUS.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,208 @@

/* Existing button-bubble base styles (keep these, or adjust as needed) */
.button-bubble {
padding: 10px;
border-radius: 7px;
font-size: 1.1rem;
font-weight: 700;
cursor: pointer;
transition: all 0.2s ease-in-out;
position: absolute;
background-color: #235789;
color: #ffffff;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
}

.button-bubble:hover {
background-color: #e2b4bd;

transform: translateY(-3px);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.3);
}

.button-bubble:active {
background-color: #7175c0;
transform: translateY(0);
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}

.button-bubble:disabled {
background-color: #cccccc;
color: #666666;
cursor: not-allowed;
transform: none;
box-shadow: none;
}


.question-circle {
display: block;
background: #424b54;
color: #fff;
border-radius: 50%;
width: 40px;
height: 40px;
line-height: 4px;
text-align: center;
font-size: 20px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.3);
transition: all 0.2s ease-in-out;
}
.question-circle:hover {
transform: translateY(-3px);
box-shadow: 0 6px 12px rgba(0, 0, 0, 0.3);
}

@keyframes slideDown {
0% {
opacity: 0;
transform: translate(-50%, -150%);
}
100% {
opacity: 1;
transform: translate(-50%, -50%);
}
}
@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}

@keyframes slideUp {
/* Starts at the current centered position (100% of the original slideDown) */
0% {
opacity: 1;
transform: translate(-50%, -50%);
}
/* Ends off-screen at the top, fading out */
100% {
opacity: 0;
transform: translate(-50%, -150%);
}
}

@keyframes fadeOut {
from {
opacity: 1;
}
to {
opacity: 0;
}
}

.popup {
/* Positioning & Layout */
position: fixed;
top: 50%;
left: 50%;
transform: translate(-50%, -50%); /* Final state/fallback */
border-right: solid gray 15px;
z-index: 100;

/* Appearance */
background-color: #ffffff;
border-top-left-radius: 25px;
border-bottom-left-radius: 25px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.5);

/* Size & Content */
width: 90%;
max-width: 645px;
max-height: 80vh;
padding: 30px;
overflow-y: auto;

/* Typography */
font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
color: #333;

/* --- ANIMATION ADDED --- */
animation: slideDown 0.5s ease-out forwards;

}

.popup h1 {
color: #4a90e2; /* A nice, friendly blue */
font-size: 2.2em;
border-bottom: 3px solid #f0f0f0; /* Subtle separator */
padding-bottom: 10px;
margin-top: 0; /* Remove default top margin */
margin-bottom: 25px;
}

.popup h2 {
color: #555;
font-size: 1.5em;
margin-top: 20px;
margin-bottom: 10px;
}

.popup h3 {
color: #6a6a6a; /* A slightly softer gray than h2 */
font-size: 1.2em; /* Smaller than h2 but larger than body text */
font-weight: 600; /* Slightly bolder for emphasis */
margin-top: 15px; /* Less space above than h2 */
margin-bottom: 5px; /* Closer to the content below it (like a list of names) */
}

/* Styling for the Paragraphs */
.popup p {
font-size: 1.05em;
line-height: 1.6;
margin-bottom: 20px;
}
.popup a {

color: #0000EE;
}

/* --- NEW EXIT CLASSES --- */
.popup.closing {
/* The animation duration and timing should match the slideDown animation */
animation: slideUp 0.5s ease-in forwards;
}

.backdrop.closing {
/* The animation duration and timing should match the original backdrop animation */
animation: fadeOut 0.7s ease forwards;
}

.close {
position: absolute;
top: 15px;
right: 25px;
font-size: 30px;
font-weight: bold;
color: #aaa;
cursor: pointer;
transition: color 0.2s ease;

}
p ul {
padding-left: 40px;
margin-top: 5px;
}

/* Hover effect for the close button */
.close:hover,
.close:focus {
color: #d9534f; /* Change to a warning color (red) on hover */
text-decoration: none;
}


.backdrop {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background-color: rgba(0, 0, 0, 0.8); /* Semi-transparent black */
z-index: 99; /* Below the popup (100) but above everything else */
animation: fadeIn 0.7s ease forwards;

}
3 changes: 2 additions & 1 deletion bookbuddy/frontend/src/Styling/Buddy_Recommendation.css
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@

/*Form CSS*/
.pageBackground {
width: 100vw;
Expand Down Expand Up @@ -190,4 +191,4 @@
display: inline-block;
width: 100%;
text-align: left;
}
}
2 changes: 1 addition & 1 deletion bookbuddy/frontend/src/Styling/Profile.css
Original file line number Diff line number Diff line change
Expand Up @@ -92,4 +92,4 @@
opacity: 1;
transform: translateY(0);
}
}
}
Loading