-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e6d08d1
commit a4cd234
Showing
19 changed files
with
8,576 additions
and
47 deletions.
There are no files selected for viewing
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,36 @@ | ||
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files. | ||
|
||
# dependencies | ||
/node_modules | ||
/.pnp | ||
.pnp.js | ||
|
||
# testing | ||
/coverage | ||
|
||
# next.js | ||
/.next/ | ||
/out/ | ||
|
||
# production | ||
/build | ||
|
||
# misc | ||
.DS_Store | ||
*.pem | ||
|
||
# debug | ||
npm-debug.log* | ||
yarn-debug.log* | ||
yarn-error.log* | ||
|
||
# local env files | ||
.env*.local | ||
|
||
# vercel | ||
.vercel | ||
|
||
# typescript | ||
*.tsbuildinfo | ||
next-env.d.ts | ||
__pycache__ |
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 |
---|---|---|
@@ -1,77 +1,78 @@ | ||
# Nodejs Sailjs web application | ||
<p align="center"> | ||
<a href="https://nextjs-flask-starter.vercel.app/"> | ||
<img src="https://assets.vercel.com/image/upload/v1588805858/repositories/vercel/logo.png" height="96"> | ||
<h3 align="center">Next.js Flask Starter</h3> | ||
</a> | ||
</p> | ||
|
||
Sample Nodejs Sailjs web application built on [visual studio code](https://code.visualstudio.com/). | ||
<p align="center">Simple Next.js boilerplate that uses <a href="https://flask.palletsprojects.com/">Flask</a> as the API backend.</p> | ||
|
||
Language| Framework | Runtime | Platform | Author | | ||
| --------| -------- | -------- |--------|--------| | ||
javascript| Sailjs | node | Azure Web App| | | ||
<br/> | ||
|
||
## Installation | ||
## Introduction | ||
|
||
For development, you will need Node.js and a node global package | ||
This is a hybrid Next.js + Python app that uses Next.js as the frontend and Flask as the API backend. One great use case of this is to write Next.js apps that use Python AI libraries on the backend. | ||
|
||
### Node | ||
- #### Node installation on Windows | ||
## How It Works | ||
|
||
Just go on [official Node.js website](https://nodejs.org/) and download the installer. | ||
Also, be sure to have `git` available in your PATH, `npm` might need it (You can find git [here](https://git-scm.com/)). | ||
The Python/Flask server is mapped into to Next.js app under `/api/`. | ||
|
||
- #### Node installation on Ubuntu | ||
This is implemented using [`next.config.js` rewrites](https://github.com/vercel/examples/blob/main/python/nextjs-flask/next.config.js) to map any request to `/api/:path*` to the Flask API, which is hosted in the `/api` folder. | ||
|
||
You can install nodejs and npm easily with apt install, just run the following commands. | ||
On localhost, the rewrite will be made to the `127.0.0.1:5328` port, which is where the Flask server is running. | ||
|
||
$ sudo apt install nodejs | ||
$ sudo apt install npm | ||
In production, the Flask server is hosted as [Python serverless functions](https://vercel.com/docs/concepts/functions/serverless-functions/runtimes/python) on Vercel. | ||
|
||
- #### Other Operating Systems | ||
You can find more information about the installation on the [official Node.js website](https://nodejs.org/) and the [official NPM website](https://npmjs.org/). | ||
## Demo | ||
|
||
If the installation was successful, you should be able to run the following command. | ||
https://nextjs-flask-starter.vercel.app/ | ||
|
||
$ node --version | ||
v8.11.3 | ||
## Deploy Your Own | ||
|
||
$ npm --version | ||
6.1.0 | ||
You can clone & deploy it to Vercel with one click: | ||
|
||
If you need to update `npm`, you can make it using `npm`! Cool right? After running the following command, just open again the command line and be happy. | ||
[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/clone?demo-title=Next.js%20Flask%20Starter&demo-description=Simple%20Next.js%20boilerplate%20that%20uses%20Flask%20as%20the%20API%20backend.&demo-url=https%3A%2F%2Fnextjs-flask-starter.vercel.app%2F&demo-image=%2F%2Fimages.ctfassets.net%2Fe5382hct74si%2F795TzKM3irWu6KBCUPpPz%2F44e0c6622097b1eea9b48f732bf75d08%2FCleanShot_2023-05-23_at_12.02.15.png&project-name=Next.js%20Flask%20Starter&repository-name=nextjs-flask-starter&repository-url=https%3A%2F%2Fgithub.com%2Fvercel%2Fexamples%2Ftree%2Fmain%2Fpython%2Fnextjs-flask&from=vercel-examples-repo) | ||
|
||
$ npm install npm -g | ||
## Developing Locally | ||
|
||
## Running | ||
|
||
- #### Clone this repository | ||
You can clone & create this repo with the following command | ||
|
||
```bash | ||
$ git clone https://github.com/YOUR_USERNAME/REPOSITORY_NAME.git | ||
npx create-next-app nextjs-flask --example "https://github.com/vercel/examples/tree/main/python/nextjs-flask" | ||
``` | ||
|
||
- #### Install dependencies | ||
```bash | ||
$ cd Application | ||
$ npm install -g | ||
``` | ||
- #### Run Application | ||
## Getting Started | ||
|
||
First, install the dependencies: | ||
|
||
```bash | ||
$ cd Application | ||
$ npm start | ||
npm install | ||
# or | ||
yarn | ||
# or | ||
pnpm install | ||
``` | ||
- #### Running tests | ||
|
||
Then, run the development server: | ||
|
||
```bash | ||
$ cd Tests | ||
$ npm install -g | ||
$ npm test | ||
npm run dev | ||
# or | ||
yarn dev | ||
# or | ||
pnpm dev | ||
``` | ||
|
||
## Deploying on Azure | ||
|
||
Any change to this repository will result in triggering a workflow to build and deploy this app on azure as an app service. Learn more about [Azure App Service](https://docs.microsoft.com/en-us/azure/app-service/) and [Github Actions](https://docs.github.com/en/actions). | ||
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result. | ||
|
||
## Contributing | ||
The Flask server will be running on [http://127.0.0.1:5328](http://127.0.0.1:5328) – feel free to change the port in `package.json` (you'll also need to update it in `next.config.js`). | ||
|
||
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [[email protected]](mailto:[email protected]) with any additional questions or comments. | ||
## Learn More | ||
|
||
To learn more about Next.js, take a look at the following resources: | ||
|
||
## License: | ||
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API. | ||
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial. | ||
- [Flask Documentation](https://flask.palletsprojects.com/en/1.1.x/) - learn about Flask features and API. | ||
|
||
See [LICENSE](LICENSE). | ||
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome! |
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,75 @@ | ||
from flask import Flask, request, render_template, send_file | ||
import os | ||
from datetime import datetime, timedelta | ||
from ics import Calendar, Event | ||
|
||
app = Flask(__name__) | ||
|
||
calendar = Calendar() | ||
event_count = {} | ||
|
||
@app.route('/', methods=['GET']) | ||
def index(): | ||
return render_template('index.html') | ||
|
||
@app.route('/add_event', methods=['POST']) | ||
def add_event(): | ||
day = request.form['day'] | ||
time = request.form['time'] | ||
name = request.form['name'] | ||
duration = request.form['duration'] | ||
notes = request.form['notes'] | ||
all_day = request.form['all_day'] | ||
|
||
duration = int(duration) | ||
start_date = get_next_day_date(day) | ||
|
||
add_event_to_ics(name, f"{start_date} {time}:00", duration, notes, all_day) | ||
return "Event added successfully!" | ||
|
||
@app.route('/save_to_file', methods=['POST']) | ||
def save_to_file(): | ||
date_str = datetime.today().strftime('%Y-%m-%d') | ||
if date_str not in event_count: | ||
event_count[date_str] = 0 | ||
event_count[date_str] += 1 | ||
filename = f"{date_str}_event_{event_count[date_str]}.ics" | ||
folder_path = "ics_files" | ||
os.makedirs(folder_path, exist_ok=True) | ||
file_path = os.path.join(folder_path, filename) | ||
with open(file_path, 'w') as f: | ||
f.writelines(calendar) | ||
return send_file(file_path, as_attachment=True, download_name=filename) | ||
|
||
def get_next_day_date(day_name): | ||
today = datetime.today() | ||
days_of_week = ['monday', 'tuesday', 'wednesday', 'thursday', 'friday', 'saturday', 'sunday'] | ||
day_name = day_name.lower() | ||
if day_name not in days_of_week: | ||
raise ValueError("Invalid day of the week.") | ||
today_weekday = today.weekday() | ||
target_weekday = days_of_week.index(day_name) | ||
days_ahead = (target_weekday - today_weekday + 7) % 7 | ||
if days_ahead == 0: | ||
days_ahead = 7 | ||
next_day_date = today + timedelta(days=days_ahead) | ||
return next_day_date.strftime('%Y-%m-%d') | ||
|
||
def add_event_to_ics(event_name, start_time_str, duration_hours, notes, all_day): | ||
start_time = datetime.strptime(start_time_str, '%Y-%m-%d %H:%M:%S') | ||
if all_day == 'yes': | ||
end_time = start_time + timedelta(days=1) | ||
else: | ||
end_time = start_time + timedelta(hours=duration_hours) | ||
|
||
event = Event() | ||
event.name = event_name | ||
event.begin = start_time | ||
event.end = end_time | ||
event.description = notes | ||
event.transparent = (all_day == 'yes') | ||
|
||
calendar.events.add(event) | ||
|
||
if __name__ == '__main__': | ||
app.run(debug=True) |
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,67 @@ | ||
// app/components/EventForm.js | ||
import React, { useState } from 'react'; | ||
|
||
const EventForm = ({ onSubmit }) => { | ||
const [formData, setFormData] = useState({ | ||
day: '', | ||
time: '', | ||
name: '', | ||
duration: '', | ||
notes: '', | ||
all_day: 'no', | ||
}); | ||
|
||
const handleChange = (e) => { | ||
const { name, value } = e.target; | ||
setFormData((prevData) => ({ | ||
...prevData, | ||
[name]: value, | ||
})); | ||
}; | ||
|
||
const handleSubmit = (e) => { | ||
e.preventDefault(); | ||
onSubmit(formData); | ||
}; | ||
|
||
return ( | ||
<form onSubmit={handleSubmit}> | ||
<label> | ||
Day: | ||
<input type="text" name="day" value={formData.day} onChange={handleChange} /> | ||
</label> | ||
<br /> | ||
<label> | ||
Time: | ||
<input type="time" name="time" value={formData.time} onChange={handleChange} /> | ||
</label> | ||
<br /> | ||
<label> | ||
Event Name: | ||
<input type="text" name="name" value={formData.name} onChange={handleChange} /> | ||
</label> | ||
<br /> | ||
<label> | ||
Duration (hours): | ||
<input type="number" name="duration" value={formData.duration} onChange={handleChange} /> | ||
</label> | ||
<br /> | ||
<label> | ||
Notes: | ||
<textarea name="notes" value={formData.notes} onChange={handleChange} /> | ||
</label> | ||
<br /> | ||
<label> | ||
All-day Event: | ||
<select name="all_day" value={formData.all_day} onChange={handleChange}> | ||
<option value="yes">Yes</option> | ||
<option value="no">No</option> | ||
</select> | ||
</label> | ||
<br /> | ||
<button type="submit">Add Event</button> | ||
</form> | ||
); | ||
}; | ||
|
||
export default EventForm; |
Binary file not shown.
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,27 @@ | ||
@tailwind base; | ||
@tailwind components; | ||
@tailwind utilities; | ||
|
||
:root { | ||
--foreground-rgb: 0, 0, 0; | ||
--background-start-rgb: 214, 219, 220; | ||
--background-end-rgb: 255, 255, 255; | ||
} | ||
|
||
@media (prefers-color-scheme: dark) { | ||
:root { | ||
--foreground-rgb: 255, 255, 255; | ||
--background-start-rgb: 0, 0, 0; | ||
--background-end-rgb: 0, 0, 0; | ||
} | ||
} | ||
|
||
body { | ||
color: rgb(var(--foreground-rgb)); | ||
background: linear-gradient( | ||
to bottom, | ||
transparent, | ||
rgb(var(--background-end-rgb)) | ||
) | ||
rgb(var(--background-start-rgb)); | ||
} |
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 @@ | ||
import './globals.css' | ||
import { Inter } from 'next/font/google' | ||
|
||
const inter = Inter({ subsets: ['latin'] }) | ||
|
||
export const metadata = { | ||
title: 'Create Next App', | ||
description: 'Generated by create next app', | ||
} | ||
|
||
export default function RootLayout({ | ||
children, | ||
}: { | ||
children: React.ReactNode | ||
}) { | ||
return ( | ||
<html lang="en"> | ||
<body className={inter.className}>{children}</body> | ||
</html> | ||
) | ||
} |
Oops, something went wrong.