Compare commits
8 Commits
2041c8998a
...
fr/review-
Author | SHA1 | Date | |
---|---|---|---|
5caaa2bf5e | |||
c6b3efad4e | |||
c9b8246218 | |||
c89dfa6786 | |||
8f3e442077 | |||
0430710522 | |||
c1805643c8 | |||
f1c296c0d3 |
@ -28,6 +28,11 @@ const schema = new Schema<IReview | any>(
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
|
note: {
|
||||||
|
type: String,
|
||||||
|
required: false,
|
||||||
|
default: ""
|
||||||
|
},
|
||||||
beer_id: {
|
beer_id: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
required: true,
|
||||||
|
@ -1 +1 @@
|
|||||||
{"version":"2.0.0","endpoints":{"user":{"signup":{"name":"user","operation":"signup","route":"/api/v1/auth/signup","method":"POST","description":"user signup api","body":{"username":"testuser","email":"text@example.com","password":"Test1234"},"response":"status object"},"signin":{"name":"user","operation":"signin","route":"/api/v1/auth/signin","method":"POST","description":"user signin api","body":{"email":"text@example.com","password":"Test1234"},"response":"status object"},"logout":{"name":"user","operation":"logout","route":"/api/v1/auth/logout","method":"POST","description":"user logout api","body":{},"response":"status object"},"status":{"name":"user","operation":"status","route":"/api/v1/auth/status","method":"GET","description":"user login status api","response":"status code | user object"}},"beer":{"add":{"name":"beer","operation":"add","route":"/api/v1/beer/add","method":"POST","description":"beer add api","body":{"brand":"Pilsner Urqell","name":"Kozel","degree":11,"packaging":"can","photos":"optional field | max 4 images | formData"},"response":"status object | beer object"},"get":{"name":"beer","operation":"get","route":"/api/v1/beer/get","method":"GET","description":"beer get api","response":"status object | array of beer objects"},"del":{"name":"beer","operation":"del","route":"/api/v1/beer/del","method":"POST","description":"beer del api","body":{"_id":"6352b303b71cb62222f39895"},"response":"status object"},"edit":{"name":"beer","operation":"edit","route":"/api/v1/beer/edit","method":"POST","description":"beer edit api","body":{"_id":"6355b95dc03fad77bc380146","brand":"Pilsner Urqell","name":"Radegast","degree":12,"packaging":"bottle","imgs":[],"photos":"optional field | max 4 images | formData"},"response":"status object | beer data"}},"docs":{"get_all":{"name":"docs","operation":"get_all","route":"/api/v1","method":"GET","description":"Get docs json","response":"docs json"}},"review":{"add":{"name":"review","operation":"add","route":"/api/v1/review/add","method":"POST","description":"review add api","body":{"beer_id":"6352b303b71cb62222f39895","foam":3,"bitter_sweetness":2,"taste":5,"packaging":3,"sourness":false,"would_again":true},"response":"status object | review object"},"get":{"name":"review","operation":"get","route":"/api/v1/review/get","method":"GET","description":"review get api","response":"status object | array of review objects"},"del":{"name":"review","operation":"del","route":"/api/v1/review/del","method":"POST","description":"review del api","body":{"_id":"6352b303b71cb62222f39895"},"response":"status object"}}}}
|
{"version":"2.0.0","endpoints":{"user":{"signup":{"name":"user","operation":"signup","route":"/api/v1/auth/signup","method":"POST","description":"user signup api","body":{"username":"testuser","email":"text@example.com","password":"Test1234"},"response":"status object"},"signin":{"name":"user","operation":"signin","route":"/api/v1/auth/signin","method":"POST","description":"user signin api","body":{"email":"text@example.com","password":"Test1234"},"response":"status object"},"logout":{"name":"user","operation":"logout","route":"/api/v1/auth/logout","method":"POST","description":"user logout api","body":{},"response":"status object"},"status":{"name":"user","operation":"status","route":"/api/v1/auth/status","method":"GET","description":"user login status api","response":"status code | user object"}},"beer":{"add":{"name":"beer","operation":"add","route":"/api/v1/beer/add","method":"POST","description":"beer add api","body":{"brand":"Pilsner Urqell","name":"Kozel","degree":11,"packaging":"can","photos":"optional field | max 4 images | formData"},"response":"status object | beer object"},"get":{"name":"beer","operation":"get","route":"/api/v1/beer/get","method":"GET","description":"beer get api","response":"status object | array of beer objects"},"del":{"name":"beer","operation":"del","route":"/api/v1/beer/del","method":"POST","description":"beer del api","body":{"_id":"6352b303b71cb62222f39895"},"response":"status object"},"edit":{"name":"beer","operation":"edit","route":"/api/v1/beer/edit","method":"POST","description":"beer edit api","body":{"_id":"6355b95dc03fad77bc380146","brand":"Pilsner Urqell","name":"Radegast","degree":12,"packaging":"bottle","imgs":[],"photos":"optional field | max 4 images | formData"},"response":"status object | beer data"}},"docs":{"get_all":{"name":"docs","operation":"get_all","route":"/api/v1","method":"GET","description":"Get docs json","response":"docs json"}},"review":{"add":{"name":"review","operation":"add","route":"/api/v1/review/add","method":"POST","description":"review add api","body":{"beer_id":"6352b303b71cb62222f39895","foam":3,"bitter_sweetness":2,"taste":5,"packaging":3,"sourness":false,"would_again":true,"note":"Pretty good beer"},"response":"status object | review object"},"get":{"name":"review","operation":"get","route":"/api/v1/review/get","method":"GET","description":"review get api","response":"status object | array of review objects"},"del":{"name":"review","operation":"del","route":"/api/v1/review/del","method":"POST","description":"review del api","body":{"_id":"6352b303b71cb62222f39895"},"response":"status object"}}}}
|
@ -5,9 +5,9 @@ export const router = Router();
|
|||||||
|
|
||||||
router.use("/api/v1", api_v1);
|
router.use("/api/v1", api_v1);
|
||||||
|
|
||||||
//router.get("*", (req: Request, res: Response) => {
|
router.get("*", (req: Request, res: Response) => {
|
||||||
// res.sendFile(path.join(__dirname, "../views/index.html"));
|
res.sendFile(path.join(__dirname, "../public/index.html"));
|
||||||
//});
|
});
|
||||||
|
|
||||||
// 404
|
// 404
|
||||||
router.use((req: Request, res: Response) => {
|
router.use((req: Request, res: Response) => {
|
||||||
|
@ -20,7 +20,8 @@ export const add = yup.object({
|
|||||||
packaging: yup.number().min(1).max(5).required(),
|
packaging: yup.number().min(1).max(5).required(),
|
||||||
sourness: yup.boolean().required(),
|
sourness: yup.boolean().required(),
|
||||||
would_again: yup.boolean().required(),
|
would_again: yup.boolean().required(),
|
||||||
user_id: yup.string().notRequired()
|
user_id: yup.string().notRequired(),
|
||||||
|
note: yup.string().notRequired()
|
||||||
});
|
});
|
||||||
export interface IReview extends yup.InferType<typeof add>, mongooseAddition {}
|
export interface IReview extends yup.InferType<typeof add>, mongooseAddition {}
|
||||||
export const addExam: IReview = {
|
export const addExam: IReview = {
|
||||||
@ -31,6 +32,7 @@ export const addExam: IReview = {
|
|||||||
packaging: 3,
|
packaging: 3,
|
||||||
sourness: false,
|
sourness: false,
|
||||||
would_again: true,
|
would_again: true,
|
||||||
|
note: "Pretty good beer"
|
||||||
};
|
};
|
||||||
|
|
||||||
// Remove
|
// Remove
|
||||||
|
@ -73,6 +73,15 @@ describe("POST /api/v1/review/add", () => {
|
|||||||
expect(res.statusCode).toBe(400);
|
expect(res.statusCode).toBe(400);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("should drop 201 (missing note)", async () => {
|
||||||
|
const jwt = await login();
|
||||||
|
const body: any = { ...addExam };
|
||||||
|
delete body.note;
|
||||||
|
const res = await request.post(url).set("Cookie", jwt).send(body);
|
||||||
|
|
||||||
|
expect(res.statusCode).toBe(201);
|
||||||
|
})
|
||||||
|
|
||||||
test("should drop 201", async () => {
|
test("should drop 201", async () => {
|
||||||
const jwt = await login();
|
const jwt = await login();
|
||||||
const res = await request.post(url).set("Cookie", jwt).send(addExam);
|
const res = await request.post(url).set("Cookie", jwt).send(addExam);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { View, StyleSheet, FlatList } from "react-native";
|
import { View, StyleSheet, FlatList, Image } from "react-native";
|
||||||
import Text from "@components/Text";
|
import Text from "@components/Text";
|
||||||
import Button from "@components/Button";
|
import Button from "@components/Button";
|
||||||
import { colors } from "@components/style";
|
import { colors } from "@components/style";
|
||||||
@ -14,6 +14,8 @@ export default function Tab() {
|
|||||||
fetchData();
|
fetchData();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
|
const API_HOST = process.env.EXPO_PUBLIC_API_URL.replace("/api/v1", "");
|
||||||
|
|
||||||
async function fetchData() {
|
async function fetchData() {
|
||||||
try {
|
try {
|
||||||
const res = await fetch(`${process.env.EXPO_PUBLIC_API_URL}/review/get`, {
|
const res = await fetch(`${process.env.EXPO_PUBLIC_API_URL}/review/get`, {
|
||||||
@ -23,6 +25,28 @@ export default function Tab() {
|
|||||||
let data = await res.json();
|
let data = await res.json();
|
||||||
// show only logged in user's data
|
// show only logged in user's data
|
||||||
data = data.data.filter((review) => review.user_id == user._id);
|
data = data.data.filter((review) => review.user_id == user._id);
|
||||||
|
|
||||||
|
let beers = await fetch(`${process.env.EXPO_PUBLIC_API_URL}/beer/get`, {
|
||||||
|
method: "GET",
|
||||||
|
credentials: "include",
|
||||||
|
});
|
||||||
|
beers = await beers.json();
|
||||||
|
beers = beers.data;
|
||||||
|
console.log(beers);
|
||||||
|
|
||||||
|
async function getBeerParam(search, beers) {
|
||||||
|
for (let i = 0; i < beers.length; i++) {
|
||||||
|
if (beers[i]._id == search) {
|
||||||
|
return beers[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
data.forEach(async (el) => {
|
||||||
|
el.beer = await getBeerParam(el.beer_id, beers);
|
||||||
|
});
|
||||||
|
|
||||||
console.log("reviews", data);
|
console.log("reviews", data);
|
||||||
setData(data);
|
setData(data);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
@ -30,27 +54,53 @@ export default function Tab() {
|
|||||||
alert("Something went wrong");
|
alert("Something went wrong");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
const opt3 = ["Bad", "Medium", "Excellent!"];
|
||||||
|
const opt5 = [
|
||||||
|
"Disgust",
|
||||||
|
"Not great, not terrible",
|
||||||
|
"Good",
|
||||||
|
"Why not?",
|
||||||
|
"Excellent!",
|
||||||
|
];
|
||||||
|
const opt2 = ["Yes", "No"];
|
||||||
|
const sourness = ["Good", "Bad"];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Button
|
|
||||||
title="Add Review"
|
|
||||||
color={colors.gold}
|
|
||||||
onPress={() => {
|
|
||||||
router.replace("/review/add");
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<FlatList
|
<FlatList
|
||||||
data={data}
|
data={data}
|
||||||
style={styles.reviewList}
|
style={styles.reviewList}
|
||||||
keyExtractor={(item) => String(item._id)}
|
keyExtractor={(item) => String(item._id)}
|
||||||
renderItem={({ item }) => (
|
renderItem={({ item }) => (
|
||||||
<View style={styles.item}>
|
<View style={styles.itemContainer}>
|
||||||
<Text>Name: {item.name}</Text>
|
<View>
|
||||||
<Text>Brand: {item.brand}</Text>
|
<Text>{item.beer.name}</Text>
|
||||||
<Text>Degree: {item.degree}</Text>
|
<Text>{item.beer.brand}</Text>
|
||||||
<Text>Packaging: {item.packaging}</Text>
|
<Text>{item.beer.degree}°</Text>
|
||||||
|
<Text>{item.beer.packaging}</Text>
|
||||||
|
<Image
|
||||||
|
source={
|
||||||
|
item.beer.imgs[0]
|
||||||
|
? {
|
||||||
|
uri: `${API_HOST}/public/uploads/${item.beer.imgs[0]}`,
|
||||||
|
}
|
||||||
|
: {
|
||||||
|
uri: "https://imagesvc.meredithcorp.io/v3/mm/image?url=https:%2F%2Fstatic.onecms.io%2Fwp-content%2Fuploads%2Fsites%2F44%2F2020%2F09%2F29%2Flight-beer.jpg",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
style={styles.itemImg}
|
||||||
|
/>
|
||||||
|
</View>
|
||||||
|
<View>
|
||||||
|
<Text>Foam → {opt3[item.foam - 1]}</Text>
|
||||||
|
<Text>
|
||||||
|
Bitter / Sweetness → {opt3[item.bitter_sweetness - 1]}
|
||||||
|
</Text>
|
||||||
|
<Text>Taste → {opt5[item.taste - 1]}</Text>
|
||||||
|
<Text>Packaging → {opt5[item.packaging - 1]}</Text>
|
||||||
|
<Text>Sourness → {sourness[item.sourness - 1]}</Text>
|
||||||
|
<Text>Would again? → {opt2[item.would_again - 1]}</Text>
|
||||||
|
</View>
|
||||||
</View>
|
</View>
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
@ -70,11 +120,20 @@ export const styles = StyleSheet.create({
|
|||||||
paddingHorizontal: "15%",
|
paddingHorizontal: "15%",
|
||||||
marginTop: "5%",
|
marginTop: "5%",
|
||||||
},
|
},
|
||||||
item: {
|
itemContainer: {
|
||||||
borderColor: "gray",
|
borderColor: "gray",
|
||||||
borderWidth: 1,
|
borderWidth: 1,
|
||||||
borderRadius: 10,
|
borderRadius: 10,
|
||||||
padding: 13,
|
padding: 13,
|
||||||
marginBottom: "5%",
|
marginBottom: "5%",
|
||||||
|
flex: 1,
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-between",
|
||||||
|
},
|
||||||
|
itemImg: {
|
||||||
|
width: 150,
|
||||||
|
aspectRatio: 1,
|
||||||
|
resizeMode: "contain",
|
||||||
|
marginTop: "5%",
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
@ -6,7 +6,8 @@
|
|||||||
"start": "expo start",
|
"start": "expo start",
|
||||||
"android": "expo start --android",
|
"android": "expo start --android",
|
||||||
"ios": "expo start --ios",
|
"ios": "expo start --ios",
|
||||||
"web": "expo start --web"
|
"web": "expo start --web",
|
||||||
|
"build:web": "npx expo export"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@expo/metro-runtime": "~3.2.1",
|
"@expo/metro-runtime": "~3.2.1",
|
||||||
|
Reference in New Issue
Block a user