Vegeatery is an eatery that promotes different kinds of vegetarian diet using ingredients sourced locally from sustainable farms, and eco-friendly producers. We aim to promote a healthy earth and lifestyle while meeting the needs of our customers.
This is an example of how you can set up your project locally. To get a local copy up and running, follow these simple steps.
Clone the repository
git clone https://github.com/KenNoYu/Vegeatery
cd Vegeatery
code .
You only need to clone the repository once. When you clone it, a copy of vegeatery will be inside your computer already.
Inside Visual Studio Code in Terminal
cd client
npm i
If the terminal prompts errors after npm i, run.
npm audit fix
Im not sure how these node modules work so the only fix I know is npm audit fix
In order to run the web application, both server and client has to be running
- Open the vegeatery.sln in server folder using Visual Studio 2022
- Configure Database
Configure DB
- Run the application
- Open the whole project in Visual Studio Code Inside Terminal
cd client
npm i
npm start
In order to setup the database for your own use inside VS 2022
- Open up Nuget Manager Console under Tools at the top bar
Add-Migration <Migration-Name>
Update-Database
WARNING: You MUST have versions 8.0.0 and above installed for the SQL packages in your Nuget Package Manager and NOT version 9.0.0 otherwise you will be unable to create the Migration.
Server and Client are connected by default through the http port number. Port for server can be found in the vegeatery.http file and to connect the port from client to server. In file client.env.development, you only need to change the port number.
This is an example of where you can write your code. To start on your part, follow these simple steps.
When doing your part always create a new branch. In terminal
git checkout -b <branchname>
When you want to push changes to main remember to first commit to your remote branch. Then create a pull request to merge with main branch
This shows where you can contribute to your part in the project file.
- In the folder Models, this is where you can add your classes for your database tables
- In the file MyDBContext.cs, you can create your new database table inside here
- In the folder Controller, this is where you can add your various request such as post, get and delete for your API endpoints
- In the file Program.cs, this is where you can configure information regarding the server such as authentication, cookies etc..
- In the folder Public, this is where your images will be at, if possible use only SVG or WEBP file formats
- In the folder src\pages, this is where you can create your html pages using React, and sending request to your API endpoints
- In the folder src\context, this is where you can add your context state, such as creating new users or new item
- To test your own endpoints inside VS 2022 in vegeatery.http, generate your request from endpoints explorer and test it yourself. I have 2 examples inside for reference.
- Do Not Commit the Vegeatery.http file, its for your own testing purpose
In order to send a request from client, you must first have a API endpoints created. These endpoints can be made inside Controller folder in server. An example would be.
// Create new product
[HttpPost]
public IActionResult AddProduct(Product product)
{
var now = DateTime.Now;
var newProduct = new Product()
{
productName = product.productName.Trim(),
productDescription = product.productDescription.Trim(),
productCategory = product.productCategory.Trim(),
CreatedAt = now,
UpdatedAt = now
};
_context.Product.Add(newProduct);
_context.SaveChanges();
return Ok(newProduct);
}
Now that we have an API controller. We need to generate these from Endpoints Explorer to see what the route looks like An example in vegeatery.http would be.
POST {{vegeatery_HostAddress}}/product
Content-Type: application/json
{
"productName":"Rice",
"productDescription":"Rice",
"productCategory":"Carbo"
}
Reminder: You do not need to commit the vegeatery.http file, its for testing purposes only.
So we have an API for creating a new product, now we need to create the client page to enable it to send request to the server. I will be using the AddTutorial as an example as I have not created one for products but the logic is still the same.
function AddTutorial() {
const navigate = useNavigate();
const [imageFile, setImageFile] = useState(null);
const formik = useFormik({
initialValues: {
title: "",
description: ""
},
validationSchema: yup.object({
title: yup.string().trim()
.min(3, 'Title must be at least 3 characters')
.max(100, 'Title must be at most 100 characters')
.required('Title is required'),
description: yup.string().trim()
.min(3, 'Description must be at least 3 characters')
.max(500, 'Description must be at most 500 characters')
.required('Description is required')
}),
onSubmit: (data) => {
if (imageFile) {
data.imageFile = imageFile;
}
data.title = data.title.trim();
data.description = data.description.trim();
http.post("/tutorial", data)
.then((res) => {
console.log(res.data);
navigate("/tutorials");
});
}
});
}
The important line here is the http.post("/tutorial", data). this is what will send the request to the server from the client. So the format is like this
http.<request>("<route>", <data>)
Another example for getting tutorials from server.
const getTutorials = () => {
http.get('/tutorial').then((res) => {
setTutorialList(res.data);
});
};
Now for the how the website will look like, I will use the Tutorials page as an example.
function Tutorials() {
<Tutorial Functions> ...
return (
<Box>
<Typography variant="h5" sx={{ my: 2 }}>
Tutorials
</Typography>
<Box sx={{ display: 'flex', alignItems: 'center', mb: 2 }}>
<Input value={search} placeholder="Search"
onChange={onSearchChange}
onKeyDown={onSearchKeyDown} />
<IconButton color="primary"
onClick={onClickSearch}>
<Search />
</IconButton>
<IconButton color="primary"
onClick={onClickClear}>
<Clear />
</IconButton>
<Box sx={{ flexGrow: 1 }} />
{
user && (
<Link to="/addtutorial">
<Button variant='contained'>
Add
</Button>
</Link>
)
}
</Box>
<Grid container spacing={2}>
{
tutorialList.map((tutorial, i) => {
return (
<Grid size={{xs:12, md:6, lg:4}} key={tutorial.id}>
<Card>
{
tutorial.imageFile && (
<Box className="aspect-ratio-container">
<img alt="tutorial"
src={`${import.meta.env.VITE_FILE_BASE_URL}${tutorial.imageFile}`}>
</img>
</Box>
)
}
<CardContent>
<Box sx={{ display: 'flex', mb: 1 }}>
<Typography variant="h6" sx={{ flexGrow: 1 }}>
{tutorial.title}
</Typography>
{
user && user.id === tutorial.userId && (
<Link to={`/edittutorial/${tutorial.id}`}>
<IconButton color="primary" sx={{ padding: '4px' }}>
<Edit />
</IconButton>
</Link>
)
}
</Box>
<Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}
color="text.secondary">
<AccountCircle sx={{ mr: 1 }} />
<Typography>
{tutorial.user?.name}
</Typography>
</Box>
<Box sx={{ display: 'flex', alignItems: 'center', mb: 1 }}
color="text.secondary">
<AccessTime sx={{ mr: 1 }} />
<Typography>
{dayjs(tutorial.createdAt).format(global.datetimeFormat)}
</Typography>
</Box>
<Typography sx={{ whiteSpace: 'pre-wrap' }}>
{tutorial.description}
</Typography>
</CardContent>
</Card>
</Grid>
);
})
}
</Grid>
</Box>
);
}
export default Tutorials;
The part where your html will be is placed inside return(). Tutorial Functions means the functions used by the page for sending request and receiving response from the server.
Thanks for reading the README and hopefully you are able to understand most of what needs to be done through README.md If you still have any questions feel free to ask me :)
- Caffeine-addictt - For the repository template
- Img Shields - For the awesome README badges
- Hyprland - For showing how to make beautiful READMEs
- Hyprdots - For showing how to make beautiful READMEs