mirror of
https://github.com/writefreely/writefreely
synced 2024-11-24 17:43:05 +00:00
add user invite instructions
this adds a new page with instructions for sharing user invites if a user clicks the link for one of their own invite codes they are directed to a page with clear instructions for it's use. if a user clicks another users link they are redirectec to their account settings witha flash telling them they do not need to register.
This commit is contained in:
parent
6b99d75aa9
commit
d954b7c8e3
4 changed files with 68 additions and 8 deletions
13
database.go
13
database.go
|
@ -2257,6 +2257,19 @@ func (db *datastore) GetUserInvite(id string) (*Invite, error) {
|
||||||
return &i, nil
|
return &i, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsUsersInvite returns true if the user with ID created the invite with code
|
||||||
|
// and an error other than sql no rows, if any. Will return false in the event
|
||||||
|
// of an error.
|
||||||
|
func (db *datastore) IsUsersInvite(code string, userID int64) (bool, error) {
|
||||||
|
var id string
|
||||||
|
err := db.QueryRow("SELECT id FROM userinvites WHERE id = ? AND owner_id = ?", code, userID).Scan(&id)
|
||||||
|
if err != nil && err != sql.ErrNoRows {
|
||||||
|
log.Error("Failed selecting invite: %v", err)
|
||||||
|
return false, err
|
||||||
|
}
|
||||||
|
return id != "", nil
|
||||||
|
}
|
||||||
|
|
||||||
func (db *datastore) GetUsersInvitedCount(id string) int64 {
|
func (db *datastore) GetUsersInvitedCount(id string) int64 {
|
||||||
var count int64
|
var count int64
|
||||||
err := db.QueryRow("SELECT COUNT(*) FROM usersinvited WHERE invite_id = ?", id).Scan(&count)
|
err := db.QueryRow("SELECT COUNT(*) FROM usersinvited WHERE invite_id = ?", id).Scan(&count)
|
||||||
|
|
29
invites.go
29
invites.go
|
@ -12,15 +12,16 @@ package writefreely
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"html/template"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/writeas/impart"
|
"github.com/writeas/impart"
|
||||||
"github.com/writeas/nerds/store"
|
"github.com/writeas/nerds/store"
|
||||||
"github.com/writeas/web-core/log"
|
"github.com/writeas/web-core/log"
|
||||||
"github.com/writeas/writefreely/page"
|
"github.com/writeas/writefreely/page"
|
||||||
"html/template"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type Invite struct {
|
type Invite struct {
|
||||||
|
@ -109,6 +110,26 @@ func handleCreateUserInvite(app *App, u *User, w http.ResponseWriter, r *http.Re
|
||||||
func handleViewInvite(app *App, w http.ResponseWriter, r *http.Request) error {
|
func handleViewInvite(app *App, w http.ResponseWriter, r *http.Request) error {
|
||||||
inviteCode := mux.Vars(r)["code"]
|
inviteCode := mux.Vars(r)["code"]
|
||||||
|
|
||||||
|
if u := getUserSession(app, r); u != nil {
|
||||||
|
// check if invite belongs to another user
|
||||||
|
// error can be ignored as not important in this case
|
||||||
|
if ownInvite, _ := app.db.IsUsersInvite(inviteCode, u.ID); !ownInvite {
|
||||||
|
addSessionFlash(app, w, r, "No need for an invite, You are already registered.", nil)
|
||||||
|
// show homepage
|
||||||
|
return impart.HTTPError{http.StatusFound, "/me/settings"}
|
||||||
|
}
|
||||||
|
// show invite instructions
|
||||||
|
p := struct {
|
||||||
|
*UserPage
|
||||||
|
InviteID string
|
||||||
|
}{
|
||||||
|
UserPage: NewUserPage(app, r, u, "Invite Instructions", nil),
|
||||||
|
InviteID: inviteCode,
|
||||||
|
}
|
||||||
|
showUserPage(w, "invite-instructions", p)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
i, err := app.db.GetUserInvite(inviteCode)
|
i, err := app.db.GetUserInvite(inviteCode)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
|
|
@ -11,13 +11,14 @@
|
||||||
package writefreely
|
package writefreely
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"net/http"
|
||||||
|
"path/filepath"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
"github.com/writeas/go-webfinger"
|
"github.com/writeas/go-webfinger"
|
||||||
"github.com/writeas/web-core/log"
|
"github.com/writeas/web-core/log"
|
||||||
"github.com/writefreely/go-nodeinfo"
|
"github.com/writefreely/go-nodeinfo"
|
||||||
"net/http"
|
|
||||||
"path/filepath"
|
|
||||||
"strings"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// InitStaticRoutes adds routes for serving static files.
|
// InitStaticRoutes adds routes for serving static files.
|
||||||
|
@ -151,7 +152,7 @@ func InitRoutes(apper Apper, r *mux.Router) *mux.Router {
|
||||||
// Handle special pages first
|
// Handle special pages first
|
||||||
write.HandleFunc("/login", handler.Web(viewLogin, UserLevelNoneRequired))
|
write.HandleFunc("/login", handler.Web(viewLogin, UserLevelNoneRequired))
|
||||||
write.HandleFunc("/signup", handler.Web(handleViewLanding, UserLevelNoneRequired))
|
write.HandleFunc("/signup", handler.Web(handleViewLanding, UserLevelNoneRequired))
|
||||||
write.HandleFunc("/invite/{code}", handler.Web(handleViewInvite, UserLevelNoneRequired)).Methods("GET")
|
write.HandleFunc("/invite/{code}", handler.Web(handleViewInvite, UserLevelOptional)).Methods("GET")
|
||||||
// TODO: show a reader-specific 404 page if the function is disabled
|
// TODO: show a reader-specific 404 page if the function is disabled
|
||||||
write.HandleFunc("/read", handler.Web(viewLocalTimeline, UserLevelReader))
|
write.HandleFunc("/read", handler.Web(viewLocalTimeline, UserLevelReader))
|
||||||
RouteRead(handler, UserLevelReader, write.PathPrefix("/read").Subrouter())
|
RouteRead(handler, UserLevelReader, write.PathPrefix("/read").Subrouter())
|
||||||
|
|
25
templates/user/invite-instructions.tmpl
Normal file
25
templates/user/invite-instructions.tmpl
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
{{define "invite-instructions"}}
|
||||||
|
{{template "header" .}}
|
||||||
|
<style>
|
||||||
|
.copy-link {
|
||||||
|
width: 100%;
|
||||||
|
margin: 2em 0;
|
||||||
|
text-align: center;
|
||||||
|
font-size-adjust: .7;
|
||||||
|
color: #555;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<div class="snug content-container">
|
||||||
|
<h1>Invite Instructions</h1>
|
||||||
|
<p>This is a special link that you can send to anyone you want to join <em>{{ .SiteName }}</em>. Copy the link below and paste it into an email, instant message, or text message and send it to the person you want. When they navigate to the link, they'll be able to create an account.</p>
|
||||||
|
<input
|
||||||
|
class="copy-link"
|
||||||
|
type="text"
|
||||||
|
name="invite-url"
|
||||||
|
value="{{$.Host}}/invite/{{.InviteID}}"
|
||||||
|
onfocus="if (this.select) this.select(); else this.setSelectionRange(0, this.value.length);"
|
||||||
|
readonly/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{{template "footer" .}}
|
||||||
|
{{end}}
|
Loading…
Reference in a new issue