SyncSpace is a responsive single-page web application designed to help users find a moment of balance between inner peace and the digital world. It provides a suite of mindfulness tools—including a guided breathing exercise, a mood tracker, and a mindfulness journal—alongside a feed of the latest tech news and motivational quotes.
This project was developed as a submission for the Team Envision club at SRMIST. The initial task was to create a simple single-page website with animations. However, I saw an opportunity to go beyond the basic requirements and build a product with a real purpose: to create a tool that I and others could use to stay centered while staying connected.
Live Site: https://syncspace-app.vercel.app/
SyncSpace is packed with features designed to be both functional and delightful to use.
- 🧘 Mindful Minute: A guided 1-minute breathing exercise with calming animations and optional ambient sound.
- 💡 Quote of the Minute: Fetches random motivational quotes from a live API, with caching for performance.
- 😊 Mood Tracker & Journal: Log your daily mood with emojis and write a corresponding journal entry. All data is saved to your browser's local storage.
- 📰 Tech News Feed: A Tinder-style swipable card stack of the latest technology news.
- ⭐ Favorites Page: Save your favorite quotes and news articles to a dedicated page to revisit them later.
- 📖 Journal Page: View and manage all your past mindfulness journal entries.
- 🎨 Dynamic 3D Background: An animated particle system built with three.js that represents the balance between the calm of inner peace and the structure of the digital world.
- 📱 Fully Responsive Design: A seamless experience on all devices, with a dedicated multi-page layout and animated navigation for mobile.
- 🌗 Light & Dark Mode: A sleek, themeable interface that respects user preferences.
- ⚡ High Performance: Utilizes API caching, skeleton loaders, and lazy loading for a fast and smooth experience.
- 👆 Haptic Feedback: Subtle vibrations on interactive elements for a more tactile experience on supported mobile devices.
This project uses a modern, professional frontend stack.
- Framework: ReactJS (with Vite)
- Styling: Tailwind CSS
- Animation: Framer Motion, React Type Animation, SwiperJS
- 3D Graphics: Three.js, React Three Fiber, React Three Drei
- Icons: Lucide React
- APIs:
- Local Storage: Browser localStorage for persisting mood data, journal entries, and favorites
The objective was to create a simple single-page website, but I saw it as an opportunity to build a product that solves a real problem for students and professionals: the difficulty of staying mindful in a hyper-connected world. The name SyncSpace was chosen to reflect this core idea: a digital space to synchronize your inner state with the external world.
The design is inspired by the "liquid glass" aesthetic of modern interfaces like macOS and Samsung's OneUI. This meant using:
backdrop-blurand semi-transparent backgrounds to create a sense of depth- Generous padding and rounded corners (
rounded-full,rounded-3xl) for a soft, friendly feel - Framer Motion was chosen for all UI animations. The alternative was simple CSS transitions, but Framer Motion's
layoutIdfeature was essential for creating the beautiful, seamless "sliding pill" animation in both the desktop and mobile navigation bars - SwiperJS was selected for the news feed specifically for its "cards" effect, which provides an intuitive, mobile-friendly way to browse content
I started with a single component and refactored it into a modular, component-based architecture. This separation of concerns is crucial for scalability and maintainability.
/src
├── /assets
├── /components
│ ├── Clock.jsx
│ ├── DynamicBackground.jsx
│ ├── Favorites.jsx
│ ├── Footer.jsx
│ ├── Header.jsx
│ ├── Journal.jsx
│ ├── Loader.jsx
│ ├── MindfulMinute.jsx
│ ├── MobileMenu.jsx
│ ├── MoodTracker.jsx
│ ├── NewsSection.jsx
│ ├── NewsSkeleton.jsx
│ └── QuoteSkeleton.jsx
├── /constants
│ └── data.js
├── /hooks
│ ├── useCachedFetch.js
│ ├── useDarkMode.js
│ ├── useHapticFeedback.js
│ ├── useIsMobile.js
│ ├── useLocalStorage.js
│ └── useScrollSpy.js
└── App.jsx
Instead of keeping all logic in App.jsx, I created custom hooks to manage distinct pieces of functionality. This is a more advanced approach that leads to cleaner, more reusable code.
useDarkMode.js: Encapsulates all logic for toggling the theme and saving the user's preference to localStorageuseIsMobile.js: Centralizes the logic for checking screen size, enabling the switch between desktop and mobile layoutsuseScrollSpy.js: Solves the problem of the navbar not updating on manual scroll- Alternative Approach: Listening directly to the
window.onscrollevent. I rejected this because it can be performance-intensive, as the event fires hundreds of times during a scroll - Chosen Approach: I implemented the modern Intersection Observer API. This is far more efficient as the browser handles the detection, and I wrapped this logic in a custom hook to keep
App.jsxclean
- Alternative Approach: Listening directly to the
useLocalStorage.js: Creates a reusable hook that syncs a React state variable with localStorage, which is used for both Favorites and the JournaluseCachedFetch.js: Manages API caching to improve performance and reduce API calls
For fetching data, I chose free and reliable APIs. A critical decision was how to handle the news API key.
- Alternative Approach: The simplest way is to hardcode the key directly in
NewsSection.jsx. However, this is a major security risk, as the key would be exposed if the code were ever pushed to a public GitHub repository - Chosen Approach: I used a
.envfile to store the API key as an environment variable. Vite automatically makes variables prefixed withVITE_available in theimport.meta.envobject. I then added.envto the.gitignorefile. This is the industry-standard method for keeping secrets secure
This flowchart illustrates how a user interacts with the application and how the core components and hooks work together to manage state and render the UI.
graph TD
subgraph "User Interaction"
A[User Loads App] --> B{isLoading?};
B -- Yes --> C[Show Loader];
C --> D{Timer Finishes};
D -- Yes --> E[Show Main App];
B -- No --> E;
E --> F[User Clicks Nav Item];
F --> G[handleNavClick];
G --> H{isMobile?};
H -- Yes --> I[Update Active Page State];
H -- No --> J[Set 'isScrolling' Flag to True];
J --> I;
E --> K[User Scrolls on Desktop];
K --> L[useScrollSpy Hook Detects Section];
L --> M{isScrolling Flag is False?};
M -- Yes --> I;
M -- No --> O[Do Nothing];
end
subgraph "State Management (App.jsx)"
I --> P[State: activePage];
P --> Q[Render Correct Component];
Q --> R[UI Updates in Header & Main Content];
end
subgraph "Data & Hooks"
S[useDarkMode] --> T[localStorage];
T --> R;
U[useLocalStorage] --> V[localStorage];
V --> W[Favorites & Journal Data];
W --> Q;
X[useCachedFetch] --> Y[localStorage & External APIs];
Y --> Z[News & Quote Data];
Z --> Q;
end
This diagram shows the overall architecture of the SyncSpace application, detailing the relationship between the main App.jsx component, its children, the custom hooks, and external services.
graph TD
subgraph "External Services"
API1[GNews API]
API2[DummyJSON API]
LS[Browser localStorage]
end
subgraph "Custom Hooks (Logic Layer)"
H_Cache[useCachedFetch]
H_Local[useLocalStorage]
H_Dark[useDarkMode]
H_Mobile[useIsMobile]
H_Spy[useScrollSpy]
H_Haptic[useHapticFeedback]
end
subgraph "React Application (UI Layer)"
App["App.jsx<br>(Manages all state)"]
subgraph "Layout Components"
Header[Header.jsx]
MobileMenu[MobileMenu.jsx]
Footer[Footer.jsx]
end
subgraph "Feature Components (Lazy Loaded)"
Mindful[MindfulMinute.jsx]
Quote[QuoteSection.jsx]
Mood[MoodTracker.jsx]
News[NewsSection.jsx]
Favorites[Favorites.jsx]
Journal[Journal.jsx]
end
end
%% --- Connections ---
%% App to Layout
App -- "Props (activePage, darkMode, etc.)" --> Header;
App -- "Props (activePage, darkMode, etc.)" --> MobileMenu;
App -- "Props (darkMode)" --> Footer;
%% App to Features
App --> Mindful;
App --> Quote;
App --> Mood;
App --> News;
App --> Favorites;
App --> Journal;
%% Hooks to App/Components
H_Dark --> App;
H_Mobile --> App;
H_Spy --> App;
H_Local --> Favorites;
H_Local --> Journal;
H_Local --> Mood;
H_Cache --> Quote;
H_Cache --> News;
H_Haptic -- "Used by most components" --> App;
%% Data Sources to Hooks
API1 --> H_Cache;
API2 --> H_Cache;
LS --> H_Dark;
LS --> H_Local;
LS --> H_Cache;
To run this project locally, follow these steps:
-
Clone the repository:
git clone https://https://github.com/mdnm18/syncspace-app.git cd syncspace-app -
Install dependencies:
npm install
-
Set up your API key:
- Create a new file in the root of the project named
.env - Get a free API key from GNews.io
- Add your key to the
.envfile:VITE_GNEWS_API_KEY="YOUR_API_KEY_HERE"
- Create a new file in the root of the project named
-
Run the development server:
npm run dev
-
The application will be available at
http://localhost:5173
Thank you for reviewing my submission!
Md Nayaj Mondal
- GitHub: @mdnm18
- LinkedIn: Md Nayaj Mondal
⭐ If you found this project helpful, please give it a star!