2020/05/20
PWA night #16
import Vue from 'vue'
export default Vue.extend({
props: {
id: {
type: String,
default: ''
},
minDate: {
type: Date,
default() {
return null
}
},
maxDate: {
type: Date,
default() {
return null
}
},
linkedCalendars: {
type: Boolean,
default: true
},
singleDatePicker: {
type: Boolean,
default: false
},
showDropdown: {
type: Boolean,
default: false
},
autoApply: {
type: Boolean,
default: false
},
dateRange: {
type: Object,
required: true
},
ranges: {
type: Object,
default() {
let today = new Date()
today.setHours(0, 0, 0, 0)
let yesterday = new Date()
yesterday.setDate(today.getDate() - 1)
yesterday.setHours(0, 0, 0, 0)
let thisMonthStart = new Date(today.getFullYear(), today.getMonth(), 1)
let thisMonthEnd = new Date(
today.getFullYear(),
today.getMonth() + 1,
0
)
let result = {}
result['今日'] = [today, today]
result['昨日'] = [yesterday, yesterday]
result['今月'] = [thisMonthStart, thisMonthEnd]
result['先月'] = [
new Date(today.getFullYear(), today.getMonth() - 1, 1),
new Date(today.getFullYear(), today.getMonth(), 0)
]
result['今年'] = [
new Date(today.getFullYear(), 0, 1),
new Date(today.getFullYear(), 11, 31)
]
result['昨年'] = [
new Date(today.getFullYear() - 1, 0, 1),
new Date(today.getFullYear() - 1, 11, 31)
]
return result
}
},
localeData: {
type: Object,
default() {
return {}
}
},
opens: {
type: String,
default: 'center'
},
dateFormat: {
type: Function,
required: true
},
clear: {
type: Boolean,
default: false
},
timePicker: {
type: Boolean,
default: false
},
timePickerIncrement: {
type: Number,
default: 5
},
timePicker24Hour: {
type: Boolean,
default: true
},
timePickerSeconds: {
type: Boolean,
default: false
}
},
})
<v-range-picker
ref="range-picker"
:single-date-picker="singleDatePicker"
:auto-apply="autoApply"
:linked-calendars="linkedCalendars"
:date-range="dateRange"
opens="right"
:date-format="dateFormat"
@update="updateValues"
@toggle="checkOpen"
>
<div slot="input" slot-scope="picker" style="min-width: 350px;">
{{ picker.startDate }} - {{ picker.endDate }}
</div>
</v-range-picker>
const PRECACHE = 'precache-v1';
const RUNTIME = 'runtime';
// キャッシュのバージョン管理の自動化
const VERSION = '<%= hash %>';
const STATIC_CACHE_KEY = 'static-' + VERSION;
const PRECACHE_URLS = [
'index.php',
'./', // Alias for index.html
'./css/app.css',
'./js/app.js',
'./js/manifest.js',
'./js/vendor.js'
];
const CACHE_VERSION = 1;
let CURRENT_CACHES = {
offline: 'offline-v' + CACHE_VERSION
};
const OFFLINE_URL = 'offline.html';
self.addEventListener('install', event => {
//console.log('Installing...');
if (typeof self.skipWaiting === 'function') {
//console.log('self.skipWaiting() is supported.');
event.waitUntil(
caches.open(PRECACHE)
.then(cache => cache.addAll(PRECACHE_URLS))
.then(self.skipWaiting())
);
} else {
console.log('self.skipWaiting() is not supported');
}
});
isSupported() {
return ('serviceWorker' in navigator
&& 'PushManager' in window)
}
const AWS = require('aws-sdk')
exports.handler = async (event) => {
const params = {
Message: 'ここに入力します。',
TopicArn: ''
}
await new AWS.SNS().publish(params).promise().then((data) => {
console.log('MessageID is ' + data.MessageId)
}).catch((err) => {
console.error(err, err.stack)
})
}
// 通知内容を表示する
self.addEventListener('push', function (event) {
let name = ((((event || {}).data || {}).json() || {}).data || {}).name;
event.waitUntil(
self.registration.showNotification(`${name}さんから`, {
'body': 'v1.0.0 がリリースされました。',
})
);
});
// クリックした時に、次にとるアクションを表示する
self.addEventListener('notificationClick', function (event) {
event.notification.close();
focusWindow(event);
});
const version = '';
const newestTopicId = `Topic_${version}`;
// クッキーを設定する
docCookies.setItem(
`COOKIE_TOPIC_${version}`,
newEstTopicId,
new Date()
);
if (docCookies.getItem(`COOKIE_TOPIC_${version}`)) {
// 存在した場合、ポップアップを表示する
}
import { initAuth0 } from '@auth0/nextjs-auth0';
export default initAuth0({
clientId: process.env.AUTH0_CLIENT_ID,
clientSecret: process.env.AUTH0_CLIENT_SECRET,
scope: process.env.AUTH0_SCOPE,
domain: process.env.AUTH0_DOMAIN,
redirectUri: process.env.REDIRECT_URI,
postLogoutRedirectUri: process.env.POST_LOGOUT_REDIRECT_URI,
session: {
cookieSecret: process.env.SESSION_COOKIE_SECRET,
cookieLifetime: process.env.SESSION_COOKIE_LIFETIME,
storeIdToken: false,
storeRefreshToken: false,
storeAccessToken: false
}
});
export interface ISignInWithAuth0 {
handleLogin: (
req: IncomingMessage,
res: ServerResponse,
options?: LoginOptions
) => Promise<void>;
}
import auth0 from '../../lib/auth0';
export default async function login(req, res) {
try {
await auth0.handleLogin(req, res);
} catch (error) {
console.error(error);
res.status(error.status || 500).end(error.message);
}
}
export interface ISignInWithAuth0 {
handleLogout: (
req: IncomingMessage,
res: ServerResponse
) => Promise<void>;
}
import auth0 from '../../lib/auth0';
export default async function logout(req, res) {
try {
await auth0.handleLogout(req, res);
} catch (error) {
console.error(error);
res.status(error.status || 500).end(error.message);
}
}
let userState;
export const fetchUser = async () => {
if (userState !== undefined) {
return userState;
}
const res = await fetch('/api/me');
userState = res.ok ? await res.json() : null;
return userState;
};
const IndexPage: NextPage<IndexPageProps> = () => {
const { user, loading } = useFetchUser()
return (
<>
{!loading && !user && <SWHeader isAuth={false} />}
{user && (
<>
<SWHeader isAuth={true} />
<!--
ログインに成功したら表示するページ
-->
</>
)}
</>
)
}