Flowchart Updated

This commit is contained in:
mukesh13
2025-08-11 16:08:29 +05:30
parent 2ced46ab8f
commit d2b2bc52d8
40 changed files with 1130 additions and 1357 deletions

View File

@ -30,21 +30,14 @@ const configs = {
sample: {
subject: 'SIF Form received for Project',
fields: [
// Customer Information
'Principal_Investigator', 'Email', 'Company_Institution', 'Contact_Number', 'Address', 'City', 'State', 'Pin',
'Secondary_Contact', 'Secondary_Email', 'Secondary_Company_Institution', 'Secondary_Contact_Number',
// Sample Information
'Project_Title', 'Number_of_Samples', 'Sample_Type', 'Sample_Type_Other', 'Sample_Source', 'Sample_Source_Other',
'Pathogenicity', 'Sample_Remarks',
// Service Information
'Service_Requested', 'Service_Requested_Other', 'Type_of_Library', 'Type_of_Library_Other',
'Required_Library_Size', 'Required_Library_Size_Other', 'Index_Information', 'Kit_Information',
'Sequencing_Platform', 'Sequencing_Platform_Other', 'Sequencing_Read_Length', 'Sequencing_Read_Length_Other',
'Total_Data_Requirement', 'Service_Remarks',
// Bioinformatics Information
'Analysis_Requested', 'Analysis_Details', 'Reference_Genome_Available', 'Genome_Size', 'Special_Consideration'
],
required: [
@ -58,6 +51,24 @@ const configs = {
}
};
// Serial number tracker
let serialTracker = {};
function generateSerialNumber() {
const today = new Date();
const dateKey = today.toISOString().slice(0, 10); // "YYYY-MM-DD"
if (!serialTracker[dateKey]) {
serialTracker[dateKey] = 1;
} else {
serialTracker[dateKey] += 1;
}
const serialNum = String(serialTracker[dateKey]).padStart(2, '0');
return {
serialNum,
formatted: `Operify Tech. ${today.getFullYear()}.${String(today.getMonth() + 1).padStart(2, '0')}.${String(today.getDate()).padStart(2, '0')}.${serialNum}`,
dateString: dateKey
};
}
// Utility functions
function isValidEmail(email) {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
@ -77,7 +88,6 @@ export async function GET() {
export async function POST(request) {
try {
// Parse form data
const formData = await request.formData();
const data = {};
const files = {};
@ -92,7 +102,6 @@ export async function POST(request) {
const form_type = data.form_type;
// Validate form type
if (!form_type || !configs[form_type]) {
return NextResponse.json({
error: 'Invalid form type: ' + (form_type || 'missing')
@ -102,7 +111,6 @@ export async function POST(request) {
const config = configs[form_type];
const errors = [];
// Validate required fields
for (const required_field of config.required) {
if (!data[required_field] || String(data[required_field]).trim() === '') {
errors.push(`The "${fieldName(required_field)}" field is required.`);
@ -111,37 +119,28 @@ export async function POST(request) {
}
}
// Validate file upload for career form
if (form_type === 'career') {
const fileField = config.file_field;
const uploadedFile = files[fileField];
if (!uploadedFile || uploadedFile.size === 0) {
errors.push('Please upload your resume.');
} else {
const allowedExtensions = ['pdf', 'doc', 'docx'];
const fileName = uploadedFile.name.toLowerCase();
const fileExtension = fileName.split('.').pop();
const fileExtension = uploadedFile.name.toLowerCase().split('.').pop();
if (!allowedExtensions.includes(fileExtension)) {
errors.push('Invalid file type. Please upload a PDF, DOC, or DOCX file.');
}
if (uploadedFile.size > 10 * 1024 * 1024) { // 10MB limit
if (uploadedFile.size > 10 * 1024 * 1024) {
errors.push('File is too large. Maximum size is 10MB.');
}
}
}
if (errors.length > 0) {
return NextResponse.json({
error: errors.join(' ')
}, { status: 400 });
return NextResponse.json({ error: errors.join(' ') }, { status: 400 });
}
// Construct email body
let emailBody = `<h2>${config.subject}</h2><table style="border: 1px solid #b5b5b5; padding: 5px;">`;
for (const [key, value] of Object.entries(data)) {
if (config.fields.includes(key) && key !== 'form_type' && key !== 'sample_details') {
emailBody += `<tr>
@ -151,7 +150,6 @@ export async function POST(request) {
}
}
// Add file info if uploaded
if (form_type === 'career' && files.resume) {
emailBody += `<tr>
<td style="border: 1px solid #b5b5b5; padding: 5px;"><strong>Resume</strong></td>
@ -159,20 +157,17 @@ export async function POST(request) {
</tr>`;
}
// Add sample details for sample form
if (form_type === 'sample' && data.sample_details) {
try {
const sampleDetails = JSON.parse(data.sample_details);
if (sampleDetails && sampleDetails.length > 0) {
if (sampleDetails.length > 0) {
emailBody += `<tr>
<td colspan="2" style="border: 1px solid #b5b5b5; padding: 10px; background-color: #e8f5f3; text-align: center;"><strong>SAMPLE DETAILS</strong></td>
</tr>`;
sampleDetails.forEach((sample, index) => {
emailBody += `<tr>
<td colspan="2" style="border: 1px solid #b5b5b5; padding: 8px; background-color: #f0f8f5; font-weight: bold;">Sample ${index + 1}</td>
</tr>`;
Object.entries(sample).forEach(([key, value]) => {
if (value && String(value).trim() !== '') {
emailBody += `<tr>
@ -183,25 +178,16 @@ export async function POST(request) {
});
});
}
} catch (error) {
console.error('Error parsing sample details:', error);
} catch {
emailBody += `<tr>
<td colspan="2" style="border: 1px solid #b5b5b5; padding: 5px; color: red;">Error: Could not parse sample details</td>
</tr>`;
}
}
emailBody += '</table>';
// Determine reply-to email based on form type
let replyToEmail;
if (form_type === 'sample') {
replyToEmail = data.Email;
} else {
replyToEmail = data.email;
}
let replyToEmail = form_type === 'sample' ? data.Email : data.email;
// Create transporter
const transporter = nodemailer.createTransport({
host: 'smtp.gmail.com',
port: 587,
@ -212,17 +198,24 @@ export async function POST(request) {
},
});
// Prepare email options
// SERIAL NUMBER LOGIC
let serialInfo;
if (form_type === 'sample') {
serialInfo = generateSerialNumber();
}
// Internal mail
const mailOptions = {
from: `${emailConfig.from_email_name} <${emailConfig.from_email}>`,
to: `${emailConfig.to_email_name} <${emailConfig.to_email}>`,
replyTo: replyToEmail || emailConfig.from_email,
subject: config.subject,
subject: form_type === 'sample'
? `${data.Company_Institution} | ${data.Principal_Investigator} | ${serialInfo.dateString} | ${serialInfo.formatted}`
: config.subject,
html: emailBody,
text: emailBody.replace(/<[^>]*>/g, ''), // Strip HTML for text version
text: emailBody.replace(/<[^>]*>/g, '')
};
// Add attachment for career form
if (form_type === 'career' && files.resume) {
const fileBuffer = await files.resume.arrayBuffer();
mailOptions.attachments = [{
@ -231,18 +224,24 @@ export async function POST(request) {
}];
}
// Send email
await transporter.sendMail(mailOptions);
return NextResponse.json({
success: true,
message: config.successMessage
});
// PI email for sample form
if (form_type === 'sample') {
const piMailOptions = {
from: `${emailConfig.from_email_name} <${emailConfig.from_email}>`,
to: `${data.Principal_Investigator} <${data.Email}>`,
subject: `SIF Form received for Project with - ${serialInfo.formatted}`,
html: emailBody,
text: emailBody.replace(/<[^>]*>/g, '')
};
await transporter.sendMail(piMailOptions);
}
return NextResponse.json({ success: true, message: config.successMessage });
} catch (error) {
console.error('Email sending error:', error);
return NextResponse.json({
error: 'Error sending email. Please try again later.'
}, { status: 500 });
return NextResponse.json({ error: 'Error sending email. Please try again later.' }, { status: 500 });
}
}
}

View File

@ -45,7 +45,7 @@ const NGSSection = () => {
description: "Rapid sequencing of large genetic material be completed within a comparatively short duration, thereby yielding quick results."
},
{
icon: "/images/homepage-1/service/Advantages-NGS-Icons-24.svg",
icon: "/images/homepage-1/service/BioinformaticsAnalysis.svg",
title: "Bioinformatics Analysis",
description: "NGS produces vast amounts of data, supporting complex research through advanced bioinformatic analysis."
}

View File

@ -6,7 +6,7 @@ const CareerPage = () => {
return (
<div className="page-content contact-us">
<CareerHero />
<div className="h-6"></div>
{/* <div className="h-2"></div> */}
<CareerSection />
</div>
);

View File

@ -4,7 +4,7 @@ import CareerInfo from './CareerInfo';
const CareerSection = () => {
return (
<section className="py-10 md:py-16 lg:py-6">
<section className="py-10 md:py-16 lg:py-2">
<div className="container mx-auto max-w-none px-4">
<div className="flex flex-col lg:flex-row gap-6">
<CareerInfo />

View File

@ -7,7 +7,7 @@ const ContactPage = () => {
return (
<div className="page-content contact-us">
<PageTitle />
<div className="h-6"></div>
{/* <div className="h-6"></div> */}
<ContactSection />
<ContactMap />
</div>

View File

@ -39,7 +39,7 @@ const Footer = () => {
</address>
{/* Social Links */}
<div className="flex space-x-4 mt-8">
<div className="flex mt-8">
<a
href="#"
target="_blank"
@ -136,7 +136,7 @@ const Footer = () => {
<div className="container mx-auto px-4 py-4">
<div className="flex flex-col md:flex-row justify-between items-center text-sm">
<p>
Copyright © 2024 <span className="text-gray-800 font-medium">Operify</span> All Rights Reserved.
Copyright © 2025 <span className="text-gray-800 font-medium">Operify</span> All Rights Reserved.
</p>
<ul className="flex space-x-6 mt-3 md:mt-0">
<li><Link href="#" className="hover:text-gray-800 transition-colors">Privacy Policy</Link></li>

View File

@ -142,8 +142,8 @@ const ShippingTemperatureTable = () => {
<table className="w-full border-collapse border border-gray-300 text-sm">
<colgroup>
<col style={{width: '25%'}} />
<col style={{width: '25%'}} />
<col style={{width: '50%'}} />
<col style={{width: '40%'}} />
<col style={{width: '35%'}} />
</colgroup>
<thead>
<tr className="bg-teal-50">

View File

@ -8,70 +8,29 @@ import SampleDetailsSection from './SampleDetailsSection';
const SampleFormContainer = () => {
const [formData, setFormData] = useState({
// Customer Information
Principal_Investigator: '',
Email: '',
Company_Institution: '',
Contact_Number: '',
Address: '',
City: '',
State: '',
Pin: '',
Secondary_Contact: '',
Secondary_Email: '',
Secondary_Company_Institution: '',
Secondary_Contact_Number: '',
// Sample Information
Project_Title: '',
Number_of_Samples: '',
Sample_Type: '',
Sample_Type_Other: '',
Sample_Source: '',
Sample_Source_Other: '',
Pathogenicity: '',
Sample_Remarks: '',
// Service Information
Service_Requested: '',
Service_Requested_Other: '',
Type_of_Library: '',
Type_of_Library_Other: '',
Required_Library_Size: '',
Required_Library_Size_Other: '',
Index_Information: '',
Kit_Information: '',
Sequencing_Platform: '',
Sequencing_Platform_Other: '',
Sequencing_Read_Length: '',
Sequencing_Read_Length_Other: '',
Total_Data_Requirement: '',
Service_Remarks: '',
// Bioinformatics Information
Analysis_Requested: '',
Analysis_Details: '',
Reference_Genome_Available: '',
Genome_Size: '',
Special_Consideration: '',
Principal_Investigator: '', Email: '', Company_Institution: '', Contact_Number: '',
Address: '', City: '', State: '', Pin: '', Secondary_Contact: '', Secondary_Email: '',
Secondary_Company_Institution: '', Secondary_Contact_Number: '', Project_Title: '',
Number_of_Samples: '', Sample_Type: '', Sample_Type_Other: '', Sample_Source: '',
Sample_Source_Other: '', Pathogenicity: '', Sample_Remarks: '', Service_Requested: '',
Service_Requested_Other: '', Type_of_Library: '', Type_of_Library_Other: '',
Required_Library_Size: '', Required_Library_Size_Other: '', Index_Information: '',
Kit_Information: '', Sequencing_Platform: '', Sequencing_Platform_Other: '',
Sequencing_Read_Length: '', Sequencing_Read_Length_Other: '', Total_Data_Requirement: '',
Service_Remarks: '', Analysis_Requested: '', Analysis_Details: '',
Reference_Genome_Available: '', Genome_Size: '', Special_Consideration: ''
});
const [sampleDetails, setSampleDetails] = useState([
{
Serial_Number: '',
Sample_Name: '',
Storage_Temp: '',
Preservative_Reagent: '',
Temp_Information: '',
Comments: ''
}
]);
const [sampleDetails, setSampleDetails] = useState([{
Serial_Number: '', Sample_Name: '', Storage_Temp: '',
Preservative_Reagent: '', Temp_Information: '', Comments: ''
}]);
const [isSubmitting, setIsSubmitting] = useState(false);
const [message, setMessage] = useState('');
const [showSuccessModal, setShowSuccessModal] = useState(false);
useEffect(() => {
// Check for Excel data in sessionStorage
const excelData = sessionStorage.getItem('excelData');
const uploadedFileName = sessionStorage.getItem('uploadedFileName');
@ -79,11 +38,8 @@ const SampleFormContainer = () => {
try {
const jsonData = JSON.parse(excelData);
autoFillForm(jsonData);
// Clear stored data
sessionStorage.removeItem('excelData');
sessionStorage.removeItem('uploadedFileName');
setMessage(`Form auto-filled from uploaded file: ${uploadedFileName}`);
} catch (error) {
console.error('Error parsing Excel data:', error);
@ -93,14 +49,10 @@ const SampleFormContainer = () => {
const autoFillForm = (jsonData) => {
if (jsonData.length === 0) return;
const data = jsonData[0];
const newFormData = { ...formData };
// Helper function to safely get value
const getValue = (key) => data[key] ? data[key].toString().trim() : '';
// Customer Information
newFormData.Principal_Investigator = getValue('Principal Investigator');
newFormData.Email = getValue('Email');
newFormData.Company_Institution = getValue('Company/Institution');
@ -114,7 +66,6 @@ const SampleFormContainer = () => {
newFormData.Secondary_Company_Institution = getValue('Secondary Company/Institution');
newFormData.Secondary_Contact_Number = getValue('Secondary Contact Number');
// Sample Information
newFormData.Project_Title = getValue('Project Title');
newFormData.Number_of_Samples = getValue('Number of Samples');
newFormData.Sample_Type = getValue('Sample Type');
@ -124,7 +75,6 @@ const SampleFormContainer = () => {
newFormData.Pathogenicity = getValue('Pathogenicity');
newFormData.Sample_Remarks = getValue('Sample Remarks');
// Service Information
newFormData.Service_Requested = getValue('Service Requested');
newFormData.Service_Requested_Other = getValue('Service Requested Other');
newFormData.Type_of_Library = getValue('Type of Library');
@ -140,7 +90,6 @@ const SampleFormContainer = () => {
newFormData.Total_Data_Requirement = getValue('Total Data Requirement');
newFormData.Service_Remarks = getValue('Service Remarks');
// Bioinformatics Information
newFormData.Analysis_Requested = getValue('Analysis Requested');
newFormData.Analysis_Details = getValue('Analysis Details');
newFormData.Reference_Genome_Available = getValue('Reference Genome Available');
@ -149,21 +98,20 @@ const SampleFormContainer = () => {
setFormData(newFormData);
// Handle Sample Details
const sampleDetailsData = jsonData.filter(row =>
row['Serial Number'] || row['Sample Name'] ||
row['Storage Temp'] || row['Preservative Reagent'] ||
const sampleDetailsData = jsonData.filter(row =>
row['Serial Number'] || row['Sample Name'] ||
row['Storage Temp'] || row['Preservative Reagent'] ||
row['Temp Information'] || row['Comments']
);
if (sampleDetailsData.length > 0) {
const newSampleDetails = sampleDetailsData.map(sample => ({
Serial_Number: getValue('Serial Number'),
Sample_Name: getValue('Sample Name'),
Storage_Temp: getValue('Storage Temp'),
Preservative_Reagent: getValue('Preservative Reagent'),
Temp_Information: getValue('Temp Information'),
Comments: getValue('Comments')
Serial_Number: sample['Serial Number'] || '',
Sample_Name: sample['Sample Name'] || '',
Storage_Temp: sample['Storage Temp'] || '',
Preservative_Reagent: sample['Preservative Reagent'] || '',
Temp_Information: sample['Temp Information'] || '',
Comments: sample['Comments'] || ''
}));
setSampleDetails(newSampleDetails);
}
@ -179,37 +127,28 @@ const SampleFormContainer = () => {
const handleSubmit = async (e) => {
e.preventDefault();
setIsSubmitting(true);
setMessage(''); // Clear previous messages
setMessage('');
try {
const formDataToSend = new FormData();
// Add form data
Object.keys(formData).forEach(key => {
if (formData[key]) {
formDataToSend.append(key, formData[key]);
}
});
// Add sample details as JSON string
formDataToSend.append('sample_details', JSON.stringify(sampleDetails));
formDataToSend.append('form_type', 'sample');
console.log('Submitting form data:', formData);
console.log('Sample details:', sampleDetails);
const response = await fetch('/api/forms', {
method: 'POST',
body: formDataToSend,
});
const result = await response.json();
console.log('API Response:', result);
if (response.ok) {
setMessage(result.message);
// Reset form after successful submission
setShowSuccessModal(true); // show modal instead of green alert
setFormData({
Principal_Investigator: '', Email: '', Company_Institution: '', Contact_Number: '',
Address: '', City: '', State: '', Pin: '', Secondary_Contact: '', Secondary_Email: '',
@ -223,7 +162,6 @@ const SampleFormContainer = () => {
Service_Remarks: '', Analysis_Requested: '', Analysis_Details: '',
Reference_Genome_Available: '', Genome_Size: '', Special_Consideration: ''
});
setSampleDetails([{
Serial_Number: '', Sample_Name: '', Storage_Temp: '',
Preservative_Reagent: '', Temp_Information: '', Comments: ''
@ -231,7 +169,6 @@ const SampleFormContainer = () => {
} else {
setMessage('Error: ' + (result.error || 'Form submission failed'));
}
} catch (error) {
console.error('Error submitting form:', error);
setMessage('Error: Network error. Please check your connection and try again.');
@ -244,41 +181,22 @@ const SampleFormContainer = () => {
<div className="bg-teal-50 min-h-screen py-8">
<div className="max-w-4xl mx-auto bg-teal-50 shadow-lg border border-gray-300 font-arial text-xs">
<form onSubmit={handleSubmit} className="space-y-6">
{/* Show message if exists */}
{message && (
{/* Only show red alert for errors */}
{message && message.includes('Error') && (
<div className="mx-6 mt-6">
<div className={`p-4 rounded ${message.includes('Error') ? 'bg-red-100 text-red-800' : 'bg-green-100 text-green-800'}`}>
<div className="p-4 rounded bg-red-100 text-red-800">
{message}
</div>
</div>
)}
<CustomerInfoSection
formData={formData}
onInputChange={handleInputChange}
/>
<SampleInfoSection
formData={formData}
onInputChange={handleInputChange}
/>
<ServiceInfoSection
formData={formData}
onInputChange={handleInputChange}
/>
<BioinformaticsSection
formData={formData}
onInputChange={handleInputChange}
/>
<SampleDetailsSection
sampleDetails={sampleDetails}
setSampleDetails={setSampleDetails}
/>
<CustomerInfoSection formData={formData} onInputChange={handleInputChange} />
<SampleInfoSection formData={formData} onInputChange={handleInputChange} />
<ServiceInfoSection formData={formData} onInputChange={handleInputChange} />
<BioinformaticsSection formData={formData} onInputChange={handleInputChange} />
<SampleDetailsSection sampleDetails={sampleDetails} setSampleDetails={setSampleDetails} />
{/* Submit Button */}
<div className="text-center py-6">
<button
type="submit"
@ -290,8 +208,50 @@ const SampleFormContainer = () => {
</div>
</form>
</div>
{/* Success Modal */}
{/* Success Modal */}
{showSuccessModal && (
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
<div className="bg-white rounded-lg shadow-lg p-6 max-w-sm w-full text-center animate-pulse">
{/* Animated Check Circle */}
<div className="flex justify-center mb-4">
<div className="relative">
{/* Outer ring animation */}
<div className="w-20 h-20 border-4 border-green-200 rounded-full animate-ping absolute"></div>
<div className="w-16 h-16 bg-green-500 rounded-full flex items-center justify-center animate-bounce relative z-10">
{/* Checkmark */}
<svg
className="w-10 h-10 text-white animate-pulse"
fill="none"
stroke="currentColor"
viewBox="0 0 24 24"
xmlns="http://www.w3.org/2000/svg"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="4"
d="M5 13l4 4L19 7"
/>
</svg>
</div>
</div>
</div>
<h2 className="text-lg font-semibold text-green-700 mb-4 animate-pulse">Submitted Successfully!</h2>
<p className="text-gray-700 mb-6">{message}</p>
<button
onClick={() => setShowSuccessModal(false)}
className="bg-teal-600 hover:bg-teal-700 text-white py-2 px-4 rounded transition-all duration-200 transform hover:scale-105"
>
OK
</button>
</div>
</div>
)}
</div>
);
};
export default SampleFormContainer;
export default SampleFormContainer;

View File

@ -1,96 +1,49 @@
import React from 'react';
import { ArrowDown, ArrowRight, ArrowUp } from 'lucide-react';
const EnrichmentPipeline = ({
title = "Bioinformatics Pipeline",
leftSteps = [
"Raw Sequencing Data (fastq files)",
"Quality Control and Preprocessing of Data",
"High Quality Sequencing Data (fastq file)",
"Alignment to Reference Genome"
],
rightSteps = [
"Downstream Advanced Analysis",
"Annotation",
"Variants Calling - SNVs, Indels, CNVs",
"Mark Duplicates and Post-Processing"
],
svgContent = null, // Pass your SVG content here as JSX
svgUrl = "/images/flowchart/resequencing.svg",
backgroundColor = "bg-gray-50",
cardColor = "bg-gray-300",
textColor = "text-teal-600",
arrowColor = "text-gray-600",
textColor = "text-gray-700",
className = "",
cardClassName = "",
titleClassName = ""
titleClassName = "",
svgClassName = "",
containerClassName = ""
}) => {
// Combine steps for mobile layout
const mobileSteps = [...leftSteps, ...rightSteps.slice().reverse()];
return (
<section className={`py-6 sm:py-8 lg:py-12 ${backgroundColor} ${className}`}>
<div className="container mx-auto max-w-none px-3 sm:px-4 lg:px-6">
<h2 className={`text-gray-700 text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
<div className={`container mx-auto max-w-none px-3 sm:px-4 lg:px-6 ${containerClassName}`}>
<h2 className={`${textColor} text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
{title}
</h2>
{/* Pipeline Flowchart */}
{/* SVG Flowchart Container */}
<div className="bg-white rounded-xl shadow-lg p-4 sm:p-6 lg:p-8">
<div className="flex justify-center">
<div className="w-full max-w-5xl">
<div className="relative">
{/* Mobile Layout - Single Column */}
<div className="block sm:hidden">
<div className="flex flex-col items-center space-y-3">
{mobileSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 w-full text-center border ${cardClassName}`}>
<h3 className={`text-xs font-medium ${textColor}`}>{step}</h3>
</div>
{index < mobileSteps.length - 1 && (
<ArrowDown className={`w-5 h-5 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
</div>
{/* Tablet and Desktop Layout - Two Columns */}
<div className="hidden sm:block">
<div className="grid grid-cols-2 gap-4 sm:gap-6 lg:gap-8">
{/* Left Column */}
<div className="flex flex-col items-center space-y-2 sm:space-y-3">
{leftSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 sm:p-4 w-full max-w-80 text-center border ${cardClassName}`}>
<h3 className={`text-xs sm:text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < leftSteps.length - 1 && (
<ArrowDown className={`w-5 h-5 sm:w-6 sm:h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
{/* Right Column */}
<div className="flex flex-col items-center space-y-2 sm:space-y-3">
{rightSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 sm:p-4 w-full max-w-80 text-center border ${cardClassName}`}>
<h3 className={`text-xs sm:text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < rightSteps.length - 1 && (
<ArrowUp className={`w-5 h-5 sm:w-6 sm:h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
<div className="w-full max-w-6xl">
{/* SVG Container with responsive sizing */}
<div className={`w-full ${svgClassName}`}>
{svgUrl ? (
// If SVG URL/path is provided
<img
src={svgUrl}
alt="Flowchart diagram"
className="w-full h-auto object-contain"
/>
) : svgContent ? (
// If SVG content is provided as JSX
<div className="w-full">
<div className="w-full">
{svgContent}
</div>
</div>
{/* Horizontal Arrow positioned between Primary and Secondary Assembly */}
<div className="absolute bottom-2 sm:bottom-4 lg:bottom-[0.7rem] left-1/2 transform -translate-x-1/2 flex items-center justify-center">
<ArrowRight className={`w-6 h-6 sm:w-8 sm:h-8 ${arrowColor}`} />
) : (
// Fallback message
<div className="flex items-center justify-center h-40 text-gray-500">
<p>Please provide SVG content or URL</p>
</div>
</div>
)}
</div>
</div>
</div>

View File

@ -1,126 +1,49 @@
import React from 'react';
import { ArrowDown, ArrowRight, ArrowUp } from 'lucide-react';
const EpigenomicsPipeline = ({
title = "Bioinformatics Pipeline",
leftSteps = [
"Raw Sequencing Data (fastq files)",
"Quality Control and Preprocessing of Data",
"High Quality Sequencing Data (fastq file)",
"Aligned to Reference Genome"
],
middleSteps = [
"Downstream Advanced Analysis",
"DMR Annotation",
"DMR Identification",
"Peak Calling"
],
rightSteps = [
"Distribution in genes & repeats",
"Methylated Distribution",
"Motif Identification",
"Relationship with gene expression",
"Go clustering",
"Pathway analysis"
],
svgContent = null, // Pass your SVG content here as JSX
svgUrl = "/images/flowchart/epigenomics.svg",
backgroundColor = "bg-gray-50",
cardColor = "bg-gray-300",
textColor = "text-teal-600",
arrowColor = "text-gray-600",
textColor = "text-gray-700",
className = "",
cardClassName = "",
titleClassName = ""
titleClassName = "",
svgClassName = "",
containerClassName = ""
}) => {
// Combine steps for mobile layout
const mobileSteps = [...leftSteps, ...middleSteps, ...rightSteps];
return (
<section className={`py-6 sm:py-8 lg:py-12 ${backgroundColor} ${className}`}>
<div className="container mx-auto max-w-none px-3 sm:px-4 lg:px-6">
<h2 className={`text-gray-700 text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
<div className={`container mx-auto max-w-none px-3 sm:px-4 lg:px-6 ${containerClassName}`}>
<h2 className={`${textColor} text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
{title}
</h2>
{/* Pipeline Flowchart */}
{/* SVG Flowchart Container */}
<div className="bg-white rounded-xl shadow-lg p-4 sm:p-6 lg:p-8">
<div className="flex justify-center">
<div className="w-full max-w-7xl">
<div className="relative">
{/* Mobile Layout - Single Column */}
<div className="block lg:hidden">
<div className="flex flex-col items-center space-y-3">
{mobileSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 w-full text-center border ${cardClassName}`}>
<h3 className={`text-xs font-medium ${textColor}`}>{step}</h3>
</div>
{index < mobileSteps.length - 1 && (
<ArrowDown className={`w-5 h-5 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
</div>
{/* Desktop Layout - Three Columns */}
<div className="hidden lg:block">
<div className="grid grid-cols-3 gap-6 lg:gap-8">
{/* Left Column */}
<div className="flex flex-col items-center space-y-3">
{leftSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-4 w-full max-w-76 text-center border ${cardClassName}`} style={{maxWidth: '19rem'}}>
<h3 className={`text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < leftSteps.length - 1 && (
<ArrowDown className={`w-6 h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
{/* Middle Column */}
<div className="flex flex-col items-center space-y-3">
{middleSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-4 w-full max-w-76 text-center border ${cardClassName}`} style={{maxWidth: '19rem'}}>
<h3 className={`text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < middleSteps.length - 1 && (
<ArrowUp className={`w-6 h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
{/* Right Column */}
<div className="flex flex-col items-center justify-center">
<div className={`${cardColor} rounded-lg p-12 w-full max-w-76 text-center border ${cardClassName}`} style={{maxWidth: '19rem'}}>
<div className="space-y-6">
{rightSteps.map((step, index) => (
<div key={index} className={`text-sm font-medium ${textColor}`}>
{step}
</div>
))}
</div>
</div>
<div className="w-full max-w-6xl">
{/* SVG Container with responsive sizing */}
<div className={`w-full ${svgClassName}`}>
{svgUrl ? (
// If SVG URL/path is provided
<img
src={svgUrl}
alt="Flowchart diagram"
className="w-full h-auto object-contain"
/>
) : svgContent ? (
// If SVG content is provided as JSX
<div className="w-full">
<div className="w-full">
{svgContent}
</div>
</div>
{/* Horizontal Arrows */}
{/* Arrow from Aligned to Reference Genome to Peak Calling */}
<div className="absolute bottom-4 left-1/3 transform -translate-x-1/2">
<ArrowRight className={`w-8 h-8 ${arrowColor}`} />
) : (
// Fallback message
<div className="flex items-center justify-center h-40 text-gray-500">
<p>Please provide SVG content or URL</p>
</div>
{/* Arrow from DMR Annotation to right box */}
<div className="absolute top-28 left-2/3 transform -translate-x-1/2">
<ArrowRight className={`w-8 h-8 ${arrowColor}`} />
</div>
{/* Arrow from Peak Calling to right box */}
<div className="absolute bottom-4 left-2/3 transform -translate-x-1/2">
<ArrowRight className={`w-8 h-8 ${arrowColor}`} />
</div>
</div>
)}
</div>
</div>
</div>

View File

@ -1,96 +1,49 @@
import React from 'react';
import { ArrowDown, ArrowRight, ArrowUp } from 'lucide-react';
const GenomeMappingPipeline = ({
title = "Bioinformatics Pipeline",
leftSteps = [
"Raw Sequencing Data (fastq files)",
"Quality Control and Preprocessing of Data",
"High Quality Sequencing Data (fastq file)",
"Alignment to Reference Genome"
],
rightSteps = [
"Evolutionary Analysis",
"Annotation",
"Variants Calling - structural variants and genomic rearrangements",
"Post-Processing"
],
svgContent = null, // Pass your SVG content here as JSX
svgUrl = "/images/flowchart/genoemapping.svg",
backgroundColor = "bg-gray-50",
cardColor = "bg-gray-300",
textColor = "text-teal-600",
arrowColor = "text-gray-600",
textColor = "text-gray-700",
className = "",
cardClassName = "",
titleClassName = ""
titleClassName = "",
svgClassName = "",
containerClassName = ""
}) => {
// Combine steps for mobile layout
const mobileSteps = [...leftSteps, ...rightSteps.slice().reverse()];
return (
<section className={`py-6 sm:py-8 lg:py-12 ${backgroundColor} ${className}`}>
<div className="container mx-auto max-w-none px-3 sm:px-4 lg:px-6">
<h2 className={`text-gray-700 text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
<div className={`container mx-auto max-w-none px-3 sm:px-4 lg:px-6 ${containerClassName}`}>
<h2 className={`${textColor} text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
{title}
</h2>
{/* Pipeline Flowchart */}
{/* SVG Flowchart Container */}
<div className="bg-white rounded-xl shadow-lg p-4 sm:p-6 lg:p-8">
<div className="flex justify-center">
<div className="w-full max-w-5xl">
<div className="relative">
{/* Mobile Layout - Single Column */}
<div className="block sm:hidden">
<div className="flex flex-col items-center space-y-3">
{mobileSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 w-full text-center border ${cardClassName}`}>
<h3 className={`text-xs font-medium ${textColor}`}>{step}</h3>
</div>
{index < mobileSteps.length - 1 && (
<ArrowDown className={`w-5 h-5 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
</div>
{/* Tablet and Desktop Layout - Two Columns */}
<div className="hidden sm:block">
<div className="grid grid-cols-2 gap-4 sm:gap-6 lg:gap-8">
{/* Left Column */}
<div className="flex flex-col items-center space-y-2 sm:space-y-3">
{leftSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 sm:p-4 w-full max-w-80 text-center border ${cardClassName}`}>
<h3 className={`text-xs sm:text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < leftSteps.length - 1 && (
<ArrowDown className={`w-5 h-5 sm:w-6 sm:h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
{/* Right Column */}
<div className="flex flex-col items-center space-y-2 sm:space-y-3">
{rightSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 sm:p-4 w-full max-w-80 text-center border ${cardClassName}`}>
<h3 className={`text-xs sm:text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < rightSteps.length - 1 && (
<ArrowUp className={`w-5 h-5 sm:w-6 sm:h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
<div className="w-full max-w-6xl">
{/* SVG Container with responsive sizing */}
<div className={`w-full ${svgClassName}`}>
{svgUrl ? (
// If SVG URL/path is provided
<img
src={svgUrl}
alt="Flowchart diagram"
className="w-full h-auto object-contain"
/>
) : svgContent ? (
// If SVG content is provided as JSX
<div className="w-full">
<div className="w-full">
{svgContent}
</div>
</div>
{/* Horizontal Arrow positioned between Primary and Secondary Assembly */}
<div className="absolute bottom-2 sm:bottom-4 lg:bottom-[0.7rem] left-1/2 transform -translate-x-1/2 flex items-center justify-center">
<ArrowRight className={`w-6 h-6 sm:w-8 sm:h-8 ${arrowColor}`} />
) : (
// Fallback message
<div className="flex items-center justify-center h-40 text-gray-500">
<p>Please provide SVG content or URL</p>
</div>
</div>
)}
</div>
</div>
</div>

View File

@ -1,124 +1,49 @@
import React from 'react';
import { ArrowDown, ArrowRight, ArrowUp } from 'lucide-react';
const MetagenomicsPipeline = ({
title = "Bioinformatics Pipeline",
leftColumn = [
"Raw Sequencing Data (fastq files)",
"Quality Control and Preprocessing of Data",
"High Quality Sequencing Data (fastq file)",
"Alignment to Host Genome"
],
middleColumn = [
"Assembly Validation",
"Secondary Assembly (Scaffolds)",
"Primary Assembly (Contigs) using Unaligned Data",
"Remove Aligned reads to Host Genome and Retain only Unaligned Reads"
],
rightColumn = [
"Gene Prediction and Gene Annotation",
"Downstream Advanced Analysis"
],
svgContent = null, // Pass your SVG content here as JSX
svgUrl = "/images/flowchart/metagenomics.svg",
backgroundColor = "bg-gray-50",
cardColor = "bg-gray-300",
textColor = "text-teal-600",
arrowColor = "text-gray-600",
textColor = "text-gray-700",
className = "",
cardClassName = "",
titleClassName = ""
titleClassName = "",
svgClassName = "",
containerClassName = ""
}) => {
// Combine all steps for mobile layout
const mobileSteps = [
...leftColumn,
...middleColumn.slice().reverse(),
...rightColumn
];
return (
<section className={`py-6 sm:py-8 lg:py-12 ${backgroundColor} ${className}`}>
<div className="container mx-auto max-w-none px-3 sm:px-4 lg:px-6">
<h2 className={`text-gray-600 text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
<div className={`container mx-auto max-w-none px-3 sm:px-4 lg:px-6 ${containerClassName}`}>
<h2 className={`${textColor} text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
{title}
</h2>
{/* Pipeline Flowchart */}
{/* SVG Flowchart Container */}
<div className="bg-white rounded-xl shadow-lg p-4 sm:p-6 lg:p-8">
<div className="flex justify-center">
<div className="w-full max-w-6xl">
<div className="relative">
{/* Mobile Layout - Single Column */}
<div className="block lg:hidden">
<div className="flex flex-col items-center space-y-3">
{mobileSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 w-full text-center border ${cardClassName}`}>
<h3 className={`text-xs font-medium ${textColor}`}>{step}</h3>
</div>
{index < mobileSteps.length - 1 && (
<ArrowDown className={`w-5 h-5 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
</div>
{/* Desktop Layout - Three Columns */}
<div className="hidden lg:block">
<div className="grid grid-cols-3 gap-6 lg:gap-10">
{/* Left Column */}
<div className="flex flex-col items-center space-y-3">
{leftColumn.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-4 w-full text-center border ${cardClassName}`}>
<h3 className={`text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < leftColumn.length - 1 && (
<ArrowDown className={`w-6 h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
{/* Middle Column */}
<div className="flex flex-col items-center space-y-3">
{middleColumn.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-4 w-full text-center border ${cardClassName}`}>
<h3 className={`text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < middleColumn.length - 1 && (
<ArrowUp className={`w-6 h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
{/* Right Column */}
<div className="flex flex-col items-center space-y-3">
{rightColumn.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-4 w-full text-center border ${cardClassName}`}>
<h3 className={`text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < rightColumn.length - 1 && (
<ArrowDown className={`w-6 h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
{/* SVG Container with responsive sizing */}
<div className={`w-full ${svgClassName}`}>
{svgUrl ? (
// If SVG URL/path is provided
<img
src={svgUrl}
alt="Flowchart diagram"
className="w-full h-auto object-contain"
/>
) : svgContent ? (
// If SVG content is provided as JSX
<div className="w-full">
<div className="w-full">
{svgContent}
</div>
</div>
{/* Horizontal Arrows */}
{/* Arrow from left to middle column */}
<div className="absolute bottom-8 left-1/3 transform -translate-x-1/2 flex items-center justify-center">
<ArrowRight className={`w-8 h-8 ${arrowColor}`} />
) : (
// Fallback message
<div className="flex items-center justify-center h-40 text-gray-500">
<p>Please provide SVG content or URL</p>
</div>
{/* Arrow from middle to right column */}
<div className="absolute top-4 right-1/3 transform translate-x-1/2 flex items-center justify-center">
<ArrowRight className={`w-8 h-8 ${arrowColor}`} />
</div>
</div>
)}
</div>
</div>
</div>

View File

@ -1,96 +1,49 @@
import React from 'react';
import { ArrowDown, ArrowRight, ArrowUp } from 'lucide-react';
const SingleCellPipeline = ({
title = "Bioinformatics Pipeline",
leftSteps = [
"Raw Sequencing Data (fastq files)",
"Quality Control and Preprocessing of Data",
"High Quality Sequencing Data (fastq file)",
"Alignment to Reference Genome"
],
rightSteps = [
"Evolutionary Analysis",
"Annotation",
"Variants Calling - SNVs, Indels, CNVs",
"Mark Duplicates and Post-Processing"
],
svgContent = null, // Pass your SVG content here as JSX
svgUrl = "/images/flowchart/singlecell.svg",
backgroundColor = "bg-gray-50",
cardColor = "bg-gray-300",
textColor = "text-teal-600",
arrowColor = "text-gray-600",
textColor = "text-gray-700",
className = "",
cardClassName = "",
titleClassName = ""
titleClassName = "",
svgClassName = "",
containerClassName = ""
}) => {
// Combine steps for mobile layout
const mobileSteps = [...leftSteps, ...rightSteps.slice().reverse()];
return (
<section className={`py-6 sm:py-8 lg:py-12 ${backgroundColor} ${className}`}>
<div className="container mx-auto max-w-none px-3 sm:px-4 lg:px-6">
<h2 className={`text-gray-700 text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
<div className={`container mx-auto max-w-none px-3 sm:px-4 lg:px-6 ${containerClassName}`}>
<h2 className={`${textColor} text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
{title}
</h2>
{/* Pipeline Flowchart */}
{/* SVG Flowchart Container */}
<div className="bg-white rounded-xl shadow-lg p-4 sm:p-6 lg:p-8">
<div className="flex justify-center">
<div className="w-full max-w-5xl">
<div className="relative">
{/* Mobile Layout - Single Column */}
<div className="block sm:hidden">
<div className="flex flex-col items-center space-y-3">
{mobileSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 w-full text-center border ${cardClassName}`}>
<h3 className={`text-xs font-medium ${textColor}`}>{step}</h3>
</div>
{index < mobileSteps.length - 1 && (
<ArrowDown className={`w-5 h-5 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
</div>
{/* Tablet and Desktop Layout - Two Columns */}
<div className="hidden sm:block">
<div className="grid grid-cols-2 gap-4 sm:gap-6 lg:gap-8">
{/* Left Column */}
<div className="flex flex-col items-center space-y-2 sm:space-y-3">
{leftSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 sm:p-4 w-full max-w-80 text-center border ${cardClassName}`}>
<h3 className={`text-xs sm:text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < leftSteps.length - 1 && (
<ArrowDown className={`w-5 h-5 sm:w-6 sm:h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
{/* Right Column */}
<div className="flex flex-col items-center space-y-2 sm:space-y-3">
{rightSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 sm:p-4 w-full max-w-80 text-center border ${cardClassName}`}>
<h3 className={`text-xs sm:text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < rightSteps.length - 1 && (
<ArrowUp className={`w-5 h-5 sm:w-6 sm:h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
<div className="w-full max-w-6xl">
{/* SVG Container with responsive sizing */}
<div className={`w-full ${svgClassName}`}>
{svgUrl ? (
// If SVG URL/path is provided
<img
src={svgUrl}
alt="Flowchart diagram"
className="w-full h-auto object-contain"
/>
) : svgContent ? (
// If SVG content is provided as JSX
<div className="w-full">
<div className="w-full">
{svgContent}
</div>
</div>
{/* Horizontal Arrow positioned between Primary and Secondary Assembly */}
<div className="absolute bottom-2 sm:bottom-4 lg:bottom-[0.7rem] left-1/2 transform -translate-x-1/2 flex items-center justify-center">
<ArrowRight className={`w-6 h-6 sm:w-8 sm:h-8 ${arrowColor}`} />
) : (
// Fallback message
<div className="flex items-center justify-center h-40 text-gray-500">
<p>Please provide SVG content or URL</p>
</div>
</div>
)}
</div>
</div>
</div>

View File

@ -1,96 +1,49 @@
import React from 'react';
import { ArrowDown, ArrowRight, ArrowUp } from 'lucide-react';
const WGSDeNovoPipeline = ({
title = "Bioinformatics Pipeline",
leftSteps = [
"Raw Sequencing Data (fastq files)",
"Quality Control and Preprocessing of Data",
"High Quality Sequencing Data (fastq file)",
"Primary Assembly (Contigs)"
],
rightSteps = [
"Downstream Advanced Analysis",
"Gene Prediction and Gene Annotation",
"Assembly Validation",
"Secondary Assembly (Scaffolds)"
],
svgContent = null, // Pass your SVG content here as JSX
svgUrl = "/images/flowchart/denovo.svg",
backgroundColor = "bg-gray-50",
cardColor = "bg-gray-300",
textColor = "text-teal-600",
arrowColor = "text-gray-600",
textColor = "text-gray-700",
className = "",
cardClassName = "",
titleClassName = ""
titleClassName = "",
svgClassName = "",
containerClassName = ""
}) => {
// Combine steps for mobile layout
const mobileSteps = [...leftSteps, ...rightSteps.slice().reverse()];
return (
<section className={`py-6 sm:py-8 lg:py-12 ${backgroundColor} ${className}`}>
<div className="container mx-auto max-w-none px-3 sm:px-4 lg:px-6">
<h2 className={`text-gray-700 text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
<div className={`container mx-auto max-w-none px-3 sm:px-4 lg:px-6 ${containerClassName}`}>
<h2 className={`${textColor} text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
{title}
</h2>
{/* Pipeline Flowchart */}
{/* SVG Flowchart Container */}
<div className="bg-white rounded-xl shadow-lg p-4 sm:p-6 lg:p-8">
<div className="flex justify-center">
<div className="w-full max-w-5xl">
<div className="relative">
{/* Mobile Layout - Single Column */}
<div className="block sm:hidden">
<div className="flex flex-col items-center space-y-3">
{mobileSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 w-full text-center border ${cardClassName}`}>
<h3 className={`text-xs font-medium ${textColor}`}>{step}</h3>
</div>
{index < mobileSteps.length - 1 && (
<ArrowDown className={`w-5 h-5 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
</div>
{/* Tablet and Desktop Layout - Two Columns */}
<div className="hidden sm:block">
<div className="grid grid-cols-2 gap-4 sm:gap-6 lg:gap-8">
{/* Left Column */}
<div className="flex flex-col items-center space-y-2 sm:space-y-3">
{leftSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 sm:p-4 w-full max-w-80 text-center border ${cardClassName}`}>
<h3 className={`text-xs sm:text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < leftSteps.length - 1 && (
<ArrowDown className={`w-5 h-5 sm:w-6 sm:h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
{/* Right Column */}
<div className="flex flex-col items-center space-y-2 sm:space-y-3">
{rightSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 sm:p-4 w-full max-w-80 text-center border ${cardClassName}`}>
<h3 className={`text-xs sm:text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < rightSteps.length - 1 && (
<ArrowUp className={`w-5 h-5 sm:w-6 sm:h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
<div className="w-full max-w-6xl">
{/* SVG Container with responsive sizing */}
<div className={`w-full ${svgClassName}`}>
{svgUrl ? (
// If SVG URL/path is provided
<img
src={svgUrl}
alt="Flowchart diagram"
className="w-full h-auto object-contain"
/>
) : svgContent ? (
// If SVG content is provided as JSX
<div className="w-full">
<div className="w-full">
{svgContent}
</div>
</div>
{/* Horizontal Arrow positioned between Primary and Secondary Assembly */}
<div className="absolute bottom-2 sm:bottom-4 lg:bottom-[0.7rem] left-1/2 transform -translate-x-1/2 flex items-center justify-center">
<ArrowRight className={`w-6 h-6 sm:w-8 sm:h-8 ${arrowColor}`} />
) : (
// Fallback message
<div className="flex items-center justify-center h-40 text-gray-500">
<p>Please provide SVG content or URL</p>
</div>
</div>
)}
</div>
</div>
</div>

View File

@ -1,96 +1,49 @@
import React from 'react';
import { ArrowDown, ArrowRight, ArrowUp } from 'lucide-react';
const WGSResequencingPipeline = ({
title = "Bioinformatics Pipeline",
leftSteps = [
"Raw Sequencing Data (fastq files)",
"Quality Control and Preprocessing of Data",
"High Quality Sequencing Data (fastq file)",
"Alignment to Reference Genome"
],
rightSteps = [
"Downstream Advanced Analysis",
"Annotation",
"Variants Calling - SNVs, Indels, CNVs",
"Mark Duplicates and Post-Processing"
],
svgContent = null, // Pass your SVG content here as JSX
svgUrl = "/images/flowchart/resequencing.svg",
backgroundColor = "bg-gray-50",
cardColor = "bg-gray-300",
textColor = "text-teal-600",
arrowColor = "text-gray-600",
textColor = "text-gray-700",
className = "",
cardClassName = "",
titleClassName = ""
titleClassName = "",
svgClassName = "",
containerClassName = ""
}) => {
// Combine steps for mobile layout
const mobileSteps = [...leftSteps, ...rightSteps.slice().reverse()];
return (
<section className={`py-6 sm:py-8 lg:py-12 ${backgroundColor} ${className}`}>
<div className="container mx-auto max-w-none px-3 sm:px-4 lg:px-6">
<h2 className={`text-gray-700 text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
<div className={`container mx-auto max-w-none px-3 sm:px-4 lg:px-6 ${containerClassName}`}>
<h2 className={`${textColor} text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
{title}
</h2>
{/* Pipeline Flowchart */}
{/* SVG Flowchart Container */}
<div className="bg-white rounded-xl shadow-lg p-4 sm:p-6 lg:p-8">
<div className="flex justify-center">
<div className="w-full max-w-5xl">
<div className="relative">
{/* Mobile Layout - Single Column */}
<div className="block sm:hidden">
<div className="flex flex-col items-center space-y-3">
{mobileSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 w-full text-center border ${cardClassName}`}>
<h3 className={`text-xs font-medium ${textColor}`}>{step}</h3>
</div>
{index < mobileSteps.length - 1 && (
<ArrowDown className={`w-5 h-5 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
</div>
{/* Tablet and Desktop Layout - Two Columns */}
<div className="hidden sm:block">
<div className="grid grid-cols-2 gap-4 sm:gap-6 lg:gap-8">
{/* Left Column */}
<div className="flex flex-col items-center space-y-2 sm:space-y-3">
{leftSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 sm:p-4 w-full max-w-80 text-center border ${cardClassName}`}>
<h3 className={`text-xs sm:text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < leftSteps.length - 1 && (
<ArrowDown className={`w-5 h-5 sm:w-6 sm:h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
{/* Right Column */}
<div className="flex flex-col items-center space-y-2 sm:space-y-3">
{rightSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 sm:p-4 w-full max-w-80 text-center border ${cardClassName}`}>
<h3 className={`text-xs sm:text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < rightSteps.length - 1 && (
<ArrowUp className={`w-5 h-5 sm:w-6 sm:h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
<div className="w-full max-w-6xl">
{/* SVG Container with responsive sizing */}
<div className={`w-full ${svgClassName}`}>
{svgUrl ? (
// If SVG URL/path is provided
<img
src={svgUrl}
alt="Flowchart diagram"
className="w-full h-auto object-contain"
/>
) : svgContent ? (
// If SVG content is provided as JSX
<div className="w-full">
<div className="w-full">
{svgContent}
</div>
</div>
{/* Horizontal Arrow positioned between Primary and Secondary Assembly */}
<div className="absolute bottom-2 sm:bottom-4 lg:bottom-[0.7rem] left-1/2 transform -translate-x-1/2 flex items-center justify-center">
<ArrowRight className={`w-6 h-6 sm:w-8 sm:h-8 ${arrowColor}`} />
) : (
// Fallback message
<div className="flex items-center justify-center h-40 text-gray-500">
<p>Please provide SVG content or URL</p>
</div>
</div>
)}
</div>
</div>
</div>

View File

@ -1,130 +1,49 @@
import React from 'react';
import { ArrowDown, ArrowRight, ArrowUp } from 'lucide-react';
const CircularRNAPipeline = ({
title = "Bioinformatics Pipeline",
leftSteps = [
"Raw Sequencing Data (fastq files)",
"Quality Control and Preprocessing of Data",
"High Quality Sequencing Data (fastq file)",
"Alignment to Reference Genome"
],
rightSteps = [
"Downstream Advanced Analysis",
"Circular RNA Identification",
"Circular RNA Prediction",
"Back Splicing Junction Reads"
],
svgContent = null, // Pass your SVG content here as JSX
svgUrl = "/images/flowchart/circularrna.svg",
backgroundColor = "bg-gray-50",
cardColor = "bg-gray-300",
textColor = "text-teal-600",
arrowColor = "text-gray-600",
textColor = "text-gray-700",
className = "",
cardClassName = "",
titleClassName = ""
titleClassName = "",
svgClassName = "",
containerClassName = ""
}) => {
// Combine steps for mobile layout
const mobileSteps = [...leftSteps, ...rightSteps.slice().reverse()];
return (
<section className={`py-6 sm:py-8 lg:py-12 ${backgroundColor} ${className}`}>
<div className="container mx-auto max-w-none px-3 sm:px-4 lg:px-6">
<h2 className={`text-gray-700 text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
<div className={`container mx-auto max-w-none px-3 sm:px-4 lg:px-6 ${containerClassName}`}>
<h2 className={`${textColor} text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
{title}
</h2>
{/* Pipeline Flowchart */}
{/* SVG Flowchart Container */}
<div className="bg-white rounded-xl shadow-lg p-4 sm:p-6 lg:p-8">
<div className="flex justify-center">
<div className="w-full max-w-5xl">
<div className="relative">
{/* Mobile Layout - Single Column */}
<div className="block sm:hidden">
<div className="flex flex-col items-center space-y-3">
{mobileSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 w-full text-center border ${cardClassName}`}>
<h3 className={`text-xs font-medium ${textColor}`}>{step}</h3>
</div>
{index < mobileSteps.length - 1 && (
<ArrowDown className={`w-5 h-5 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
</div>
{/* Tablet and Desktop Layout - Two Columns */}
<div className="hidden sm:block">
<div className="grid grid-cols-2 gap-4 sm:gap-6 lg:gap-8">
{/* Left Column */}
<div className="flex flex-col items-center space-y-2 sm:space-y-3">
{leftSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 sm:p-4 w-full max-w-80 text-center border ${cardClassName}`}>
<h3 className={`text-xs sm:text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < leftSteps.length - 1 && (
<ArrowDown className={`w-5 h-5 sm:w-6 sm:h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
{/* Right Column */}
<div className="flex flex-col items-center space-y-2 sm:space-y-3">
{rightSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 sm:p-4 w-full max-w-80 text-center border ${cardClassName}`}>
<h3 className={`text-xs sm:text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < rightSteps.length - 1 && (
<ArrowUp className={`w-5 h-5 sm:w-6 sm:h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
<div className="w-full max-w-6xl">
{/* SVG Container with responsive sizing */}
<div className={`w-full ${svgClassName}`}>
{svgUrl ? (
// If SVG URL/path is provided
<img
src={svgUrl}
alt="Flowchart diagram"
className="w-full h-auto object-contain"
/>
) : svgContent ? (
// If SVG content is provided as JSX
<div className="w-full">
<div className="w-full">
{svgContent}
</div>
</div>
{/* Custom arrows from "Alignment to Reference Genome" */}
<div className="absolute bottom-12 sm:bottom-16 lg:bottom-[2rem] left-1/2 transform -translate-x-1/2">
<div className="relative w-0 h-0">
{/* Arrow 1: Straight horizontal to "Back Splicing Junction Reads" (Unmapped Reads) */}
<div className="absolute top-0 left-0">
<div className="relative">
{/* Horizontal line */}
<div className="w-16 sm:w-20 lg:w-28 h-0.5 bg-gray-600"></div>
{/* Arrowhead */}
<div className="absolute right-0 -top-1 w-2 h-2 border-r-2 border-t-2 border-gray-600 rotate-45"></div>
{/* Label */}
<div className="absolute top-2 left-4 sm:left-6 lg:left-10 text-xs text-gray-700 font-medium whitespace-nowrap">
Unmapped Reads
</div>
</div>
</div>
{/* Arrow 2: Diagonal upward to "Circular RNA Prediction" (Mapped Reads) */}
<div className="absolute top-0 left-0">
<div className="relative">
{/* Diagonal line going up and right */}
<div className="absolute origin-left w-20 sm:w-24 lg:w-32 h-0.5 bg-gray-600 transform -rotate-45"></div>
{/* Arrowhead positioned at the end of diagonal line */}
<div className="absolute w-2 h-2 border-r-2 border-t-2 border-gray-600 transform rotate-0"
style={{
left: 'calc(20 * 0.25rem * 0.707 - 4px)', // cos(45deg) ≈ 0.707
top: 'calc(-20 * 0.25rem * 0.707 - 4px)' // -sin(45deg) ≈ -0.707
}}></div>
{/* Label */}
<div className="absolute -top-8 left-6 sm:left-8 lg:left-12 text-xs text-gray-700 font-medium whitespace-nowrap">
Mapped Reads
</div>
</div>
</div>
</div>
) : (
// Fallback message
<div className="flex items-center justify-center h-40 text-gray-500">
<p>Please provide SVG content or URL</p>
</div>
</div>
)}
</div>
</div>
</div>

View File

@ -1,123 +1,49 @@
import React from 'react';
import { ArrowDown, ArrowRight, ArrowUp } from 'lucide-react';
const DegradomeSequencingPipeline = ({
title = "Degradome Sequencing",
title = "Bioinformatics Pipeline",
svgContent = null, // Pass your SVG content here as JSX
svgUrl = "/images/flowchart/degradomerna.svg",
backgroundColor = "bg-gray-50",
cardColor = "bg-blue-200",
textColor = "text-gray-800",
arrowColor = "text-gray-600",
textColor = "text-gray-700",
className = "",
cardClassName = "",
titleClassName = ""
titleClassName = "",
svgClassName = "",
containerClassName = ""
}) => {
const leftSteps = [
"Raw Sequencing Data (fastq files)",
"Quality Control and Preprocessing of Data",
"High Quality Sequencing Data (fastq file)",
"Alignment to Reference Genome"
];
const rightSteps = [
"Related miRNA Identification",
"mRNAs Degradome Sites",
"Identify Target mRNAs",
"Retain mRNA data Remove rRNA, tRNA and other RNA"
];
const middleSteps = [
"Functional Analysis"
];
return (
<section className={`py-6 sm:py-8 lg:py-12 ${backgroundColor} ${className}`}>
<div className="container mx-auto max-w-none px-3 sm:px-4 lg:px-6">
<h2 className={`text-gray-700 text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
<div className={`container mx-auto max-w-none px-3 sm:px-4 lg:px-6 ${containerClassName}`}>
<h2 className={`${textColor} text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
{title}
</h2>
{/* Pipeline Flowchart */}
{/* SVG Flowchart Container */}
<div className="bg-white rounded-xl shadow-lg p-4 sm:p-6 lg:p-8">
<div className="flex justify-center">
<div className="w-full max-w-6xl">
<div className="relative">
{/* Mobile Layout - Single Column */}
<div className="block lg:hidden">
<div className="flex flex-col items-center space-y-3">
{[...leftSteps, ...rightSteps.slice().reverse(), ...middleSteps].map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 w-full text-center border ${cardClassName}`}>
<h3 className={`text-xs font-medium ${textColor}`}>{step}</h3>
</div>
{index < leftSteps.length + rightSteps.length + middleSteps.length - 1 && (
<ArrowDown className={`w-5 h-5 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
</div>
{/* Desktop Layout - Complex Flow */}
<div className="hidden lg:block">
<div className="grid grid-cols-3 gap-6 lg:gap-8">
{/* Left Column */}
<div className="flex flex-col items-center space-y-3">
{leftSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-4 w-full max-w-80 text-center border ${cardClassName}`}>
<h3 className={`text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < leftSteps.length - 1 && (
<ArrowDown className={`w-6 h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
{/* Middle Column */}
<div className="flex flex-col items-center justify-center space-y-3">
{middleSteps.map((step, index) => (
<div key={index} className={`${cardColor} rounded-lg p-4 w-full max-w-60 text-center border ${cardClassName}`}>
<h3 className={`text-sm font-medium ${textColor}`}>{step}</h3>
</div>
))}
</div>
{/* Right Column */}
<div className="flex flex-col items-center space-y-3">
{rightSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-4 w-full max-w-80 text-center border ${cardClassName}`}>
<h3 className={`text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < rightSteps.length - 1 && (
<ArrowUp className={`w-6 h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
{/* SVG Container with responsive sizing */}
<div className={`w-full ${svgClassName}`}>
{svgUrl ? (
// If SVG URL/path is provided
<img
src={svgUrl}
alt="Flowchart diagram"
className="w-full h-auto object-contain"
/>
) : svgContent ? (
// If SVG content is provided as JSX
<div className="w-full">
<div className="w-full">
{svgContent}
</div>
</div>
{/* Horizontal Arrow from left to right (after alignment) */}
<div className="absolute bottom-4 left-1/3 transform -translate-x-1/2 flex items-center justify-center">
<ArrowRight className={`w-8 h-8 ${arrowColor}`} />
) : (
// Fallback message
<div className="flex items-center justify-center h-40 text-gray-500">
<p>Please provide SVG content or URL</p>
</div>
{/* Bidirectional arrows between middle and right columns */}
<div className="absolute top-1/2 right-1/3 transform translate-x-1/2 -translate-y-1/2 flex flex-col items-center space-y-2">
<ArrowUp className={`w-6 h-6 ${arrowColor}`} />
<ArrowDown className={`w-6 h-6 ${arrowColor}`} />
</div>
{/* Additional arrows for the circular flow in right column */}
<div className="absolute top-1/4 right-6 flex items-center justify-center">
<ArrowUp className={`w-5 h-5 ${arrowColor}`} />
</div>
<div className="absolute top-2/3 right-6 flex items-center justify-center">
<ArrowUp className={`w-5 h-5 ${arrowColor}`} />
</div>
</div>
)}
</div>
</div>
</div>

View File

@ -1,127 +1,49 @@
import React from 'react';
import { ArrowDown, ArrowRight, ArrowUp } from 'lucide-react';
const IsoformPipeline = ({
title = "Bioinformatics Pipeline",
leftSteps = [
"Raw Sequencing Data (fastq files)",
"Quality Control and Preprocessing of Data",
"High Quality Sequencing Data (fastq file)",
"Build Similarity Graph and Polishing"
],
rightSteps = [
"Downstream Analysis (Fusion Analysis, Splicing Analysis)",
"Transcript Annotation and Classification",
"Sequencing Merge and Redundancy Removal",
"Alignment to Reference Genome"
],
svgContent = null, // Pass your SVG content here as JSX
svgUrl = "/images/flowchart/isoseqrna.svg",
backgroundColor = "bg-gray-50",
cardColor = "bg-gray-300",
textColor = "text-teal-600",
arrowColor = "text-gray-600",
textColor = "text-gray-700",
className = "",
cardClassName = "",
titleClassName = ""
titleClassName = "",
svgClassName = "",
containerClassName = ""
}) => {
// Combine steps for mobile layout
const mobileSteps = [...leftSteps, ...rightSteps.slice().reverse()];
return (
<section className={`py-6 sm:py-8 lg:py-12 ${backgroundColor} ${className}`}>
<div className="container mx-auto max-w-none px-3 sm:px-4 lg:px-6">
<h2 className={`text-gray-700 text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
<div className={`container mx-auto max-w-none px-3 sm:px-4 lg:px-6 ${containerClassName}`}>
<h2 className={`${textColor} text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
{title}
</h2>
{/* Pipeline Flowchart */}
{/* SVG Flowchart Container */}
<div className="bg-white rounded-xl shadow-lg p-4 sm:p-6 lg:p-8">
<div className="flex justify-center">
<div className="w-full max-w-5xl">
<div className="relative">
{/* Mobile Layout - Single Column */}
<div className="block sm:hidden">
<div className="flex flex-col items-center space-y-3">
{mobileSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 w-full text-center border ${cardClassName}`}>
<h3 className={`text-xs font-medium ${textColor}`}>{step}</h3>
</div>
{index < mobileSteps.length - 1 && (
<ArrowDown className={`w-5 h-5 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
</div>
{/* Desktop Layout - Two Columns */}
<div className="hidden sm:block">
<div className="grid grid-cols-2 gap-4 sm:gap-6 lg:gap-8">
{/* Left Column */}
<div className="flex flex-col items-center space-y-3">
{leftSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-4 w-full text-center border ${cardClassName}`} style={{maxWidth: '19rem'}}>
<h3 className={`text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < leftSteps.length - 1 && (
<ArrowDown className={`w-6 h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
{/* Right Column */}
<div className="flex flex-col items-center space-y-3">
{rightSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-4 w-full text-center border ${cardClassName}`} style={{maxWidth: '19rem'}}>
<h3 className={`text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < rightSteps.length - 1 && (
<ArrowUp className={`w-6 h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
<div className="w-full max-w-6xl">
{/* SVG Container with responsive sizing */}
<div className={`w-full ${svgClassName}`}>
{svgUrl ? (
// If SVG URL/path is provided
<img
src={svgUrl}
alt="Flowchart diagram"
className="w-full h-auto object-contain"
/>
) : svgContent ? (
// If SVG content is provided as JSX
<div className="w-full">
<div className="w-full">
{svgContent}
</div>
</div>
{/* Diagonal Arrow from High Quality Sequencing Data to Alignment to Reference Genome */}
<div className="absolute top-80 left-1/2 transform -translate-x-1/2 -translate-y-1/2">
<svg
width="180"
height="60"
viewBox="0 0 180 60"
className={arrowColor}
style={{transform: 'rotate(20deg)'}}
>
<defs>
<marker
id="arrowhead"
markerWidth="10"
markerHeight="7"
refX="9"
refY="3.5"
orient="auto"
>
<polygon
points="0 0, 10 3.5, 0 7"
fill="currentColor"
/>
</marker>
</defs>
<line
x1="10"
y1="10"
x2="170"
y2="50"
stroke="currentColor"
strokeWidth="2"
markerEnd="url(#arrowhead)"
/>
</svg>
) : (
// Fallback message
<div className="flex items-center justify-center h-40 text-gray-500">
<p>Please provide SVG content or URL</p>
</div>
</div>
)}
</div>
</div>
</div>

View File

@ -1,28 +1,51 @@
// app/rna-sequencing/lncrna-sequencing/components/LncRNABioinformatics.jsx
import React from 'react';
const LncRNABioinformatics = () => {
const LncRNABioinformatics = ({
title = "Bioinformatics Pipeline",
svgContent = null, // Pass your SVG content here as JSX
svgUrl = "/images/flowchart/totalrna.svg",
backgroundColor = "bg-gray-50",
textColor = "text-gray-700",
className = "",
titleClassName = "",
svgClassName = "",
containerClassName = ""
}) => {
return (
<section className="py-8 lg:py-12 bg-gray-50">
<div className="container mx-auto max-w-none px-4 lg:px-6">
<h2 className="text-2xl lg:text-3xl text-gray-700 text-left pb-2 mb-6 lg:mb-6">
Bioinformatics Pipeline
<section className={`py-6 sm:py-8 lg:py-12 ${backgroundColor} ${className}`}>
<div className={`container mx-auto max-w-none px-3 sm:px-4 lg:px-6 ${containerClassName}`}>
<h2 className={`${textColor} text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
{title}
</h2>
{/* Pipeline Image */}
<div className="bg-white rounded-xl shadow-lg p-6 lg:p-8">
{/* SVG Flowchart Container */}
<div className="bg-white rounded-xl shadow-lg p-4 sm:p-6 lg:p-8">
<div className="flex justify-center">
<img
src="/images/lncrna-bioinformatics-pipeline.jpg"
alt="lncRNA Sequencing Bioinformatics Pipeline Workflow"
className="max-w-full h-auto rounded-lg"
/>
</div>
{/* Pipeline Description */}
<div className="mt-6 text-center">
<p className="text-gray-600 text-sm lg:text-base">
lncRNA sequencing bioinformatics pipeline for long non-coding RNA analysis and expression profiling
</p>
<div className="w-full max-w-6xl">
{/* SVG Container with responsive sizing */}
<div className={`w-full ${svgClassName}`}>
{svgUrl ? (
// If SVG URL/path is provided
<img
src={svgUrl}
alt="Flowchart diagram"
className="w-full h-auto object-contain"
/>
) : svgContent ? (
// If SVG content is provided as JSX
<div className="w-full">
<div className="w-full">
{svgContent}
</div>
</div>
) : (
// Fallback message
<div className="flex items-center justify-center h-40 text-gray-500">
<p>Please provide SVG content or URL</p>
</div>
)}
</div>
</div>
</div>
</div>
</div>
@ -30,4 +53,4 @@ const LncRNABioinformatics = () => {
);
};
export default LncRNABioinformatics
export default LncRNABioinformatics;

View File

@ -1,188 +1,49 @@
import React from 'react';
import { ArrowDown, ArrowRight, ArrowUp } from 'lucide-react';
const MetatranscriptomicsPipeline = ({
title = "Metatranscriptomics",
title = "Bioinformatics Pipeline",
svgContent = null, // Pass your SVG content here as JSX
svgUrl = "/images/flowchart/metatranscriptomicsrna.svg",
backgroundColor = "bg-gray-50",
cardColor = "bg-blue-200",
textColor = "text-blue-800",
arrowColor = "text-gray-600",
textColor = "text-gray-700",
className = "",
cardClassName = "",
titleClassName = ""
titleClassName = "",
svgClassName = "",
containerClassName = ""
}) => {
const topSteps = [
"Raw Sequencing Data (fastq files)",
"Quality Control",
"High Quality Sequencing Data (fastq file)",
"Retain mRNA reads and remove rRNA Reads"
];
const bottomLeftSteps = [
"Reference Genome Alignment",
"Gene Expression Analysis",
"Differential Analysis"
];
const bottomCenterSteps = [
"Transcript Assembly",
"Structural Identification",
"SNPs, SSRs Analysis eQTLs Analysis"
];
const bottomRightSteps = [
"Functional Annotation",
"Statistical Analysis"
];
return (
<section className={`py-6 sm:py-8 lg:py-12 ${backgroundColor} ${className}`}>
<div className="container mx-auto max-w-none px-3 sm:px-4 lg:px-6">
<h2 className={`text-gray-700 text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
<div className={`container mx-auto max-w-none px-3 sm:px-4 lg:px-6 ${containerClassName}`}>
<h2 className={`${textColor} text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
{title}
</h2>
{/* Pipeline Flowchart */}
{/* SVG Flowchart Container */}
<div className="bg-white rounded-xl shadow-lg p-4 sm:p-6 lg:p-8">
<div className="flex justify-center">
<div className="w-full max-w-6xl">
<div className="relative">
{/* Mobile Layout - Single Column */}
<div className="block lg:hidden">
<div className="flex flex-col items-center space-y-3">
{topSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 w-full text-center border ${cardClassName}`}>
<h3 className={`text-xs font-medium ${textColor}`}>{step}</h3>
</div>
{index < topSteps.length - 1 && (
<ArrowDown className={`w-5 h-5 ${arrowColor}`} />
)}
</React.Fragment>
))}
{/* Bottom sections for mobile */}
<div className="grid grid-cols-1 gap-4 w-full mt-6">
{bottomLeftSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 w-full text-center border ${cardClassName}`}>
<h3 className={`text-xs font-medium ${textColor}`}>{step}</h3>
</div>
{index < bottomLeftSteps.length - 1 && (
<ArrowDown className={`w-5 h-5 ${arrowColor} mx-auto`} />
)}
</React.Fragment>
))}
{bottomCenterSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 w-full text-center border ${cardClassName}`}>
<h3 className={`text-xs font-medium ${textColor}`}>{step}</h3>
</div>
{index < bottomCenterSteps.length - 1 && (
<ArrowDown className={`w-5 h-5 ${arrowColor} mx-auto`} />
)}
</React.Fragment>
))}
{bottomRightSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 w-full text-center border ${cardClassName}`}>
<h3 className={`text-xs font-medium ${textColor}`}>{step}</h3>
</div>
{index < bottomRightSteps.length - 1 && (
<ArrowDown className={`w-5 h-5 ${arrowColor} mx-auto`} />
)}
</React.Fragment>
))}
{/* SVG Container with responsive sizing */}
<div className={`w-full ${svgClassName}`}>
{svgUrl ? (
// If SVG URL/path is provided
<img
src={svgUrl}
alt="Flowchart diagram"
className="w-full h-auto object-contain"
/>
) : svgContent ? (
// If SVG content is provided as JSX
<div className="w-full">
<div className="w-full">
{svgContent}
</div>
</div>
</div>
{/* Desktop Layout */}
<div className="hidden lg:block">
{/* Top vertical sequence */}
<div className="flex flex-col items-center space-y-4 mb-8">
{topSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-4 w-96 text-center border ${cardClassName}`}>
<h3 className={`text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < topSteps.length - 1 && (
<ArrowDown className={`w-6 h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
) : (
// Fallback message
<div className="flex items-center justify-center h-40 text-gray-500">
<p>Please provide SVG content or URL</p>
</div>
{/* Branching arrows from "Retain mRNA reads and remove rRNA Reads" */}
<div className="flex justify-center mb-8">
<div className="relative">
{/* Left branch arrow */}
<div className="absolute -left-32 top-0">
<ArrowDown className={`w-6 h-6 ${arrowColor}`} />
</div>
{/* Right branch arrow */}
<div className="absolute left-32 top-0">
<ArrowDown className={`w-6 h-6 ${arrowColor}`} />
</div>
</div>
</div>
{/* Bottom three columns */}
<div className="grid grid-cols-3 gap-8">
{/* Left Column */}
<div className="flex flex-col items-center space-y-4">
{bottomLeftSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-4 w-full text-center border ${cardClassName}`}>
<h3 className={`text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < bottomLeftSteps.length - 1 && (
<ArrowDown className={`w-6 h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
{/* Center Column */}
<div className="flex flex-col items-center space-y-4">
{bottomCenterSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-4 w-full text-center border ${cardClassName}`}>
<h3 className={`text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < bottomCenterSteps.length - 1 && (
<ArrowDown className={`w-6 h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
{/* Right Column */}
<div className="flex flex-col items-center space-y-4">
{bottomRightSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-4 w-full text-center border ${cardClassName}`}>
<h3 className={`text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < bottomRightSteps.length - 1 && (
<ArrowDown className={`w-6 h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
</div>
{/* Horizontal arrows connecting bottom sections */}
<div className="absolute bottom-4 left-1/3 transform -translate-x-1/2">
<ArrowRight className={`w-6 h-6 ${arrowColor}`} />
</div>
<div className="absolute bottom-4 right-1/3 transform translate-x-1/2">
<ArrowRight className={`w-6 h-6 ${arrowColor}`} />
</div>
</div>
)}
</div>
</div>
</div>

View File

@ -1,98 +1,49 @@
import React from 'react';
import { ArrowDown, ArrowRight, ArrowUp } from 'lucide-react';
const SRNABioinformatics = ({
title = "Bioinformatics Pipeline",
leftSteps = [
"Raw Sequencing Data (fastq files)",
"Quality Control and Preprocessing of Data",
"High Quality Sequencing Data (fastq file)",
"Blast Against mRNA, Rfam and RepBase",
"Retained data with no annotation and remove data annotated with mRNA, Rfam and RepBase"
],
rightSteps = [
"Downstream Advanced Analysis",
"Identification of known and Novel microRNA",
"Hairpin Prediction",
"Aligned to Genome",
"Aligned to Genome"
],
svgContent = null, // Pass your SVG content here as JSX
svgUrl = "/images/flowchart/smallrna.svg",
backgroundColor = "bg-gray-50",
cardColor = "bg-gray-300",
textColor = "text-teal-600",
arrowColor = "text-gray-600",
textColor = "text-gray-700",
className = "",
cardClassName = "",
titleClassName = ""
titleClassName = "",
svgClassName = "",
containerClassName = ""
}) => {
// Combine steps for mobile layout
const mobileSteps = [...leftSteps, ...rightSteps.slice().reverse()];
return (
<section className={`py-6 sm:py-8 lg:py-12 ${backgroundColor} ${className}`}>
<div className="container mx-auto max-w-none px-3 sm:px-4 lg:px-6">
<h2 className={`text-gray-700 text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
<div className={`container mx-auto max-w-none px-3 sm:px-4 lg:px-6 ${containerClassName}`}>
<h2 className={`${textColor} text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
{title}
</h2>
{/* Pipeline Flowchart */}
{/* SVG Flowchart Container */}
<div className="bg-white rounded-xl shadow-lg p-4 sm:p-6 lg:p-8">
<div className="flex justify-center">
<div className="w-full max-w-5xl">
<div className="relative">
{/* Mobile Layout - Single Column */}
<div className="block sm:hidden">
<div className="flex flex-col items-center space-y-3">
{mobileSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-3 w-full text-center border ${cardClassName}`}>
<h3 className={`text-xs font-medium ${textColor}`}>{step}</h3>
</div>
{index < mobileSteps.length - 1 && (
<ArrowDown className={`w-5 h-5 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
</div>
{/* Desktop Layout - Two Columns */}
<div className="hidden sm:block">
<div className="grid grid-cols-2 gap-4 sm:gap-6 lg:gap-8">
{/* Left Column */}
<div className="flex flex-col items-center space-y-3">
{leftSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-4 w-full text-center border ${cardClassName}`} style={{maxWidth: '19rem'}}>
<h3 className={`text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < leftSteps.length - 1 && (
<ArrowDown className={`w-6 h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
</div>
{/* Right Column */}
<div className="flex flex-col items-center space-y-3">
{rightSteps.map((step, index) => (
<React.Fragment key={index}>
<div className={`${cardColor} rounded-lg p-4 w-full text-center border ${cardClassName}`} style={{maxWidth: '19rem'}}>
<h3 className={`text-sm font-medium ${textColor}`}>{step}</h3>
</div>
{index < rightSteps.length - 1 && (
<ArrowUp className={`w-6 h-6 ${arrowColor}`} />
)}
</React.Fragment>
))}
<div className="w-full max-w-6xl">
{/* SVG Container with responsive sizing */}
<div className={`w-full ${svgClassName}`}>
{svgUrl ? (
// If SVG URL/path is provided
<img
src={svgUrl}
alt="Flowchart diagram"
className="w-full h-auto object-contain"
/>
) : svgContent ? (
// If SVG content is provided as JSX
<div className="w-full">
<div className="w-full">
{svgContent}
</div>
</div>
{/* Horizontal Arrow from Transcript Assembly to Transcript Assembly Validation */}
<div className="absolute bottom-4 left-1/2 transform -translate-x-1/2 flex items-center justify-center">
<ArrowRight className={`w-8 h-8 ${arrowColor}`} />
) : (
// Fallback message
<div className="flex items-center justify-center h-40 text-gray-500">
<p>Please provide SVG content or URL</p>
</div>
</div>
)}
</div>
</div>
</div>

View File

@ -0,0 +1,56 @@
import React from 'react';
const WTSPipeline = ({
title = "Bioinformatics Pipeline",
svgContent = null, // Pass your SVG content here as JSX
svgUrl = "/images/flowchart/totalrna.svg",
backgroundColor = "bg-gray-50",
textColor = "text-gray-700",
className = "",
titleClassName = "",
svgClassName = "",
containerClassName = ""
}) => {
return (
<section className={`py-6 sm:py-8 lg:py-12 ${backgroundColor} ${className}`}>
<div className={`container mx-auto max-w-none px-3 sm:px-4 lg:px-6 ${containerClassName}`}>
<h2 className={`${textColor} text-left pb-4 sm:pb-6 text-xl sm:text-2xl lg:text-3xl font-normal ${titleClassName}`}>
{title}
</h2>
{/* SVG Flowchart Container */}
<div className="bg-white rounded-xl shadow-lg p-4 sm:p-6 lg:p-8">
<div className="flex justify-center">
<div className="w-full max-w-6xl">
{/* SVG Container with responsive sizing */}
<div className={`w-full ${svgClassName}`}>
{svgUrl ? (
// If SVG URL/path is provided
<img
src={svgUrl}
alt="Flowchart diagram"
className="w-full h-auto object-contain"
/>
) : svgContent ? (
// If SVG content is provided as JSX
<div className="w-full">
<div className="w-full">
{svgContent}
</div>
</div>
) : (
// Fallback message
<div className="flex items-center justify-center h-40 text-gray-500">
<p>Please provide SVG content or URL</p>
</div>
)}
</div>
</div>
</div>
</div>
</div>
</section>
);
};
export default WTSPipeline;

View File

@ -2,6 +2,7 @@
import TitleBar from '../../components/shared/TitleBar';
import WTSIntroduction from './components/WTSIntroduction';
import WTSAdvantages from './components/WTSAdvantages';
import WTSPipeline from './components/WTSPipeline';
import WTSApplications from './components/WTSApplications';
import WTSSpecifications from './components/WTSSpecifications';
import PageLayout from '../../components/Layout/PageLayout';
@ -21,6 +22,7 @@ export default function WholeTranscriptomeSequencingPage() {
/>
<WTSIntroduction />
<WTSAdvantages />
<WTSPipeline/>
<WTSApplications />
<WTSSpecifications />
</PageLayout>

10
package-lock.json generated
View File

@ -8,6 +8,7 @@
"name": "nextjs",
"version": "0.1.0",
"dependencies": {
"@heroicons/react": "^2.2.0",
"lucide-react": "^0.525.0",
"next": "^15.2.0",
"nodemailer": "^7.0.3",
@ -214,6 +215,15 @@
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@heroicons/react": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@heroicons/react/-/react-2.2.0.tgz",
"integrity": "sha512-LMcepvRaS9LYHJGsF0zzmgKCUim/X3N/DQKc4jepAXJ7l8QxJ1PmxJzqplF2Z3FE4PqBAIGyJAQ/w4B5dsqbtQ==",
"license": "MIT",
"peerDependencies": {
"react": ">= 16 || ^19.0.0-rc"
}
},
"node_modules/@humanfs/core": {
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",

View File

@ -9,6 +9,7 @@
"lint": "next lint"
},
"dependencies": {
"@heroicons/react": "^2.2.0",
"lucide-react": "^0.525.0",
"next": "^15.2.0",
"nodemailer": "^7.0.3",

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 224 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 217 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 202 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 274 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 204 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 249 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 295 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 246 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 222 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 205 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 196 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 257 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 282 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 274 KiB

File diff suppressed because one or more lines are too long

After

Width:  |  Height:  |  Size: 5.4 KiB