-
Notifications
You must be signed in to change notification settings - Fork 30
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #123 from protob/template/vue-express-fullstack
feat:[TEMPLATE] - Vue + Express - FullStack #96
- Loading branch information
Showing
34 changed files
with
1,155 additions
and
0 deletions.
There are no files selected for viewing
133 changes: 133 additions & 0 deletions
133
template/FullStack/Vue(Frontend)+Express(Backend)/README.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,133 @@ | ||
# FullStack Template: Vue.js + Express.js | ||
|
||
This repository provides a simple FullStack template for building modern web applications using **Vue.js** for the frontend and **Express.js** for the backend. It includes essential features such as user authentication, session management, and an user interface. | ||
|
||
## Features | ||
|
||
- **User Authentication**: Supports user registration and login with session management using JWT. | ||
- **Frontend**: Built with Vue.js, offering a dynamic and responsive user interface. | ||
- **Backend**: Powered by Express.js with Node.js, providing a robust RESTful API. | ||
- **Session Management**: Utilizes JSON Web Tokens (JWT) to manage user authentication. | ||
|
||
## Technologies Used | ||
|
||
### Frontend | ||
|
||
- **Vue.js 3**: A progressive JavaScript framework for building user interfaces, using the Composition API. | ||
- **Vue Router**: Handles navigation and routing in the application. | ||
- **Pinia**: State management library for Vue.js applications. | ||
- **Tailwind CSS**: Utility-first CSS framework for rapid UI development. | ||
- **Vue Toastification**: For displaying toast notifications. | ||
- **@vueuse/motion**: For improved animation experience. | ||
|
||
### Backend | ||
|
||
- **Node.js**: A JavaScript runtime built on Chrome's V8 JavaScript engine. | ||
- **Express.js**: A minimal and flexible Node.js web application framework. | ||
- **MongoDB**: A NoSQL database known for its flexibility and scalability. | ||
- **Mongoose**: An elegant MongoDB object modeling for Node.js. | ||
|
||
## Installation | ||
|
||
### Prerequisites | ||
|
||
- **Node.js**: Ensure you have Node.js installed. You can download it from [here](https://nodejs.org/). | ||
- **MongoDB**: Make sure MongoDB is installed and running locally or accessible remotely. | ||
|
||
### Steps | ||
|
||
1. **Populate the `.env.example` File**: | ||
|
||
```bash | ||
# server/.env | ||
MONGO_URL=<YOUR_MONGODB_CONNECTION_STRING> | ||
JWT_SECRET=<YOUR_JWT_SECRET_KEY> | ||
PORT=3000 | ||
``` | ||
|
||
2. **Install the Required Dependencies**: | ||
|
||
```bash | ||
cd client && npm install | ||
cd server && npm install | ||
``` | ||
|
||
3. **Ensure MongoDB is Running**: | ||
- Make sure your MongoDB server is running locally or accessible remotely. | ||
|
||
4. **Run the Application**: | ||
|
||
```bash | ||
# both client and server | ||
npm run dev | ||
``` | ||
|
||
5. **Access the Application**: | ||
|
||
Visit `http://localhost:5173/` in your web browser. | ||
|
||
## Routes and Functionalities | ||
|
||
- **`/api/auth/signup` [POST]**: | ||
- Handles user registration. | ||
- **Request Body**: | ||
- `username`: String | ||
- `emailid`: String | ||
- `password`: String | ||
|
||
|
||
- **`/api/auth/signin` [POST]**: | ||
- **Description**: Handles user login. | ||
- **Request Body**: | ||
- `emailid`: String | ||
- `password`: String | ||
|
||
- **`/api/user/signout` [POST]**: | ||
- Logs the user out by clearing the authentication cookie. | ||
- **`/api/user/test` [GET]**: | ||
- **Description**: Test route to verify API is working. | ||
|
||
- **`/api/user/profile` [GET]**: | ||
- **Description**: Retrieves the user profile information of the authenticated user. | ||
- **Response**: | ||
- **Success**: Returns user profile details such as `id`, `username`, and `emailid`. | ||
- **Error**: Returns an error if the user is not authenticated. | ||
|
||
|
||
|
||
### Frontend Routes | ||
|
||
- **`/` [GET]**: | ||
- **Description**: Renders the homepage of the application. | ||
|
||
- **`/signin` [GET]**: | ||
- Renders the login page where users can log in with their credentials. | ||
|
||
- **`/signup` [GET]**: | ||
- Renders the registration page where new users can sign up. | ||
|
||
## Flash Messages | ||
|
||
The application uses flash messages to communicate the following events to the user: | ||
|
||
- **Signup**: | ||
- **Success**: "Signup successful! Please sign in." | ||
- **Error**: "Username or Email already exists. Please choose a different one." | ||
|
||
- **Signin**: | ||
- **Error**: "Invalid email or password. Please try again." | ||
|
||
These messages are displayed on the frontend in the registration and login pages using toast notifications. | ||
|
||
## Database | ||
|
||
The application uses **MongoDB** for storing user information. The `users` collection in the MongoDB database contains the following fields for each user: | ||
|
||
- **_id**: `ObjectId`, the unique identifier for each document (user). | ||
- **username**: `String`, unique, cannot be null. | ||
- **emailid**: `String`, unique, cannot be null. | ||
- **password**: `String`, hashed, cannot be null. | ||
|
||
--- | ||
|
||
Made using [Universal-Box](https://github.com/Abhishek-Mallick/universal-box) |
1 change: 1 addition & 0 deletions
1
template/FullStack/Vue(Frontend)+Express(Backend)/client/.env.example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
VITE_BASE_URL=http://localhost:PORT |
13 changes: 13 additions & 0 deletions
13
template/FullStack/Vue(Frontend)+Express(Backend)/client/index.html
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<!doctype html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8" /> | ||
<link rel="icon" type="image/svg+xml" href="/vite.svg" /> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | ||
<title>Vite + Vue</title> | ||
</head> | ||
<body> | ||
<div id="app"></div> | ||
<script type="module" src="/src/main.js"></script> | ||
</body> | ||
</html> |
29 changes: 29 additions & 0 deletions
29
template/FullStack/Vue(Frontend)+Express(Backend)/client/package.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
{ | ||
"name": "vue-frontend", | ||
"version": "1.0.0", | ||
"private": true, | ||
"type": "module", | ||
"scripts": { | ||
"dev": "vite", | ||
"build": "vite build", | ||
"serve": "vite preview", | ||
"lint": "eslint ." | ||
}, | ||
"dependencies": { | ||
"@vueuse/motion": "^2.2.5", | ||
"axios": "^1.4.0", | ||
"pinia": "^2.1.0", | ||
"pinia-plugin-persistedstate": "^4.1.1", | ||
"vue": "^3.3.4", | ||
"vue-router": "^4.2.3", | ||
"vue-toastification": "next" | ||
}, | ||
"devDependencies": { | ||
"@vitejs/plugin-vue": "^5.1.4", | ||
"vite": "^5.4.8", | ||
"autoprefixer": "^10.4.7", | ||
"eslint": "^8.28.0", | ||
"postcss": "^8.4.14", | ||
"tailwindcss": "^3.4.10" | ||
} | ||
} |
6 changes: 6 additions & 0 deletions
6
template/FullStack/Vue(Frontend)+Express(Backend)/client/postcss.config.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
module.exports = { | ||
plugins: { | ||
tailwindcss: {}, | ||
autoprefixer: {}, | ||
}, | ||
} |
Binary file added
BIN
+25.8 KB
template/FullStack/Vue(Frontend)+Express(Backend)/client/public/logo.webp
Binary file not shown.
21 changes: 21 additions & 0 deletions
21
template/FullStack/Vue(Frontend)+Express(Backend)/client/src/App.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
<template> | ||
<div class="flex flex-col min-h-screen min-w-[320px]"> | ||
<Header /> | ||
<main class="flex-grow flex items-center justify-center"> | ||
<router-view class="w-full" /> | ||
</main> | ||
<Footer /> | ||
</div> | ||
</template> | ||
|
||
<script setup> | ||
import Header from './components/Header.vue' | ||
import Footer from './components/Footer.vue' | ||
</script> | ||
|
||
<style> | ||
body, html { | ||
height: 100%; | ||
margin: 0; | ||
} | ||
</style> |
23 changes: 23 additions & 0 deletions
23
template/FullStack/Vue(Frontend)+Express(Backend)/client/src/api.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import axios from 'axios' | ||
const baseURL = import.meta.env.VITE_BASE_URL || 'http://localhost:3000' | ||
|
||
const api = axios.create({ | ||
baseURL, | ||
withCredentials: true, // Ensure credentials/cookies are sent with cross-origin requests | ||
}) | ||
|
||
// Set up a response interceptor to handle errors globally | ||
api.interceptors.response.use( | ||
(response) => response, // return the response if no errors | ||
|
||
(error) => { | ||
// Check and reject 401 (Unauthorized) error | ||
if (error.response && error.response.status === 401) { | ||
return Promise.reject(error) | ||
} | ||
console.error('API Error:', error) | ||
return Promise.reject(error) | ||
} | ||
) | ||
|
||
export default api |
42 changes: 42 additions & 0 deletions
42
template/FullStack/Vue(Frontend)+Express(Backend)/client/src/components/Cards.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
<template> | ||
<div class="max-w-5xl mx-auto px-0 xs:px-8"> | ||
<CardsListingHover :items="projects" /> | ||
</div> | ||
</template> | ||
|
||
<script setup> | ||
import CardsListingHover from './CardsListingHover.vue' | ||
const projects = [ | ||
{ | ||
title: "Stripe", | ||
description: "A technology company that builds economic infrastructure for the internet.", | ||
link: "stripe.com", | ||
}, | ||
{ | ||
title: "Netflix", | ||
description: "A streaming service that offers a wide variety of award-winning TV shows, movies, anime, documentaries, and more on thousands of internet-connected devices.", | ||
link: "netflix.com", | ||
}, | ||
{ | ||
title: "Google", | ||
description: "A multinational technology company that specializes in Internet-related services and products.", | ||
link: "google.com", | ||
}, | ||
{ | ||
title: "Meta", | ||
description: "A technology company that focuses on building products that advance Facebook's mission of bringing the world closer together.", | ||
link: "meta.com", | ||
}, | ||
{ | ||
title: "Amazon", | ||
description: "A multinational technology company focusing on e-commerce, cloud computing, digital streaming, and artificial intelligence.", | ||
link: "amazon.com", | ||
}, | ||
{ | ||
title: "Microsoft", | ||
description: "A multinational technology company that develops, manufactures, licenses, supports, and sells computer software, consumer electronics, personal computers, and related services.", | ||
link: "microsoft.com", | ||
}, | ||
] | ||
</script> |
83 changes: 83 additions & 0 deletions
83
...late/FullStack/Vue(Frontend)+Express(Backend)/client/src/components/CardsListingHover.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
<template> | ||
<div class="max-w-5xl mx-auto md:px-8"> | ||
<div :class="['grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 py-10 cursor-pointer', className]"> | ||
<div | ||
v-for="(item, idx) in items" | ||
:key="item.link" | ||
class="relative group block p-2 h-full w-full" | ||
@mouseenter="setHoveredIndex(idx)" | ||
@mouseleave="setHoveredIndex(null)" | ||
@click="navigate(item.link)" | ||
> | ||
<div | ||
v-motion | ||
:initial="{ opacity: 0, scale: 0.95 }" | ||
:enter="{ | ||
opacity: 1, | ||
scale: .99, | ||
transition: { | ||
type: 'spring', | ||
stiffness: 300, | ||
damping: 30, | ||
opacity: { duration: 0.2 } | ||
} | ||
}" | ||
:leave="{ | ||
opacity: 0, | ||
scale: 0.95, | ||
transition: { | ||
type: 'spring', | ||
stiffness: 300, | ||
damping: 30, | ||
opacity: { duration: 0.2 } | ||
} | ||
}" | ||
:style="{ | ||
position: 'absolute', | ||
inset: '-5px', | ||
zIndex: 0, | ||
pointerEvents: 'none' | ||
}" | ||
class="bg-neutral-200 dark:bg-slate-800/[0.8] rounded-3xl" | ||
v-if="hoveredIndex === idx" | ||
></div> | ||
<div class="rounded-2xl h-full w-full p-4 overflow-hidden bg-black border border-transparent dark:border-white/[0.2] relative z-10"> | ||
<div class="p-4"> | ||
<h4 class="text-zinc-100 font-bold tracking-[1px] mt-4 uppercase text-center"> | ||
{{ item.title }} | ||
</h4> | ||
<p class="mt-8 text-zinc-400 tracking-wide leading-relaxed text-sm text-center"> | ||
{{ item.description }} | ||
</p> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</div> | ||
</template> | ||
|
||
<script setup> | ||
import { ref } from 'vue' | ||
const props = defineProps({ | ||
items: { | ||
type: Array, | ||
required: true | ||
}, | ||
className: { | ||
type: String, | ||
default: '' | ||
} | ||
}) | ||
const hoveredIndex = ref(null) | ||
const setHoveredIndex = (idx) => { | ||
hoveredIndex.value = idx | ||
} | ||
const navigate = (link) => { | ||
const url = link.startsWith('https://') ? link : `https://${link}` | ||
window.open(url, '_blank', 'noopener,noreferrer') | ||
} | ||
</script> |
13 changes: 13 additions & 0 deletions
13
template/FullStack/Vue(Frontend)+Express(Backend)/client/src/components/Footer.vue
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
<template> | ||
<footer class="bg-gray-100 p-5 flex justify-center items-center"> | ||
<div class="flex items-center gap-2"> | ||
<p class="text-sm text-gray-600">© 2024 Universal-Box</p> | ||
</div> | ||
</footer> | ||
</template> | ||
|
||
<script> | ||
export default { | ||
name: 'Footer' | ||
} | ||
</script> |
Oops, something went wrong.