Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions samples/Vuejs-sample/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.DS_Store
node_modules
/dist


# local env files
.env.local
.env.*.local

# Log files
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

# Editor directories and files
.idea
.vscode
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?
19 changes: 19 additions & 0 deletions samples/Vuejs-sample/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# vuejs-skyflow-react-sample

## Project setup
```
npm install
```

### Compiles and hot-reloads for development
```
npm run serve
```

### Compiles and minifies for production
```
npm run build
```

### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).
7 changes: 7 additions & 0 deletions samples/Vuejs-sample/babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
module.exports = {
presets: [
['@vue/cli-plugin-babel/preset'],
['@babel/preset-react'],
['@babel/preset-typescript']
]
}
30 changes: 30 additions & 0 deletions samples/Vuejs-sample/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
{
"name": "vuejs-skyflow-reactsdk-sample",
"version": "0.1.0",
"private": true,
"scripts": {
"serve": "vue-cli-service serve --host localhost --port 8080 --public localhost:8080",
"build": "vue-cli-service build"
},
"dependencies": {
"@types/react": "^19.1.8",
"react": "^19.1.0",
"react-dom": "^19.1.0",
"react-to-webcomponent": "^2.0.1",
"skyflow-js": "^2.3.2",
"skyflow-react-js": "^2.4.3",
"vue": "^3.2.13"
},
"devDependencies": {
"@babel/preset-react": "^7.27.1",
"@babel/preset-typescript": "^7.27.1",
"@types/react-dom": "^19.1.6",
"@vue/babel-preset-jsx": "^1.4.0",
"@vue/cli-plugin-babel": "^5.0.8",
"@vue/cli-plugin-typescript": "~5.0.0",
"@vue/cli-service": "~5.0.0",
"babel-loader": "^10.0.0",
"typescript": "~4.5.5",
"webpack": "^5.99.9"
}
}
Binary file added samples/Vuejs-sample/public/favicon.ico
Binary file not shown.
17 changes: 17 additions & 0 deletions samples/Vuejs-sample/public/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html lang="">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>
10 changes: 10 additions & 0 deletions samples/Vuejs-sample/src/App.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<script setup lang="ts">
import VueComponent from './components/VueComponent.vue'
</script>

<template>
<div>
</div>
<h1>React + Vue</h1>
<VueComponent />
</template>
Binary file added samples/Vuejs-sample/src/assets/logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
188 changes: 188 additions & 0 deletions samples/Vuejs-sample/src/components/CollectComponents.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
import React from 'react';
import {
CardHolderNameElement,
CardNumberElement,
CVVElement,
ExpirationDateElement,
ExpirationMonthElement,
ExpirationYearElement,
FileInputElement,
InputFieldElement,
PinElement,
useCollectContainer,
useMakeSkyflowStyles
} from 'skyflow-react-js';

export const CollectComponents: React.FC = () => {
// Initialize Skyflow container for collecting sensitive data
const container = useCollectContainer();

if (!container) {
return <div>Loading...</div>;
}

// Handler for collecting form data
const handleCollect = () => {
const response = container.collect();
response
.then((res: unknown) => {
console.log(JSON.stringify(res));
})
.catch((e: unknown) => {
console.log(e);
});
};

// Handler for file uploads
const handleFile = () => {
const response = container.uploadFiles({});
response
.then((res: unknown) => {
console.log(JSON.stringify(res));
})
.catch((e: unknown) => {
console.log(e);
});
};

// Define styles for Skyflow elements
const useStyles = useMakeSkyflowStyles({
// Input field styles
inputStyles: {
base: {
border: '1px solid blue',
borderRadius: '4px',
color: 'red',
padding: '10px 16px',
fontFamily: '"Roboto", sans-serif',
},
complete: { color: '#4caf50' },
empty: {},
focus: {},
invalid: { color: '#f44336' },
global: {
'@import': 'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
}
},
// Label styles
labelStyles: {
base: {
fontSize: '16px',
fontWeight: 'bold',
fontFamily: '"Roboto", sans-serif'
},
global: {
'@import': 'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
},
requiredAsterisk: { color: 'red' }
},
// Error message styles
errorTextStyles: {
base: {
color: 'red',
fontFamily: '"Roboto", sans-serif',
},
global: {
'@import': 'url("https://fonts.googleapis.com/css2?family=Roboto&display=swap")',
},
},
});

// File upload options (empty for now)
const options = {}

// Apply styles to elements
const classes = useStyles();

return (
<div>
<h1>Collect Components</h1>
<CardNumberElement
container={container}
table="<TABLE_NAME>" // replace with actual table name
column="<COLUMN_NAME>" // replace with actual column name
placeholder="Card Number"
classes={classes}
label="Card Number"
/>
<CardHolderNameElement
container={container}
table="<TABLE_NAME>" // replace with actual table name
column="<COLUMN_NAME>" // replace with actual column name
placeholder="Card holder name"
classes={classes}
label="Card Holder Name"
/>
<CVVElement
id='cvv'
container={container}
table='<TABLE_NAME>' // replace with actual table name
classes={classes}
column={'<CVV>'} // replace with actual column name
label='Collect CVV'
placeholder='CVV'
/>
<ExpirationMonthElement
id='month'
container={container}
classes={classes}
table='<TABLE_NAME>' // replace with actual table name
column={'<EXPIRATION_MONTH>'} // replace with actual column name
label='Collect Exp Month'
placeholder='MM'
/>
<ExpirationYearElement
id='year'
container={container}
classes={classes}
table='<TABLE_NAME>' // replace with actual table name
column={'<EXPIRATION_YEAR>'} // replace with actual column name
label='Collect Exp Year'
placeholder='YY'
/>
<ExpirationDateElement
id='date'
container={container}
classes={classes}
table={'<TABLE_NAME>'} // replace with actual table name
column={'<EXPIRATION_DATE>'} // replace with actual column name
label={'Expiration Date'}
placeholder='MM/YY'
/>

<PinElement
id='pin'
container={container}
classes={classes}
table={'<TABLE_NAME>'}
column={'<PIN>'} // replace with actual column name
label={'Pin'}
placeholder='122334'
/>

<InputFieldElement
id='input'
container={container}
classes={classes}
table={'<TABLE_NAME>'}
column={'<SSN>'} // replace with actual column name
label={'SSN'}
placeholder='123-45-6789'
/>
<FileInputElement
id='file-input'
container={container}
classes={classes}
table={'<TABLE_NAME>'}
column={'<COLUMN_NAME>'} // replace with actual column name
skyflowID='<SKYFLOW_ID>'
label={'file-input'}
options={options}
/>
<button onClick={handleCollect}>Collect</button>
<button onClick={handleFile}>Submit file</button>
</div>
);
};


69 changes: 69 additions & 0 deletions samples/Vuejs-sample/src/components/Connector.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
import React, { useState } from "react";
import { CollectComponents } from "./CollectComponents";
import { SkyflowWrapper } from "./SkyflowWrapper";
import { Root, createRoot } from 'react-dom/client';
import RevealComponents from "./RevealComponents";

// Component to manage visibility state of Collect and Reveal forms
const ComponentWrapper: React.FC = () => {
// State hooks for toggling component visibility
const [showCollect, setShowCollect] = useState(false);
const [showReveal, setShowReveal] = useState(false);

return (
<div>
{/* Button container */}
<div style={{ marginBottom: '20px' }}>
{/* Toggle Collect form visibility */}
<button
onClick={() => setShowCollect(!showCollect)}
style={{ marginRight: '10px' }}
>
{showCollect ? 'Hide Collect' : 'Show Collect'}
</button>
{/* Toggle Reveal form visibility */}
<button
onClick={() => setShowReveal(!showReveal)}
>
{showReveal ? 'Hide Reveal' : 'Show Reveal'}
</button>
</div>

{/* Conditional rendering of components */}
{showCollect && <CollectComponents />}
{showReveal && <RevealComponents />}
</div>
);
};

// Class to handle React integration with Vue
export class ReactConnector {
// Store React root instance
private root: Root | null = null;

// Initialize React root with target DOM element
constructor(targetEl: HTMLElement) {
if (targetEl) {
this.root = createRoot(targetEl);
}
}

// Render React components with Skyflow context
render() {
if (this.root) {
this.root.render(
<SkyflowWrapper>
<ComponentWrapper />
</SkyflowWrapper>
);
}
}

// Cleanup method to prevent memory leaks
cleanup() {
if (this.root) {
this.root.unmount();
this.root = null;
}
}
}
Loading