Open Timee2023 opened 10 months ago
Hi, thanks for integrating square payments into the application:
I've been trying to run this using mongoDB. I've been able to look at prisma configuration for mongoDB and have updated it as such:
generator client {
provider = "prisma-client-js"
previewFeatures = ["mongodb"]
}
datasource db {
provider = "mongodb"
url = env("DATABASE_CONNECTION_STRING")
}
model orders {
id String @id @default(uuid()) @map("_id")
created_at DateTime @default(now())
status String
cart Json @db.Json
transaction_id String?
checkout_id String?
paid Boolean?
gateway String
totalUniqueItems Int
totalAmount Int
customerId String @default(uuid())
customer customers? @relation(fields: [customerId], references: [id])
}
model products {
id String @id @default(uuid()) @map("_id")
created_at DateTime? @default(now())
name String
permalink String
summary String
description String
price Float // Change to Float
images images[]
enabled Boolean
}
model customers {
id String @id @default(uuid()) @map("_id")
created_at DateTime @default(now())
email String
phone String
firstName String
lastName String
address1 String
suburb String
state String
postcode String
country String
orders orders[]
}
model users {
id String @id @default(uuid()) @map("_id")
created_at DateTime @default(now())
name String
email String
enabled Boolean
}
model images {
id String @id @default(uuid()) @map("_id")
created_at DateTime @default(now())
url String
alt String
filename String
order Int
productId String @default(uuid())
product products? @relation(fields: [productId], references: [id], onDelete: Cascade)
}
model discounts {
id String @id @default(uuid()) @map("_id")
created_at DateTime @default(now())
name String
code String
type discountType @default(amount)
value Float @default(0) // Change to Float
enabled Boolean
start_at DateTime @default(now())
end_at DateTime @default(now())
}
enum discountType {
amount
percent
}
my db connection string has been updated: Github client id has been updated Github secret has been updated
DATABASE_CONNECTION_STRING=mongodb://localhost:27017/nextjs-checkout GITHUB_CLIENT_ID mygithubclientid GITHUB_SECRET mygithubsecret
I don't see anything currently in my mongodb database, additionally, I'm trying to access the admin panel/dashboard.
For my OAuth I've set up my homepage as: http://localhost:3000/ I'm not sure what should be the callback url but I put: http://localhost:3000/admin/dashboard
Once i log in with github i get redirected back to the sign in page always
Any help is appreciated thank you
Hi @Timee2023, thanks for the feedback on the docs. I've updated readme here: https://github.com/mrvautin/nextjs-checkout?tab=readme-ov-file#github-authentication
The doco is pretty raw. If you find anything else missing please let me know or submit a PR.
Hi @Timee2023, thanks for the feedback on the docs. I've updated readme here: https://github.com/mrvautin/nextjs-checkout?tab=readme-ov-file#github-authentication
The doco is pretty raw. If you find anything else missing please let me know or submit a PR.
I wasn't necessarily able to get it working with mongoDB unfortunately. I believe the configurations I altered weren't exactly correct but I tried to follow everything that Prisma stated for mongo, using the configuration settings I mentioned above.
I decided to use instead PostreSQL, like yourself, and have successfully been able to get the database working with my configuration.
I proceeded to alter the OAuth setting with correct directories for callback URL, etc and have been able to access the Admin dashboard and Authentication works.
The AWS S3 service unfortunately is where I'm running into problems (For the photos). I did create a bucket and was able to generate an ID and Access Key. However, this didn't end up working after placing these keys/Ids in my .env files. I tried a few times with different buckets and generating new keys but wasn't successful. I do believe there's quite a few configuration settings on the S3 service that may need to be set correctly.
Thank you.
Hi @Timee2023 - I recall AWS being a bit touchy to setup. I've created a little guide here: https://github.com/mrvautin/nextjs-checkout?tab=readme-ov-file#images
Let me know how you go.
Hi @Timee2023 - I recall AWS being a bit touchy to setup. I've created a little guide here: https://github.com/mrvautin/nextjs-checkout?tab=readme-ov-file#images
Let me know how you go.
Hey, just got back to configuring this and found a workaround:
Just configuring the .env
with AWS S3 BUCKET_NAME, ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY
didn't actually work.
The error I had gotten in the console was:
err Error: Region is missing
This was thrown from the config.js file within the aws-sdk:
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.NODE_REGION_CONFIG_FILE_OPTIONS = exports.NODE_REGION_CONFIG_OPTIONS = exports.REGION_INI_NAME = exports.REGION_ENV_NAME = void 0;
exports.REGION_ENV_NAME = "AWS_REGION";
exports.REGION_INI_NAME = "region";
exports.NODE_REGION_CONFIG_OPTIONS = {
environmentVariableSelector: (env) => env[exports.REGION_ENV_NAME],
configFileSelector: (profile) => profile[exports.REGION_INI_NAME],
default: () => {
throw new Error("Region is missing");
},
};
exports.NODE_REGION_CONFIG_FILE_OPTIONS = {
preferredFile: "credentials",
};
To resolve this, in the .env file I had added:
AWS_REGION=us-east-1
(My region)
This resolved the problem and allowed me to upload images successfully and they appear in my AWS S3 bucket.
My .env
now contains the following AWS configurations:
AWS_REGION=my-region
AWS_S3_BUCKET_NAME=nextjs-checkout
AWS_ACCESS_KEY_ID=my-key
AWS_SECRET_ACCESS_KEY=my-key
Good find! I've added some code and updated the README instructions to set the region. Not sure how mine worked without setting this value.
If you find anything else, please let me know.
@mrvautin There's a search issue when searching for products that actually exist, in addition, generating their appropiate image in the search result
In SearchResult.tsx
located in components/SearchResults.tsx
there was a runtime error:
Unhandled Runtime Error
TypeError: Cannot read properties of undefined (reading '0')
In particular, this section of code:
<img
alt={product.images[0].alt}
className="card-img-top"
height={300}
src={product.images[0].url}
style={{
width: 'auto',
height: 'auto',
}}
width={300}
/>
Specifically this line:
src={product.images[0].url}
I have rectified the issue by adding modifying the code slightly within the div of card product-card
and changed it to this:
{product.images && product.images.length > 0 && (
<img
alt={product.images[0].alt}
className="card-img-top"
height={300}
src={product.images[0].url}
style={{
width: 'auto',
height: 'auto',
}}
width={300}
/>
)}
Upon searching further on the web it appears the mistake arises from the code because it is accessing properties of an object that's undefined or an empty array
Modifying the code does generate the appropiate search result. However, there's no image. The code provided in the SearchResults.tsx
does look it's supported but I couldn't find an appropiate solution for that
@Timee2023 Good fine. I'm looking to rework and build out the tests. There are next to no tests right now.
I've fixed the issue where the images were not getting returned in the search results here.
Thanks. Those were all the errors I have discovered so far.
I have made some updates to SearchResult.tsx
personally for myself. Firstly, you can now click on the photos. Secondly, when you search for items, you can see the product summary and add it to your basket. Rather than clicking the product name and then adding it to the cart. I believe this mainly adds convenience.
/* eslint-disable @next/next/no-img-element */
/* eslint-disable @typescript-eslint/no-explicit-any */
import React, { useEffect, useState } from 'react';
import { useRouter } from 'next/router';
import Link from 'next/link';
import { useCart } from 'react-use-cart';
import { toast } from 'react-toastify';
import { currency } from '../lib/helpers';
const SearchResult = () => {
const router = useRouter();
const { addItem } = useCart();
const [searchTerm, setSearchTerm] = useState<any>();
const [searchResults, setSearchResults] = useState<any>();
useEffect(() => {
if (!router.isReady) {
return;
}
searchProducts();
}, [router.isReady]);
function searchProducts() {
const searchQuery = router.query.keyword;
setSearchTerm(searchQuery);
fetch('/api/search', {
method: 'POST',
cache: 'no-cache',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
searchTerm: searchQuery,
}),
})
.then(response => response.json())
.then(data => {
if (data.error) {
toast(data.error, {
hideProgressBar: false,
autoClose: 2000,
type: 'error',
});
setSearchResults([]);
return;
}
setSearchResults(data);
})
.catch(err => {
console.log('Payload error:' + err);
});
}
if (!searchResults) {
return <></>;
}
const mainImage = (product) => {
const imgProps = {
alt: 'product image',
className: 'card-img-top',
style: {
width: '100%',
height: '100%',
},
};
if (product.images.length === 0) {
return (
<Link href={`/product/${product.permalink}`}>
<div>
<img {...imgProps} />
</div>
</Link>
);
}
return (
<Link href={`/product/${product.permalink}`}>
<div>
<img
{...imgProps}
alt={product.images[0].alt}
src={product.images[0].url}
/>
</div>
</Link>
);
};
return (
<>
<div className="row row-cols-1 row-cols-sm-2 row-cols-md-3 g-3">
<h5>
Showing {searchResults.length} results for '
{searchTerm}'
</h5>
</div>
<div className="row row-cols-1 row-cols-sm-2 row-cols-md-3 g-3">
{searchResults.map(product => (
<div className="col" key={product.id}>
<div className="card product-card">
{mainImage(product)}
<div className="card-body">
<div className="card-text">
<Link
className="link-secondary"
href={`/product/${product.permalink}`}
>
<h2 className="h4">{product.name}</h2>
</Link>
<span className="h6 text-danger">
{currency(product.price / 100)}
</span>
<p>{product.summary}</p>
<div className="d-flex justify-content-between">
<div className="btn-group flex-fill">
<button
className="btn btn-dark"
onClick={() => {
addItem(product);
toast('Cart updated', {
hideProgressBar: false,
autoClose: 2000,
type: 'success',
});
}}
>
Add to cart
</button>
</div>
</div>
</div>
</div>
</div>
</div>
))}
</div>
</>
);
};
export default SearchResult;
@Timee2023 Awesome! I'd love to see the finished website when you have completed it.
Hi, feature request
Possible for you to add integration with Square payments?