Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
272 commits
Select commit Hold shift + click to select a range
6ae622e
navBar
alex91-html Aug 12, 2025
0b599c9
nav bar
alex91-html Aug 12, 2025
37a6dd2
navigation with arrow and adding new sphere in 3D view added
alex91-html Aug 12, 2025
6287b25
refactor todo list structure for 3D environment and UI improvements
alex91-html Aug 12, 2025
4e7de9b
style component for navBar
alex91-html Aug 13, 2025
46964a8
installed npm material-icons etc
alex91-html Aug 13, 2025
414ef79
data flow for ideaCard is working with mockapi and data
HolaCarmensita Aug 13, 2025
68da5f2
data flow for ideaCarousel is working with mockapi and data
HolaCarmensita Aug 13, 2025
33aa289
moved the mocknagivation to its own file, making it esier to add the …
HolaCarmensita Aug 13, 2025
8214fb5
react-swipble added to imgCarousel and navbuttons deleted
HolaCarmensita Aug 13, 2025
40b2a84
navBar done
alex91-html Aug 13, 2025
35ebad3
navBar styling
alex91-html Aug 13, 2025
b75d126
Merge remote-tracking branch 'origin/dev' into ideaPage
HolaCarmensita Aug 13, 2025
c494254
found the solution for us. Added the solution in a file called LAYERE…
HolaCarmensita Aug 13, 2025
198d42f
just refining the LAUYERED file
HolaCarmensita Aug 13, 2025
9bb60fb
commited all changes
alex91-html Aug 13, 2025
56c0e8d
solved bug
alex91-html Aug 13, 2025
40c2bb0
Merge branch 'dev' into navBar
alex91-html Aug 13, 2025
6dabd2b
todo
alex91-html Aug 13, 2025
1606fbf
moved md files
alex91-html Aug 13, 2025
057260b
fixed code error
alex91-html Aug 13, 2025
b8360be
install npm nipplejs, createdd jsx file, coded
alex91-html Aug 13, 2025
b9cfd3a
somthing can't remember
alex91-html Aug 13, 2025
d29bbe0
joystick added
alex91-html Aug 13, 2025
1f1c5a7
updates
alex91-html Aug 13, 2025
de7512e
joystic controlling camera view
alex91-html Aug 13, 2025
15ba20d
joystic added for different formats
alex91-html Aug 13, 2025
36fa3ea
Routes added and placeholder pages. Also the css for the layout is in…
HolaCarmensita Aug 14, 2025
e1a0ed0
updated todo.md
alex91-html Aug 14, 2025
7a3f28a
latest update
alex91-html Aug 14, 2025
aa6a567
npm nipplejs
alex91-html Aug 14, 2025
915e11d
merged dev
alex91-html Aug 14, 2025
bfab258
joystick
alex91-html Aug 14, 2025
dc9977b
mod
alex91-html Aug 14, 2025
cac7850
done
alex91-html Aug 14, 2025
43afbbc
text
alex91-html Aug 14, 2025
63962b6
Merge branch 'navBar' into dev
alex91-html Aug 14, 2025
1af8629
Move icons and mockImg from public to assets and update paths
alex91-html Aug 14, 2025
3f22414
moved icons
alex91-html Aug 14, 2025
df24260
Removed the left and right arrow keys navigation in the imgCarousel a…
HolaCarmensita Aug 14, 2025
07ee765
adding an idea modal
alex91-html Aug 14, 2025
319cb29
navigation
alex91-html Aug 14, 2025
c421883
moved files
alex91-html Aug 14, 2025
1b122c7
fixed folders
alex91-html Aug 14, 2025
d4420de
renamed ideaCarousle into ideaPage
alex91-html Aug 14, 2025
e83b374
moved navBar to App.jsx
alex91-html Aug 14, 2025
69030fb
fixing text
alex91-html Aug 14, 2025
8eccaa7
sync the navigations bro
alex91-html Aug 14, 2025
449c013
ProfilePage name change
alex91-html Aug 15, 2025
1e086c5
color code for sphere
alex91-html Aug 15, 2025
04b0c52
logic in store
alex91-html Aug 15, 2025
f0aedce
zustand update
alex91-html Aug 15, 2025
dcbf94f
installed gasp
alex91-html Aug 15, 2025
b8fa2c1
added navBar click,navigation
alex91-html Aug 15, 2025
f555a71
removed console.log
alex91-html Aug 15, 2025
d2f6733
moved modal add idea
alex91-html Aug 15, 2025
635d672
created a button component
alex91-html Aug 15, 2025
573e9f1
added icons from assets to navBar
alex91-html Aug 15, 2025
b8ca46f
fixes nav bar width
alex91-html Aug 15, 2025
41936e6
the header is now working accordning to the design. But the routes ca…
HolaCarmensita Aug 15, 2025
d17a3f7
optimization
alex91-html Aug 15, 2025
fd34b85
removed and add media queris for shadow due to making components look…
HolaCarmensita Aug 18, 2025
88c631c
deleted previous files
alex91-html Aug 18, 2025
e404c01
profile page design implementations
alex91-html Aug 18, 2025
266fe12
fixes during merge
HolaCarmensita Aug 18, 2025
b1c47f4
deleted the unwished old ideaCarousel from merge
HolaCarmensita Aug 18, 2025
3d9d895
forgot to save
HolaCarmensita Aug 18, 2025
8fed725
had to copyPaste the login from another branch made from a old dev, t…
HolaCarmensita Aug 18, 2025
234f757
added the same validation stucture in login as register, regex, error…
HolaCarmensita Aug 18, 2025
36633e1
updated
alex91-html Aug 18, 2025
727cf79
removed breakpoint
alex91-html Aug 18, 2025
021f3e5
margin bottom section fixed
alex91-html Aug 18, 2025
c8eeb10
test
alex91-html Aug 18, 2025
36731e4
fixed styling
alex91-html Aug 18, 2025
5225129
added css animation to unstack cards
alex91-html Aug 18, 2025
2702c2c
added unstack also to liked ideas
alex91-html Aug 18, 2025
bb5157c
added shadow
alex91-html Aug 18, 2025
9d8d09d
removed gradiant
alex91-html Aug 18, 2025
251722d
styled btn
alex91-html Aug 18, 2025
07b4fc5
changed btn border radious
alex91-html Aug 18, 2025
ceafe21
modify cards stack
alex91-html Aug 18, 2025
f6ed986
a few styling changes to the auth modals, added by a new classname mo…
HolaCarmensita Aug 19, 2025
ce18db3
just took away a background color used during refactoring
HolaCarmensita Aug 19, 2025
4e71caa
cursor added to cards
alex91-html Aug 19, 2025
6c3194c
hide navBar in Profile page when on mobile
alex91-html Aug 19, 2025
bc2dc08
had to add IdeasPage to the route /ideas and also fixed a fixed hight…
HolaCarmensita Aug 19, 2025
72c49cb
edit icons for ideas
alex91-html Aug 19, 2025
3347208
like an idea
alex91-html Aug 19, 2025
2b20572
i forgot now
alex91-html Aug 19, 2025
9a487b7
added files and folders and dependecies
HolaCarmensita Aug 19, 2025
6a286af
deleted unnecessart routes
alex91-html Aug 19, 2025
8619d19
made a open idea btn component
alex91-html Aug 19, 2025
8a4d632
added the user and idea model, tryied to add everything we need and a…
HolaCarmensita Aug 19, 2025
ed66f6f
refractioned code
alex91-html Aug 19, 2025
7d315df
resolved conflict
alex91-html Aug 19, 2025
8202552
auth middlewere and auth routes done
HolaCarmensita Aug 19, 2025
6464cd9
temporary ideas
alex91-html Aug 19, 2025
7319812
basic server done, connected to mongoDB
HolaCarmensita Aug 19, 2025
27ba2f1
styling my idea edit card
alex91-html Aug 19, 2025
4a2ef0c
changed ideas for my profile
alex91-html Aug 19, 2025
165da87
removed ai icon
alex91-html Aug 19, 2025
8c68db8
modify text
alex91-html Aug 19, 2025
ed2eb87
glow
alex91-html Aug 19, 2025
0416be7
changes 3d
alex91-html Aug 19, 2025
7e798a6
end
alex91-html Aug 19, 2025
e25d3cc
myidapage
alex91-html Aug 20, 2025
ef00ae5
the authRoutees are mounet in the server, tested in Postman
HolaCarmensita Aug 20, 2025
b0474b5
deleted page
alex91-html Aug 20, 2025
b40c24d
idk
alex91-html Aug 20, 2025
31cb3da
ideas routes done
HolaCarmensita Aug 20, 2025
48c2e50
users routes set and done
HolaCarmensita Aug 20, 2025
a75efec
did not commit regulary so I try to copy paste abit here, this is the…
HolaCarmensita Aug 20, 2025
6313a6f
Merge remote-tracking branch 'origin/dev' into backendSetup
HolaCarmensita Aug 20, 2025
33ebae3
added new component for stacked idea
alex91-html Aug 20, 2025
0634b9c
fixing some styling
alex91-html Aug 20, 2025
df740dc
styling
alex91-html Aug 20, 2025
052698f
im bored
alex91-html Aug 20, 2025
e28fe05
im tired
alex91-html Aug 20, 2025
b107106
removed a line
alex91-html Aug 20, 2025
1acd536
fixing user page
alex91-html Aug 20, 2025
fbbec64
changed mockData
alex91-html Aug 20, 2025
d2f6041
connecting to user
alex91-html Aug 20, 2025
b674d9d
fixing navigation
alex91-html Aug 20, 2025
0d97b56
Merge branch 'dev' into MyCon
alex91-html Aug 20, 2025
a175e17
todo list for connecting b and f
HolaCarmensita Aug 21, 2025
6440a62
api.js is done with error handling and interceptors
HolaCarmensita Aug 21, 2025
7471a67
adding sparkles in the space
alex91-html Aug 21, 2025
19a1543
now both Auth, ideas and users service filesis ready for Zustand
HolaCarmensita Aug 21, 2025
52f5ecb
changing style of 3d sphere
alex91-html Aug 21, 2025
320bdc6
VSC not responding, saving everytingh
alex91-html Aug 21, 2025
5082de9
commented out outer orbit
alex91-html Aug 21, 2025
c249813
trying to fix orb
alex91-html Aug 21, 2025
c026cb8
useAuthStore done
HolaCarmensita Aug 21, 2025
2244ed3
sparkle fix
alex91-html Aug 21, 2025
1b52e26
sparkle speed
alex91-html Aug 21, 2025
4904a28
moves UI related things to a nes useUIStore and changed the imports i…
HolaCarmensita Aug 21, 2025
26ebfb6
added useUserStore and added search to ideaService and ideaStore
HolaCarmensita Aug 21, 2025
5e3bd10
added puls to the sparkles
alex91-html Aug 21, 2025
0462792
LoginPage is now connected to Store and backend
HolaCarmensita Aug 21, 2025
c30b9a3
Register connected t bakcend and store implemented in the Page, also …
HolaCarmensita Aug 22, 2025
138729f
refactored the app.jsx cus it was so messy. did this with ai and I th…
HolaCarmensita Aug 22, 2025
751bc20
fixed the bud where auth wasnt restored after pagereload. So for now …
HolaCarmensita Aug 22, 2025
eb02658
changed some header css and also added a nagivate back to homepage cl…
HolaCarmensita Aug 22, 2025
3a87fd1
have to fix the layout once again beacuse of a buf i could not find, …
HolaCarmensita Aug 22, 2025
1c6e35f
new added
alex91-html Aug 22, 2025
44b85f2
added rim light around the 3D sphere
alex91-html Aug 25, 2025
cfb10a7
added npm postprocessing
alex91-html Aug 25, 2025
b9e2253
animated sphere
alex91-html Aug 25, 2025
3aa6900
removed auraColor
alex91-html Aug 25, 2025
49b1f42
OMG did the layout all overagain beacuse of to much redudant code, re…
HolaCarmensita Aug 25, 2025
f7d1706
refractored code, cleand up 3D scene
alex91-html Aug 25, 2025
6c9b709
removed header to the background
alex91-html Aug 25, 2025
215e286
fixed navBar arrow left and right shows idea card
alex91-html Aug 25, 2025
c552e82
slowed time for idea card to appear when clicking on sphere
alex91-html Aug 25, 2025
ef8a5a9
Last pices for mvp, their is still loadingspinner and Errorhandling t…
HolaCarmensita Aug 25, 2025
7aae1ea
Merge remote-tracking branch 'origin/dev' into bfintegration
HolaCarmensita Aug 25, 2025
e897450
get connections route didnt not exist? How is that possible
HolaCarmensita Aug 25, 2025
33664ac
took away the fixed width in the 3d space making it flow within the f…
HolaCarmensita Aug 25, 2025
8d2acfe
fixed the layout errors that accourd after merge
HolaCarmensita Aug 25, 2025
432cf1a
Merge remote-tracking branch 'origin/dev' into bfintegration
HolaCarmensita Aug 25, 2025
4abd2cb
Redudant fetches, i dont know what happend, it is fixed hopefully. No…
HolaCarmensita Aug 25, 2025
b012180
added connectedBy in the ideamodel and the routes to connect to an id…
HolaCarmensita Aug 26, 2025
ebdc6e4
added connect to idea service,refactored the modal to work with the b…
HolaCarmensita Aug 26, 2025
b2242a3
Okey i just realised that i'm not using the sotre correct, now both l…
HolaCarmensita Aug 26, 2025
9e735de
you can not conecct or like your own idea
HolaCarmensita Aug 26, 2025
75a302b
now you cant like or connect to your idea on the frontend, buttons di…
HolaCarmensita Aug 26, 2025
18c8ace
the mockdata and fallbacks for development made me crazy and confused…
HolaCarmensita Aug 27, 2025
c78ce1a
protected routes in frontend. Public and protected. User now gets red…
HolaCarmensita Aug 27, 2025
5d0cb55
all old .id has been removed, now only usin _id thrue the hole app
HolaCarmensita Aug 27, 2025
991dfd5
My Connections is now one section
HolaCarmensita Aug 27, 2025
83870c2
ai cleaned uo unused searchIdeas function and made the The LikeButton…
HolaCarmensita Aug 27, 2025
f1fbe2f
still problem with the likeing and connection logic, storing the same…
HolaCarmensita Aug 27, 2025
3eb0bb7
just a mess dont remember anything anymoregit add . ! Frustrated as h…
HolaCarmensita Aug 27, 2025
dced63e
added loggedin username on profile to not be confused
HolaCarmensita Aug 27, 2025
2c5807d
wrong store for logged in user dispaly
HolaCarmensita Aug 27, 2025
b6cc071
reload bug fixed
HolaCarmensita Aug 27, 2025
3e6d1d5
seems liek i can like unlike, connect and unconnect again
HolaCarmensita Aug 27, 2025
2895988
delited todo files and a hook not being used
HolaCarmensita Aug 27, 2025
316134c
multer intalled and upload.js as fileupload middlewere
HolaCarmensita Aug 27, 2025
958a3b6
försökte att fixa ett moln Cloudanry men fick det inte att funka
HolaCarmensita Aug 27, 2025
3f51345
The UseSceneNav hook is now used handle the left/right keys on the /i…
HolaCarmensita Aug 28, 2025
73ef039
ready to merge auModal to dev
alex91-html Aug 28, 2025
f2d4def
nodemailer and a ok looking confirmationemail and notifikation email …
HolaCarmensita Aug 28, 2025
671ba53
profile got a title and the logged in display has roght padding and m…
HolaCarmensita Aug 28, 2025
0d27a4d
took away queris in the stacked cards in profile that had an overflow…
HolaCarmensita Aug 28, 2025
3400b59
modal is now grwing in as an animtion
HolaCarmensita Aug 28, 2025
fc5c0ea
fixes
alex91-html Aug 28, 2025
cd38f92
modalcontainer is now animated to grow and shrink when open and closing
HolaCarmensita Aug 28, 2025
403aed1
removed console logs from the backend
HolaCarmensita Aug 28, 2025
08ccf6c
animations for text in coloredcard
HolaCarmensita Aug 28, 2025
409d84e
idea have always same color
alex91-html Aug 28, 2025
9c104a4
cloudinary image up
alex91-html Aug 28, 2025
395d3fb
images upload
alex91-html Aug 28, 2025
2a7e76f
test image upload
alex91-html Aug 28, 2025
12f76dd
env file
alex91-html Aug 28, 2025
88e20d8
added comments
alex91-html Aug 28, 2025
9b20e6a
comment camera control
alex91-html Aug 28, 2025
77a70ea
Remove fade animations and improve text truncation
HolaCarmensita Aug 28, 2025
f5cbff2
removed animations cus it dosent work for profile to idea and vs
HolaCarmensita Aug 28, 2025
9590774
what i wrote in commiten innan
HolaCarmensita Aug 28, 2025
e9a4a9d
radial gradiant restored
alex91-html Aug 28, 2025
21e139b
added comment
alex91-html Aug 28, 2025
cd9d3a2
installerad framer motion
HolaCarmensita Aug 28, 2025
a031e3d
PageHeader done
HolaCarmensita Aug 28, 2025
c2496fe
ProfileButton close the modal when the modal is open
HolaCarmensita Aug 28, 2025
edf2659
just forgot to delete the margin
HolaCarmensita Aug 28, 2025
0d0b44a
ConnectedPage polish
HolaCarmensita Aug 28, 2025
adc32c4
Add Netlify configuration for deployment
HolaCarmensita Aug 28, 2025
0f72490
refacotred so the uiStore handles the hole function for the nagivatio…
HolaCarmensita Aug 29, 2025
e3868e3
moved the useSceneNavigation hook to hooks folder
HolaCarmensita Aug 29, 2025
368a3d3
css
HolaCarmensita Aug 29, 2025
872429f
demo fix
HolaCarmensita Aug 29, 2025
94cf48b
fix: standardize API responses for like and connect operations
HolaCarmensita Aug 29, 2025
2ce6409
removed header on ideapge
HolaCarmensita Aug 29, 2025
37ab141
fixed the header padding onmodal continer
HolaCarmensita Aug 29, 2025
306d17e
added render in netlifyconfig file
HolaCarmensita Aug 29, 2025
b303835
x
HolaCarmensita Aug 29, 2025
ab2d992
merged with demoBranch
HolaCarmensita Aug 29, 2025
97b3f83
some old varbile referns changed back to ideas
HolaCarmensita Aug 29, 2025
ed45c4c
Merge branch 'dev'
HolaCarmensita Aug 29, 2025
413ddcb
tried some esy cirs settings
HolaCarmensita Aug 29, 2025
bebe63d
wrong render url
HolaCarmensita Aug 29, 2025
c5246cb
did a /
HolaCarmensita Aug 29, 2025
267b57c
added netlify in the allowdOrigins
HolaCarmensita Aug 29, 2025
b983d51
timeout longer
HolaCarmensita Aug 29, 2025
6b116b3
100vb
HolaCarmensita Aug 29, 2025
2a32776
cloudinary deltied and css for modal sidebar container done
HolaCarmensita Aug 29, 2025
bef84d8
making idea card more accessible
alex91-html Aug 29, 2025
24ed4a0
delete, edit, unlike size
alex91-html Aug 29, 2025
0813655
accessibility
alex91-html Aug 29, 2025
66b15a2
accessibitliy on profile page
alex91-html Aug 29, 2025
f5b7432
color saturation
alex91-html Aug 29, 2025
32d80c1
Add Cloudinary integration for image uploads
HolaCarmensita Aug 31, 2025
673f6f2
Clean up debugging logs from Cloudinary integration
HolaCarmensita Aug 31, 2025
9254720
README
HolaCarmensita Aug 31, 2025
4bd76eb
Update README.md
HolaCarmensita Aug 31, 2025
5628d05
fixed the lighthouse errors. just H2/h3/4 changes and some labels for…
HolaCarmensita Aug 31, 2025
dfa79a3
Merge branch 'main' of https://github.com/HolaCarmensita/project-final
HolaCarmensita Aug 31, 2025
803f1b2
...
HolaCarmensita Aug 31, 2025
1eaef10
just added padding due to no time to fix the animation/behavior of th…
HolaCarmensita Aug 31, 2025
2e8f7d3
Merge branch 'accessibility'
HolaCarmensita Aug 31, 2025
c993c0d
Update README.md
HolaCarmensita Aug 31, 2025
5ec39ba
AI helped me solve the data issues regardning the login bug and also …
HolaCarmensita Sep 1, 2025
9971fde
Thought it was a bug but it was me deliting ideas manually in the dat…
HolaCarmensita Sep 1, 2025
3fe60f9
delited cvonsole logs
HolaCarmensita Sep 1, 2025
a0918a1
ops! wrong Render url
HolaCarmensita Sep 1, 2025
e451ee0
Fix connection endpoint: handle null/orphaned references in populated…
HolaCarmensita Oct 8, 2025
cef3313
Add detailed logging to diagnose connection endpoint issue
HolaCarmensita Oct 8, 2025
479fa13
Fix: Send connection emails asynchronously to prevent request timeout
HolaCarmensita Oct 8, 2025
c64452a
Clean up debug logs, keept helpful comments
HolaCarmensita Oct 8, 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
58 changes: 52 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,13 +1,59 @@
# Final Project
# Creative Ideas Hub / The Pensive

Replace this readme with your own information about your project.
A collaborative platform where users can share and discover creative ideas in an immersive 3D environment. Connect with ideas and find collaborators for your projects through idea connections.

Start by briefly describing the assignment in a sentence or two. Keep it short and to the point.
OBS!!! MVP mode - header and nav not fixed/animated on mobile, basic scroll behavior. The hidden mobileheader also take room in the desktop, no time to refactor that one.

## The problem
## What it does

Describe how you approached to problem, and what tools and techniques you used to solve it. How did you plan? What technologies did you use? If you had more time, what would be next?
This app lets you:

- Share your creative ideas with text and images
- Browse ideas in a cool 3D space where each idea is a floating orb
- Connect with ideas you're interested in collaborating on
- Receive email notifications when someone connects with your idea
- Get social media links from potential collaborators
- Navigate the 3D world using keyboard, mouse, or touch controls
- Edit and manage your own ideas (under construction)
- View and edit your profile (under construction)

## How we built it

### Frontend (React)

- **React 19** - The main framework for building the user interface
- **Three.js** - For the 3D graphics and interactive scene
- **Zustand** - For managing app state (like user data and ideas)
- **Styled Components** - For styling the app
- **React Router** - For navigation between pages

### Backend (Node.js)

- **Express.js** - The server framework
- **MongoDB** - Database to store users, ideas, and connections
- **JWT** - For user authentication and security
- **Cloudinary** - For storing and managing images
- **Multer** - For handling file uploads

## View it live

Every project should be deployed somewhere. Be sure to include the link to the deployed project so that the viewer can click around and see what it's all about.
- **Frontend**: https://aesthetic-dolphin-63dc60.netlify.app/
- **Backend API**: https://project-final-backend-gq0x.onrender.com

## API Documentation

The backend uses the `express-list-endpoints` library to automatically generate API documentation. You can view all available endpoints at:
https://project-final-backend-gq0x.onrender.com/api-docs

## Future improvements

If we had more time, we'd add:

- BETTER errorhandling
- BETTER Loading States through out the app
- BETTER User Experience
- Well, to be honest, finish the app? Its only at MVP stage
- Real-time chat between users
- More 3D effects and animations
- Idea categories and search
- Video upload support
50 changes: 50 additions & 0 deletions backend/middleware/auth.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import jwt from 'jsonwebtoken';
import User from '../models/User.js';

const JWT_SECRET = process.env.JWT_SECRET || 'your-secret-key';

export const authenticateToken = async (req, res, next) => {
try {
// Get token from header
const authHeader = req.headers['authorization'];
const token = authHeader && authHeader.split(' ')[1]; // Bearer TOKEN

console.log('Auth: Checking token...', {
hasAuthHeader: !!authHeader,
hasToken: !!token,
tokenLength: token ? token.length : 0
});

if (!token) {
return res.status(401).json({ message: 'Access token required' });
}

// Verify token
const decoded = jwt.verify(token, JWT_SECRET);
console.log('Auth: Token decoded successfully', { userId: decoded.userId });

// Find user
const user = await User.findById(decoded.userId).select('-password');

if (!user) {
console.log('Auth: User not found', { userId: decoded.userId });
return res.status(401).json({ message: 'Invalid token' });
}

console.log('Auth: User authenticated successfully', {
userId: user._id,
email: user.email
});

// Add user to request object
req.user = user;
next();
} catch (error) {
console.error('Auth: Token verification failed', error.message);
return res.status(403).json({ message: 'Invalid token' });
}
};

// Default export for convenience
const auth = authenticateToken;
export default auth;
26 changes: 26 additions & 0 deletions backend/middleware/upload.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import multer from 'multer';

// Keep files in memory as Buffer for Cloudinary upload
const storage = multer.memoryStorage();

// File filter to only allow certain file types
const fileFilter = (req, file, cb) => {
// Allow images only
if (file.mimetype.startsWith('image/')) {
cb(null, true);
} else {
cb(new Error('Only image files are allowed!'), false);
}
};

// Configure multer for Cloudinary uploads
const upload = multer({
storage: storage, // Keep in memory for Cloudinary
fileFilter: fileFilter,
limits: {
fileSize: 5 * 1024 * 1024, // 5MB limit
files: 5, // Maximum 5 files per request
},
});

export default upload;
62 changes: 62 additions & 0 deletions backend/models/Idea.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import mongoose from 'mongoose';

const ideaSchema = new mongoose.Schema(
{
title: {
type: String,
required: [true, 'Title is required'],
trim: true,
minlength: [3, 'Title must be at least 3 characters long'],
maxlength: [100, 'Title cannot exceed 100 characters'],
},
description: {
type: String,
required: [true, 'Description is required'],
trim: true,
minlength: [10, 'Description must be at least 10 characters long'],
maxlength: [2000, 'Description cannot exceed 2000 characters'],
},
creator: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
required: [true, 'Creator is required'],
},
likeCount: {
type: Number,
default: 0,
min: 0,
},
connectionCount: {
type: Number,
default: 0,
min: 0,
},
images: [
{
type: String,
trim: true,
},
],
},
{
timestamps: true,
}
);

// Virtual field to get image count
ideaSchema.virtual('imageCount').get(function () {
return this.images.length;
});

// Virtual field to check if idea has images
ideaSchema.virtual('hasImages').get(function () {
return this.images.length > 0;
});

// Ensure virtual fields are serialized
ideaSchema.set('toJSON', { virtuals: true });
ideaSchema.set('toObject', { virtuals: true });

const Idea = mongoose.model('Idea', ideaSchema);

export default Idea;
168 changes: 168 additions & 0 deletions backend/models/User.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
import mongoose from 'mongoose';
import bcrypt from 'bcrypt';

const userSchema = new mongoose.Schema(
{
email: {
type: String,
required: [true, 'Email is required'],
unique: true,
lowercase: true,
trim: true,
match: [
/^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$/,
'Please enter a valid email',
],
},
password: {
type: String,
required: [true, 'Password is required'],
minlength: [6, 'Password must be at least 6 characters long'],
},
firstName: {
type: String,
required: [true, 'First name is required'],
trim: true,
minlength: [2, 'First name must be at least 2 characters long'],
maxlength: [50, 'First name cannot exceed 50 characters'],
},
lastName: {
type: String,
required: [true, 'Last name is required'],
trim: true,
minlength: [2, 'Last name must be at least 2 characters long'],
maxlength: [50, 'Last name cannot exceed 50 characters'],
},
role: {
type: String,
default: 'creative mind',
trim: true,
maxlength: [100, 'Role cannot exceed 100 characters'],
},
description: {
type: String,
trim: true,
maxlength: [500, 'Description cannot exceed 500 characters'],
},
link: {
type: String,
trim: true,
maxlength: [200, 'Link cannot exceed 200 characters'],
},
likedIdeas: [
{
type: mongoose.Schema.Types.ObjectId,
ref: 'Idea',
},
],
connectedIdeas: [
{
idea: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Idea',
},
message: {
type: String,
required: true,
maxlength: [500, 'Connection message cannot exceed 500 characters'],
},
socialLink: {
type: String,
trim: true,
maxlength: [200, 'Social link cannot exceed 200 characters'],
},
connectedAt: {
type: Date,
default: Date.now,
},
},
],
receivedConnections: [
{
idea: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Idea',
},
connectedBy: {
type: mongoose.Schema.Types.ObjectId,
ref: 'User',
},
message: {
type: String,
required: true,
maxlength: [500, 'Connection message cannot exceed 500 characters'],
},
socialLink: {
type: String,
trim: true,
maxlength: [200, 'Social link cannot exceed 200 characters'],
},
connectedAt: {
type: Date,
default: Date.now,
},
},
],
},
{
timestamps: true,
}
);

// Virtual field to get full name
userSchema.virtual('fullName').get(function () {
return `${this.firstName} ${this.lastName}`;
});

// Virtual field to get like count
userSchema.virtual('likeCount').get(function () {
return this.likedIdeas ? this.likedIdeas.length : 0;
});

// Virtual field to get connection count (ideas I connected to)
userSchema.virtual('connectionCount').get(function () {
return this.connectedIdeas ? this.connectedIdeas.length : 0;
});

// Virtual field to get received connections count (people who connected to my ideas)
userSchema.virtual('receivedConnectionCount').get(function () {
return this.receivedConnections ? this.receivedConnections.length : 0;
});

// Virtual field to check if user has description
userSchema.virtual('hasDescription').get(function () {
return this.description && this.description.trim().length > 0;
});

// Virtual field to check if user has link
userSchema.virtual('hasLink').get(function () {
return this.link && this.link.trim().length > 0;
});

// Ensure virtual fields are serialized
userSchema.set('toJSON', { virtuals: true });
userSchema.set('toObject', { virtuals: true });

// Hash password before saving
userSchema.pre('save', async function (next) {
// Only hash the password if it has been modified (or is new)
if (!this.isModified('password')) return next();

try {
// Hash password with salt rounds of 10
const hashedPassword = await bcrypt.hash(this.password, 10);
this.password = hashedPassword;
next();
} catch (error) {
next(error);
}
});

// Method to compare password for login
userSchema.methods.comparePassword = async function (candidatePassword) {
return bcrypt.compare(candidatePassword, this.password);
};

const User = mongoose.model('User', userSchema);

export default User;
11 changes: 10 additions & 1 deletion backend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,18 @@
"@babel/core": "^7.17.9",
"@babel/node": "^7.16.8",
"@babel/preset-env": "^7.16.11",
"bcrypt": "^5.1.0",
"cloudinary": "^2.7.0",
"cors": "^2.8.5",
"dotenv": "^16.0.3",
"express": "^4.17.3",
"express-list-endpoints": "^6.0.0",
"express-validator": "^7.0.1",
"jsonwebtoken": "^9.0.0",
"mongodb": "^6.18.0",
"mongoose": "^8.4.0",
"multer": "^2.0.2",
"nodemailer": "^7.0.5",
"nodemon": "^3.0.1"
}
}
}
Loading