adding pretteir and fixing post call so now clicking continue will upload to aws
This commit is contained in:
8
.prettierrc
Normal file
8
.prettierrc
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"trailingComma": "none",
|
||||||
|
"semi": false,
|
||||||
|
"singleQuote": true,
|
||||||
|
"jsxSingleQuote": true,
|
||||||
|
"printWidth": 120,
|
||||||
|
"tabWidth": 4
|
||||||
|
}
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
import { PutObjectCommand, S3Client } from '@aws-sdk/client-s3';
|
import { PutObjectCommand, S3Client } from '@aws-sdk/client-s3'
|
||||||
import { Buffer } from 'node:buffer';
|
import { Buffer } from 'node:buffer'
|
||||||
import { v4 as uuidv4 } from 'uuid';
|
import { v4 as uuidv4 } from 'uuid'
|
||||||
|
|
||||||
class AWSUtil {
|
class AWSUtil {
|
||||||
constructor() {
|
constructor() {
|
||||||
this.s3 = new S3Client({ region: "us-east-2" });
|
this.s3 = new S3Client({ region: 'us-east-2' })
|
||||||
}
|
}
|
||||||
|
|
||||||
async uploadFile(base64, ACL = "public-read") {
|
async uploadFile(base64, ACL = 'public-read') {
|
||||||
const base64Data = Buffer.from(base64.replace(/^data:image\/\w+;base64,/, ""), 'base64');
|
const base64Data = Buffer.from(base64.replace(/^data:image\/\w+;base64,/, ''), 'base64')
|
||||||
const type = base64.split(';')[0].split('/')[1];
|
const type = base64.split(';')[0].split('/')[1]
|
||||||
const uuid = uuidv4();
|
const uuid = uuidv4()
|
||||||
|
|
||||||
const params = {
|
const params = {
|
||||||
Bucket: process.env.AWS_S3_BUCKET,
|
Bucket: process.env.AWS_S3_BUCKET,
|
||||||
@@ -18,21 +18,16 @@ class AWSUtil {
|
|||||||
Body: base64Data,
|
Body: base64Data,
|
||||||
ContentEncoding: 'base64', // required
|
ContentEncoding: 'base64', // required
|
||||||
ContentType: `image/${type}` // required
|
ContentType: `image/${type}` // required
|
||||||
};
|
}
|
||||||
|
|
||||||
// Create an object and upload it to the Amazon S3 bucket.
|
// Create an object and upload it to the Amazon S3 bucket.
|
||||||
try {
|
try {
|
||||||
const results = await this.s3.send(new PutObjectCommand(params));
|
const results = await this.s3.send(new PutObjectCommand(params))
|
||||||
console.log(
|
console.log(
|
||||||
"Successfully created " +
|
'Successfully created ' + params.Key + ' and uploaded it to ' + params.Bucket + '/' + params.Key
|
||||||
params.Key +
|
)
|
||||||
" and uploaded it to " +
|
|
||||||
params.Bucket +
|
|
||||||
"/" +
|
|
||||||
params.Key
|
|
||||||
);
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log("Error", err);
|
console.log('Error', err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return `https://tattletires.s3.us-east-2.amazonaws.com/${params.Key}`
|
return `https://tattletires.s3.us-east-2.amazonaws.com/${params.Key}`
|
||||||
@@ -41,13 +36,13 @@ class AWSUtil {
|
|||||||
async deleteFile(Location) {
|
async deleteFile(Location) {
|
||||||
const params = {
|
const params = {
|
||||||
Bucket: process.env.AWS_S3_BUCKET,
|
Bucket: process.env.AWS_S3_BUCKET,
|
||||||
Key: Location.split("s3.amazonaws.com/").pop()
|
Key: Location.split('s3.amazonaws.com/').pop()
|
||||||
};
|
}
|
||||||
|
|
||||||
const data = await this.s3.deleteObject(params).promise();
|
const data = await this.s3.deleteObject(params).promise()
|
||||||
|
|
||||||
return data;
|
return data
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AWSUtil;
|
export default AWSUtil
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import AWSUtil from '../bin/aws.js';
|
import AWSUtil from '../bin/aws.js'
|
||||||
import Post from '../models/postModel.js';
|
import Post from '../models/postModel.js'
|
||||||
|
|
||||||
export const getAllPosts = async (req, res, next) => {
|
export const getAllPosts = async (req, res, next) => {
|
||||||
const allPosts = await Post.find({}).exec();
|
const allPosts = await Post.find({}).exec()
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
status: 'success',
|
status: 'success',
|
||||||
data: allPosts
|
data: allPosts
|
||||||
@@ -10,61 +10,60 @@ export const getAllPosts = async (req, res, next) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export const getPost = async (req, res, next) => {
|
export const getPost = async (req, res, next) => {
|
||||||
const post = await Post.findById(req.params.id).exec();
|
const post = await Post.findById(req.params.id).exec()
|
||||||
if (!post) {
|
if (!post) {
|
||||||
return next('No document found with that id', 404);
|
return next('No document found with that id', 404)
|
||||||
}
|
}
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
status: 'success',
|
status: 'success',
|
||||||
data: post
|
data: post
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const getAllPostsByUser = async (req, res, next) => {
|
export const getAllPostsByUser = async (req, res, next) => {
|
||||||
const post = await Post.find({email: req.params.user}).exec();
|
const post = await Post.find({ email: req.params.user }).exec()
|
||||||
if (!post) {
|
if (!post) {
|
||||||
return next('No document found with that id', 404);
|
return next('No document found with that id', 404)
|
||||||
}
|
}
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
status: 'success',
|
status: 'success',
|
||||||
data: post
|
data: post
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const createPost = async (req, res, next) => {
|
export const createPost = async (req, res, next) => {
|
||||||
const aws = new AWSUtil();
|
const aws = new AWSUtil()
|
||||||
|
|
||||||
// Grab base64 photo from the req body
|
// Grab base64 photo from the req body
|
||||||
const location = await aws.uploadFile(req.body.photo);
|
const location = await aws.uploadFile(req.body.photo)
|
||||||
|
|
||||||
const payload = {
|
const payload = {
|
||||||
...req.body,
|
...req.body,
|
||||||
photo: location
|
photo: location
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Post.create(payload).then((result) => {
|
||||||
Post.create(payload).then(result => {
|
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
status: 'success',
|
status: 'success',
|
||||||
data: result
|
data: result
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const updatePost = async (req, res, next) => {
|
export const updatePost = async (req, res, next) => {
|
||||||
Post.updateOne({_id: req.params.id},{$set: req.body}).then(result => {
|
Post.updateOne({ _id: req.params.id }, { $set: req.body }).then((result) => {
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
status: 'success',
|
status: 'success',
|
||||||
data: result
|
data: result
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const deletePost = async (req, res, next) => {
|
export const deletePost = async (req, res, next) => {
|
||||||
Post.deleteOne({_id: req.params.id}).then(result => {
|
Post.deleteOne({ _id: req.params.id }).then((result) => {
|
||||||
res.status(200).json({
|
res.status(200).json({
|
||||||
status: 'success',
|
status: 'success',
|
||||||
data: result
|
data: result
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
5014
api/package-lock.json
generated
5014
api/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -1,24 +1,24 @@
|
|||||||
{
|
{
|
||||||
"name": "api",
|
"name": "api",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node ./bin/www"
|
"start": "node ./bin/www"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"aws-sdk": "^2.1692.0",
|
"@aws-sdk/client-s3": "^3.850.0",
|
||||||
"cookie-parser": "~1.4.4",
|
"cookie-parser": "~1.4.4",
|
||||||
"cors": "^2.8.5",
|
"cors": "^2.8.5",
|
||||||
"debug": "~2.6.9",
|
"debug": "~2.6.9",
|
||||||
"dotenv": "^17.2.1",
|
"dotenv": "^17.2.1",
|
||||||
"express": "~4.16.1",
|
"express": "~4.16.1",
|
||||||
"http-errors": "~1.6.3",
|
"http-errors": "~1.6.3",
|
||||||
"jade": "~1.11.0",
|
"jade": "~1.11.0",
|
||||||
"mongodb": "^6.18.0",
|
"mongodb": "^6.18.0",
|
||||||
"mongoose": "^8.16.4",
|
"mongoose": "^8.16.4",
|
||||||
"morgan": "~1.9.1",
|
"morgan": "~1.9.1",
|
||||||
"nanoid": "^5.1.5",
|
"nanoid": "^5.1.5",
|
||||||
"validator": "^13.15.15",
|
"validator": "^13.15.15",
|
||||||
"xss-clean": "^0.1.4"
|
"xss-clean": "^0.1.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,35 +1,38 @@
|
|||||||
import { CameraView, useCameraPermissions } from 'expo-camera';
|
import { CameraView, useCameraPermissions } from 'expo-camera'
|
||||||
import { useRef, useState } from 'react';
|
import { useRef, useState } from 'react'
|
||||||
import { Button, Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native';
|
import { Button, Image, StyleSheet, Text, TouchableOpacity, View } from 'react-native'
|
||||||
|
|
||||||
export default function App() {
|
export default function App() {
|
||||||
const [permission, requestPermission] = useCameraPermissions();
|
const [permission, requestPermission] = useCameraPermissions()
|
||||||
const [photo, setPhoto] = useState('');
|
const [photo, setPhoto] = useState('')
|
||||||
const cameraRef = useRef<CameraView>(null);
|
const cameraRef = useRef<CameraView>(null)
|
||||||
|
|
||||||
async function _takePhoto() {
|
async function _takePhoto() {
|
||||||
if (cameraRef.current) {
|
if (cameraRef.current) {
|
||||||
const pic = await cameraRef.current.takePictureAsync()
|
const pic = await cameraRef.current.takePictureAsync()
|
||||||
setPhoto(pic.base64 || '');
|
setPhoto(pic.base64 || '')
|
||||||
console.log(pic.base64);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function sendData() {
|
async function sendData() {
|
||||||
const response = await fetch("localhost:3000/api/v1/posts", {
|
await fetch('http://localhost:3000/api/v1/posts', {
|
||||||
method: "POST",
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
Accept: 'application/json, text/plain, */*',
|
||||||
|
'Content-Type': 'application/json'
|
||||||
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
userID: '6883ddb2640ebaa1a12e3791',
|
userID: '6883ddb2640ebaa1a12e3791',
|
||||||
date: new Date(),
|
date: new Date(),
|
||||||
photo: photo,
|
photo: photo,
|
||||||
notes: '3333 W Smoochie St'
|
notes: '3333 W Smoochie St'
|
||||||
}),
|
})
|
||||||
}).then(() => {console.log(response)});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!permission) {
|
if (!permission) {
|
||||||
// Camera permissions are still loading.
|
// Camera permissions are still loading.
|
||||||
return <View />;
|
return <View />
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!permission.granted) {
|
if (!permission.granted) {
|
||||||
@@ -37,9 +40,9 @@ export default function App() {
|
|||||||
return (
|
return (
|
||||||
<View style={styles.container}>
|
<View style={styles.container}>
|
||||||
<Text style={styles.message}>We need your permission to show the camera</Text>
|
<Text style={styles.message}>We need your permission to show the camera</Text>
|
||||||
<Button onPress={requestPermission} title="grant permission" />
|
<Button onPress={requestPermission} title='grant permission' />
|
||||||
</View>
|
</View>
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -49,27 +52,27 @@ export default function App() {
|
|||||||
<Image source={{ uri: photo }} style={styles.camera} />
|
<Image source={{ uri: photo }} style={styles.camera} />
|
||||||
<View style={styles.buttonContainer}>
|
<View style={styles.buttonContainer}>
|
||||||
<TouchableOpacity style={styles.button} onPress={() => setPhoto('')}>
|
<TouchableOpacity style={styles.button} onPress={() => setPhoto('')}>
|
||||||
<Text style={styles.text}>Retake</Text>
|
<Text style={styles.text}>Retake</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
<TouchableOpacity style={styles.button} onPress={sendData}>
|
<TouchableOpacity style={styles.button} onPress={sendData}>
|
||||||
<Text style={styles.text}>Continue</Text>
|
<Text style={styles.text}>Continue</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
</View>
|
</View>
|
||||||
) : (
|
) : (
|
||||||
<>
|
<>
|
||||||
<View style={styles.cameraContainer}>
|
<View style={styles.cameraContainer}>
|
||||||
<CameraView style={styles.camera} facing={'back'} ref={cameraRef}>
|
<CameraView style={styles.camera} facing={'back'} ref={cameraRef}></CameraView>
|
||||||
</CameraView>
|
|
||||||
</View>
|
</View>
|
||||||
<View style={styles.buttonContainer}>
|
<View style={styles.buttonContainer}>
|
||||||
<TouchableOpacity style={styles.button} onPress={_takePhoto}>
|
<TouchableOpacity style={styles.button} onPress={_takePhoto}>
|
||||||
<Text style={styles.text}>Take Photo</Text>
|
<Text style={styles.text}>Take Photo</Text>
|
||||||
</TouchableOpacity>
|
</TouchableOpacity>
|
||||||
</View>
|
</View>
|
||||||
</>)}
|
</>
|
||||||
|
)}
|
||||||
</View>
|
</View>
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const styles = StyleSheet.create({
|
const styles = StyleSheet.create({
|
||||||
@@ -81,30 +84,30 @@ const styles = StyleSheet.create({
|
|||||||
paddingVertical: 200
|
paddingVertical: 200
|
||||||
},
|
},
|
||||||
cameraContainer: {
|
cameraContainer: {
|
||||||
flex: 1,
|
flex: 1
|
||||||
},
|
},
|
||||||
message: {
|
message: {
|
||||||
textAlign: 'center',
|
textAlign: 'center',
|
||||||
paddingBottom: 10,
|
paddingBottom: 10
|
||||||
},
|
},
|
||||||
camera: {
|
camera: {
|
||||||
flex: 1,
|
flex: 1
|
||||||
},
|
},
|
||||||
buttonContainer: {
|
buttonContainer: {
|
||||||
flex: 0.2,
|
flex: 0.2,
|
||||||
flexDirection: 'row',
|
flexDirection: 'row',
|
||||||
backgroundColor: 'orange',
|
backgroundColor: 'orange',
|
||||||
marginTop: 15,
|
marginTop: 15,
|
||||||
borderRadius: 5,
|
borderRadius: 5
|
||||||
},
|
},
|
||||||
button: {
|
button: {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
alignSelf: 'center',
|
alignSelf: 'center',
|
||||||
alignItems: 'center',
|
alignItems: 'center'
|
||||||
},
|
},
|
||||||
text: {
|
text: {
|
||||||
fontSize: 24,
|
fontSize: 24,
|
||||||
fontWeight: 'bold',
|
fontWeight: 'bold',
|
||||||
color: 'white',
|
color: 'white'
|
||||||
},
|
}
|
||||||
});
|
})
|
||||||
|
|||||||
16
package-lock.json
generated
16
package-lock.json
generated
@@ -28,6 +28,7 @@
|
|||||||
"expo-system-ui": "~5.0.10",
|
"expo-system-ui": "~5.0.10",
|
||||||
"expo-web-browser": "~14.2.0",
|
"expo-web-browser": "~14.2.0",
|
||||||
"express": "^5.1.0",
|
"express": "^5.1.0",
|
||||||
|
"prettier": "^3.6.2",
|
||||||
"react": "19.0.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "19.0.0",
|
"react-dom": "19.0.0",
|
||||||
"react-native": "0.79.5",
|
"react-native": "0.79.5",
|
||||||
@@ -11806,6 +11807,21 @@
|
|||||||
"node": ">= 0.8.0"
|
"node": ">= 0.8.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/prettier": {
|
||||||
|
"version": "3.6.2",
|
||||||
|
"resolved": "https://registry.npmjs.org/prettier/-/prettier-3.6.2.tgz",
|
||||||
|
"integrity": "sha512-I7AIg5boAr5R0FFtJ6rCfD+LFsWHp81dolrFD8S79U9tb8Az2nGrJncnMSnys+bpQJfRUzqs9hnA81OAA3hCuQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"bin": {
|
||||||
|
"prettier": "bin/prettier.cjs"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">=14"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/prettier/prettier?sponsor=1"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/pretty-bytes": {
|
"node_modules/pretty-bytes": {
|
||||||
"version": "5.6.0",
|
"version": "5.6.0",
|
||||||
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
|
"resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz",
|
||||||
|
|||||||
102
package.json
102
package.json
@@ -1,53 +1,53 @@
|
|||||||
{
|
{
|
||||||
"name": "tattletires",
|
"name": "tattletires",
|
||||||
"main": "expo-router/entry",
|
"main": "expo-router/entry",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "expo start",
|
"start": "expo start",
|
||||||
"reset-project": "node ./scripts/reset-project.js",
|
"reset-project": "node ./scripts/reset-project.js",
|
||||||
"android": "expo start --android",
|
"android": "expo start --android",
|
||||||
"ios": "expo start --ios",
|
"ios": "expo start --ios",
|
||||||
"web": "expo start --web",
|
"web": "expo start --web",
|
||||||
"lint": "expo lint"
|
"lint": "expo lint"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@aws-sdk/client-s3": "^3.850.0",
|
"@expo/vector-icons": "^14.1.0",
|
||||||
"@expo/vector-icons": "^14.1.0",
|
"@react-navigation/bottom-tabs": "^7.3.10",
|
||||||
"@react-navigation/bottom-tabs": "^7.3.10",
|
"@react-navigation/elements": "^2.3.8",
|
||||||
"@react-navigation/elements": "^2.3.8",
|
"@react-navigation/native": "^7.1.6",
|
||||||
"@react-navigation/native": "^7.1.6",
|
"expo": "~53.0.20",
|
||||||
"expo": "~53.0.20",
|
"expo-blur": "~14.1.5",
|
||||||
"expo-blur": "~14.1.5",
|
"expo-camera": "~16.1.11",
|
||||||
"expo-camera": "~16.1.11",
|
"expo-constants": "~17.1.7",
|
||||||
"expo-constants": "~17.1.7",
|
"expo-font": "~13.3.2",
|
||||||
"expo-font": "~13.3.2",
|
"expo-haptics": "~14.1.4",
|
||||||
"expo-haptics": "~14.1.4",
|
"expo-image": "~2.4.0",
|
||||||
"expo-image": "~2.4.0",
|
"expo-linking": "~7.1.7",
|
||||||
"expo-linking": "~7.1.7",
|
"expo-router": "~5.1.4",
|
||||||
"expo-router": "~5.1.4",
|
"expo-splash-screen": "~0.30.10",
|
||||||
"expo-splash-screen": "~0.30.10",
|
"expo-status-bar": "~2.2.3",
|
||||||
"expo-status-bar": "~2.2.3",
|
"expo-symbols": "~0.4.5",
|
||||||
"expo-symbols": "~0.4.5",
|
"expo-system-ui": "~5.0.10",
|
||||||
"expo-system-ui": "~5.0.10",
|
"expo-web-browser": "~14.2.0",
|
||||||
"expo-web-browser": "~14.2.0",
|
"express": "^5.1.0",
|
||||||
"express": "^5.1.0",
|
"prettier": "^3.6.2",
|
||||||
"react": "19.0.0",
|
"react": "19.0.0",
|
||||||
"react-dom": "19.0.0",
|
"react-dom": "19.0.0",
|
||||||
"react-native": "0.79.5",
|
"react-native": "0.79.5",
|
||||||
"react-native-gesture-handler": "~2.24.0",
|
"react-native-gesture-handler": "~2.24.0",
|
||||||
"react-native-reanimated": "~3.17.4",
|
"react-native-reanimated": "~3.17.4",
|
||||||
"react-native-safe-area-context": "5.4.0",
|
"react-native-safe-area-context": "5.4.0",
|
||||||
"react-native-screens": "~4.11.1",
|
"react-native-screens": "~4.11.1",
|
||||||
"react-native-web": "~0.20.0",
|
"react-native-web": "~0.20.0",
|
||||||
"react-native-webview": "13.13.5",
|
"react-native-webview": "13.13.5",
|
||||||
"uuid": "^11.1.0"
|
"uuid": "^11.1.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "^7.25.2",
|
"@babel/core": "^7.25.2",
|
||||||
"@types/react": "~19.0.10",
|
"@types/react": "~19.0.10",
|
||||||
"eslint": "^9.25.0",
|
"eslint": "^9.25.0",
|
||||||
"eslint-config-expo": "~9.2.0",
|
"eslint-config-expo": "~9.2.0",
|
||||||
"typescript": "~5.8.3"
|
"typescript": "~5.8.3"
|
||||||
},
|
},
|
||||||
"private": true
|
"private": true
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user