As events evolve in the digital landscape, we might have seen some fun, engaging, and personalized event tickets shared on social media. This innovation is fascinating and showcases just how many excellent low-cost services and capabilities exist in web development.
This post will discuss building concert tickets using Cloudinary, Xata, and Next.js. At the end of this tutorial, we will learn how to store images on Cloudinary and explore the rich capabilities of Xata, a serverless database.
Check here for the source code on GitHub and the demo here.
Prerequisites
The knowledge of the following is required:
- Knowledge of JavaScript and React.js
- Node.js and its package manager, npm. We run the command
node -v&&npm -vto verify we have them installed or install them from here - Signup for a free Cloudinary account
- A Xata account
- Understanding Next.js would help us quickly follow this tutorial
Creating a Next.js application
To create the Next.js app, we go to our terminal or command line. Using the cd command, we navigate to the directory we want our to create our app.
cd <directory-name>
Once inside the directory, we create a new project using the command:
npx create-next-app
# or
yarn create next-app
Once that's finished, we navigate into that directory and start a hot-reloading development server for the project on http://localhost:3000 with:
npm run dev
#or
yarn dev
Installing Cloudinary
Cloudinary provides a robust solution to store, transform, optimize and deliver images and videos in software applications.
Install the cloudinary-react package that exposes various media delivery and transformation functions using the command line.
npm i cloudinary-react lodash
Lodash is a dependency of the Cloudinary package.
Installing TailwindCSS
TailwindCSS is a utility-first CSS framework packed with classes to help us style web pages.
We install tailwindcss and its peer dependencies via npm, which generates tailwind.config.js and postcss.config.js.
npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p
We need to add the paths to all of our template files in the tailwind.config.js file.
//tailwind.config.js
module.exports = {
content: [
"./pages/**/*.{js,ts,jsx,tsx}",
"./components/**/*.{js,ts,jsx,tsx}",
],
theme: {
extend: {},
},
plugins: [],
}
We should add the @tailwind directives for Tailwind’s layers to our ./styles/globals.css file.
//globals.css
@tailwind base;
@tailwind components;
@tailwind utilities;
Setting up the Xata database
Let’s create a new database on our Xata dashboard called concert-ticket
Click on the created database and add a table titled concert. Next, add concert_name and artist column of type String to the table.
Our database should look like this:
Setting up the Xata instance
To set up Xata, we'll need to install the CLI globally:
npm install @xata.io/cli -g
Then, authorize Xata to log us in:
xata auth login
Next, we select Create a new API key in the browser from the prompts in our terminal. This opens our browser, where we can type in any name we choose. Once successful, we will get a display page indicating that we are all set.
Now, let’s cd into the Nextjs project created earlier and run xata init to initialize Xata in our project;
cd <directory-name>
xata init
This is where we select the name of the database created earlier, then select Generate Javascript code with ES modules code and choose our output source as src/xata.js which is where the Xata codegen will be generated.
Image Upload to Cloudinary
In our dashboard, we will have access to upload and save the downloaded images in Cloudinary by clicking the Media Library tab and Upload button, as displayed below.
Next, we need to copy the publicId for the saved images from our dashboard, which will be necessary to generate the article banner.
Setting up the image collection
We’ll create a utils folder in the project root directory, where we need to create a ticket.json file to hold to data of the uploaded images.
Here is the JSON data for the ticket.json file.
[
{
"id": 1,
"publicId": "photo-1649894221695-45abb718a190_sgjhwd.jpg"
},
{
"id": 2,
"publicId": "photo-1649894222226-056a1a79d9fb_xlv73h.jpg"
},
{
"id": 3,
"publicId": "photo-1648800475313-2bb7fbec8701_ae60yw.jpg"
},
{
"id": 4,
"publicId": "photo-1647067867267-e01d98462f3c_ugtnwe.jpg"
},
{
"id": 5,
"publicId": "photo-1644241687200-eadaf7601290_xcz2kh.jpg"
}
]
Creating the concert ticket
With our project fully set up and configured, we can start building the concert ticket.
First, we need to modify the index.js file in the pages folder to the gist below:
From the code snippet in the gist, we:
- Import required dependencies and image collections
- Create state variables to manage selected Image ID, form data, and display the Concert ticket
- A
handleChange()function to control form inputs - Markups for form elements and conditionally render the list of Images using
cloudinary-react. The list of images also has anonClick()function that sets the current imageidto show the active image, the form object, and theshowCardproperty
By now, the application should look like this:
Next, we create a components folder in the root directory, and create a Concert.js file with the following snippet:
import { CloudinaryContext, Transformation, Image } from "cloudinary-react";
export const Concert = ({ message, name, publicId }) => {
return (
<div>
<CloudinaryContext cloudName="beswift">
<Image publicId={publicId} alt="image" width={1000} ref={ref}>
<Transformation crop="fit" effect="blur:100" />
<Transformation effect="brightness_hsb:-50" />
<Transformation
color="#FFFFFF"
overlay={{
background: "",
fontFamily: "Neucha",
fontSize: 150,
fontWeight: "bold",
text: message,
textAlign: "center",
}}
width="1300"
crop="fit"
/>
<Transformation flags="layer_apply" />
<Transformation
color="#FFFFFF"
overlay={{
fontFamily: "Dancing Script",
fontSize: 50,
fontWeight: "bold",
text: `Artist: ${name}`,
}}
/>
<Transformation
flags="layer_apply"
gravity="center"
x="450"
y="350"
/>
</Image>
</CloudinaryContext>
</div>
);
};
The snippet above does the following:
- Imports the required dependencies
- The
Concertcomponent accepts amessage,name, andpublicIdprops - Configure
CloudinaryContext,Image, andTransformationto render the image, message, and name - We also leverage Cloudinary to apply multiple transformations on the image. We added the following transformations, cropping, blurring, brightening, and adding overlays for text, text position, text properties, and flags to alter the position of the text
Then, we update index.js to conditionally render the Concert.js component as shown below:
//imports here
import { Concert } from '../components/Concert'; //add
export default function Home() {
//states here
const handleChange = (e) => {
//handle change codes here
};
//add
const handleSubmit = (e) => {
e.preventDefault();
if (imageId) {
setShowCard(true);
} else {
setFormData({ ...formData, error: true });
}
};
return (
<div className='p-10'>
{/* Head JSX comes here */}
<main className=''>
<h1 className='text-3xl'>Concert ticket</h1>
<header className='flex border-b-2 mt-7 mb-7'>
{/* Header contents JSX comes here */}
</header>
<form onSubmit={handleSubmit} className='lg:w-2/5'> {/* add handleSubmit */}
{/* Form contents JSX comes here */}
</form>
{/* Conditionally render card Components */}
{showCard && (
<div className='mt-10'>
<Concert
message={formData.message}
name={formData.name}
publicId={formData.publicId}
/>
</div>
)}
</main>
</div>
);
}
In the snippet above, we:
- Imported the
Concertcomponent - Created an
handleSubmitfunction that checks if an image is selected and then conditionally renders theConcertcomponent with necessaryprops
Storing data in the database
Let’s create a new file in the api folder and name it add-concert.js. Paste the code below in the file:
import { getXataClient } from "../../src/xata";
const handler = async (req, res) => {
const xata = await getXataClient();
const { concert_name, artist } =
req.body;
await xata.db.concert.create({
concert_name,
artist,
});
res.end();
};
export default handler;
We get the data sent to the API and save it to the Xata database.
Finally, we test our application by starting the development server and creating different event tickets.
We can right-click to copy the URL of the generated image.
Conclusion
This post discussed building a concert tickets generator using Cloudinary’s image transformation and saving data in the Xata database. Explore adding more text information to the image and a copy-to-clipboard function for the image URL.
Resources
We may find these resources helpful:






Top comments (0)