npm package: @polymindslabs/widget-sdk
Description: Universal Job Widget SDK for embedding job boards and apply buttons
Author: Job Widget
Latest version: 1.1.1

# Job Widget SDK

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![npm version](https://badge.fury.io/js/%40job-widget%2Fsdk.svg)](https://badge.fury.io/js/%40job-widget%2Fsdk)
[![TypeScript](https://img.shields.io/badge/%3C%2F%3E-TypeScript-%230074c1.svg)](http://www.typescriptlang.org/)

Universal JavaScript SDK for embedding job widgets in any web application.

## Features

- 🎯 **Universal Support** - Works with vanilla JavaScript, React, Vue, Angular, and more
- 🔐 **OAuth Integration** - Seamless authentication with popup or redirect flow
- 📱 **Responsive Design** - Mobile-first, accessible components
- 🎨 **Customizable** - Themes, colors, and styling options
- 🚀 **Lightweight** - Minimal bundle size with tree-shaking support
- ⚡ **TypeScript** - Full type safety and IntelliSense support

## Prerequisites

Before using the Job Widget SDK, you need to:

1. **Contact us for an API key** at partnerships@inzif.com
2. **Register an OAuth client** (contact partnerships@inzif.com)
3. **Review our pricing** at [inzif.com](https://inzif.com)

> **Note**: The SDK is free and open source (MIT License), but connecting to our job widget service requires registration and may have usage fees.

## Installation

### NPM/Yarn

```bash
npm install @polymindslabs/widget-sdk
# or
yarn add @polymindslabs/widget-sdk
```

### CDN

```html
<script src="https://cdn.inzif.com/sdk/latest/inzif-widget.min.js"></script>
```

## Quick Start

### Vanilla JavaScript

```javascript
import { JobWidget } from '@polymindslabs/widget-sdk';

const widget = new JobWidget({
  container: '#widget-container',
  tenantId: 'your-tenant-id',
  apiKey: 'your-api-key',
  clientId: 'your-oauth-client-id',
  redirectUri: 'https://yoursite.com/oauth-callback',
  type: 'job-list',
  theme: 'light',
  onSuccess: (application) => {
    console.log('Application submitted:', application);
  }
});

await widget.init();
```

### React

```jsx
import { JobBoard } from '@polymindslabs/widget-sdk/react';

function App() {
  return (
    <JobBoard
      container="#widget-container"
      tenantId="your-tenant-id"
      apiKey="your-api-key"
      clientId="your-oauth-client-id"
      redirectUri="https://yoursite.com/oauth-callback"
      theme="light"
      onSuccess={(application) => {
        console.log('Application submitted:', application);
      }}
    />
  );
}
```

### Vue

```vue
<template>
  <JobBoard
    container="#widget-container"
    :tenant-id="tenantId"
    :api-key="apiKey"
    :client-id="clientId"
    :redirect-uri="redirectUri"
    theme="light"
    @success="handleSuccess"
  />
</template>

<script>
import { JobBoard } from '@polymindslabs/widget-sdk/vue';

export default {
  components: { JobBoard },
  data() {
    return {
      tenantId: 'your-tenant-id',
      apiKey: 'your-api-key',
      clientId: 'your-oauth-client-id',
      redirectUri: 'https://yoursite.com/oauth-callback'
    };
  },
  methods: {
    handleSuccess(application) {
      console.log('Application submitted:', application);
    }
  }
};
</script>
```

## Widget Types

### Apply Button
Simple button for single job applications.

```javascript
new JobWidget({
  type: 'job-list',
  container: '#job-widget',
  tenantId: 'your-tenant-id',
  apiKey: 'your-api-key',
  clientId: 'your-oauth-client-id',
  redirectUri: 'https://yoursite.com/oauth-callback'
});
```

### Job List
List of available jobs with apply buttons.

```javascript
new JobWidget({
  type: 'job-list',
  container: '#job-list',
  tenantId: 'your-tenant-id',
  apiKey: 'your-api-key',
  clientId: 'your-oauth-client-id',
  redirectUri: 'https://yoursite.com/oauth-callback'
});
```

### Job Board
Full-featured job board with search and filters.

```javascript
new JobWidget({
  type: 'job-list',
  container: '#job-board',
  tenantId: 'your-tenant-id',
  apiKey: 'your-api-key',
  clientId: 'your-oauth-client-id',
  redirectUri: 'https://yoursite.com/oauth-callback'
});
```

### Career Page
Complete career page with company branding.

```javascript
new JobWidget({
  type: 'job-list',
  container: '#career-page',
  tenantId: 'your-tenant-id',
  apiKey: 'your-api-key',
  clientId: 'your-oauth-client-id',
  redirectUri: 'https://yoursite.com/oauth-callback'
});
```

### Status Tracker
Track application status for users.

```javascript
new JobWidget({
  type: 'job-list',
  container: '#status-tracker',
  tenantId: 'your-tenant-id',
  apiKey: 'your-api-key',
  clientId: 'your-oauth-client-id',
  redirectUri: 'https://yoursite.com/oauth-callback'
});
```

## Configuration Options

### Required Parameters

| Option | Type | Description |
|--------|------|-------------|
| `container` | `string \| HTMLElement` | Container element or selector |
| `tenantId` | `string` | Your tenant ID for API access |
| `apiKey` | `string` | Your API key for authentication |
| `clientId` | `string` | OAuth client ID for job applications |
| `redirectUri` | `string` | OAuth callback URL for authentication |

### Optional Parameters

| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `type` | `WidgetType` | `'job-list'` | Widget type to render |
| `apiUrl` | `string` | `'https://api.job-widget.com'` | API endpoint |
| `oauthUrl` | `string` | `'https://api.job-widget.com'` | OAuth provider URL |
| `theme` | `'light' \| 'dark' \| 'auto'` | `'light'` | Theme mode |
| `primaryColor` | `string` | `'#6366f1'` | Primary brand color |
| `fontFamily` | `string` | System font | Custom font family |
| `locale` | `string` | `'en-US'` | Locale for translations |
| `usePopup` | `boolean` | `true` | Use popup for OAuth |
| `showLogo` | `boolean` | `true` | Show company logo |
| `showPoweredBy` | `boolean` | `true` | Show "Powered by" branding |
| `profileCompletionRequired` | `number` | `50` | Required profile completion % |
| `debug` | `boolean` | `false` | Enable debug logging |

## Event Callbacks

```javascript
const widget = new JobWidget({
  // ... config
  onReady: () => {
    console.log('Widget ready');
  },
  onApply: (job) => {
    console.log('Apply clicked:', job);
  },
  onSuccess: (application) => {
    console.log('Application successful:', application);
  },
  onError: (error) => {
    console.error('Error:', error);
  },
  onProfileIncomplete: (data) => {
    console.log('Profile incomplete:', data);
  },
  onAuthRequired: () => {
    console.log('Authentication required');
  },
  onAuthSuccess: (token) => {
    console.log('Authentication successful');
  }
});
```

## Event Subscription

```javascript
// Subscribe to events
widget.on('ready', () => console.log('Widget ready'));
widget.on('error', (error) => console.error('Error:', error));
widget.on('apply:start', (job) => console.log('Applying to:', job));
widget.on('apply:success', (app) => console.log('Success:', app));

// Unsubscribe
const handler = (data) => console.log(data);
widget.on('ready', handler);
widget.off('ready', handler);

// One-time subscription
widget.once('ready', () => console.log('Ready once'));
```

## Methods

### `init()`
Initialize the widget.

```javascript
await widget.init();
```

### `authenticate()`
Manually trigger authentication.

```javascript
await widget.authenticate();
```

### `applyToJob(jobId, data?)`
Apply to a specific job.

```javascript
const application = await widget.applyToJob('job-123', {
  cover_letter: 'My cover letter...'
});
```

### `getState()`
Get current widget state.

```javascript
const state = widget.getState();
console.log(state);
```

### `destroy()`
Clean up and destroy widget.

```javascript
widget.destroy();
```

## React Hooks

### `useJobWidget`

```jsx
import { useJobWidget } from '@polymindslabs/widget-sdk/react';

function MyComponent() {
  const { widget, state, loading, error, authenticate, applyToJob } = useJobWidget({
    container: '#widget-container',
    tenantId: 'your-tenant-id',
    apiKey: 'your-api-key',
    clientId: 'your-oauth-client-id',
    redirectUri: 'https://yoursite.com/oauth-callback',
    type: 'job-list'
  });

  if (loading) return <div>Loading...</div>;
  if (error) return <div>Error: {error.message}</div>;

  return (
    <div>
      <button onClick={authenticate}>Login</button>
      <button onClick={() => applyToJob('job-123')}>Apply</button>
    </div>
  );
}
```

## Styling

### CSS Variables

```css
:root {
  --inzif-primary: #6366f1;
  --inzif-primary-dark: #4f46e5;
  --inzif-primary-light: #818cf8;
  --inzif-secondary: #ec4899;
  --inzif-success: #10b981;
  --inzif-warning: #f59e0b;
  --inzif-error: #ef4444;
  --inzif-font-sans: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif;
  --inzif-radius: 0.375rem;
}
```

### Custom CSS

```javascript
new InzifWidget({
  // ... config
  customStyles: `
    .inzif-widget {
      font-family: 'Custom Font', sans-serif;
    }
    .inzif-apply-button {
      background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
    }
  `
});
```

## OAuth Callback

Create an `oauth-callback.html` file in your public directory:

```html
<!DOCTYPE html>
<html>
<head>
  <title>OAuth Callback</title>
</head>
<body>
  <script src="https://cdn.inzif.com/widget-sdk/oauth-handler.js"></script>
</body>
</html>
```

## Browser Support

- Chrome 90+
- Firefox 88+
- Safari 14+
- Edge 90+

## TypeScript

Full TypeScript support with type definitions included.

```typescript
import { JobWidget, WidgetConfig, Job, Application } from '@polymindslabs/widget-sdk';

const config: WidgetConfig = {
  container: '#widget',
  tenantId: 'test',
  apiKey: 'key',
  clientId: 'client-id',
  redirectUri: 'https://yoursite.com/oauth-callback',
  type: 'job-list',
  onSuccess: (application: Application) => {
    console.log(application);
  }
};

const widget = new JobWidget(config);
```

## Examples

See the `/examples` directory for complete examples:
- Vanilla JavaScript
- React
- Vue
- Angular
- Next.js

## License

MIT © Job Widget

## Support

For partnerships, email partnerships@inzif.com or visit [inzif.com](https://inzif.com).